Use BWindow TabFrame property to find where to apply transparency.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32232 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jonas Sundström
2009-08-10 19:21:39 +00:00
parent 4fd3a03652
commit 8f1c695124
2 changed files with 70 additions and 76 deletions
+69 -75
View File
@@ -30,6 +30,8 @@
#include <NodeInfo.h> #include <NodeInfo.h>
#include <Path.h> #include <Path.h>
#include <RadioButton.h> #include <RadioButton.h>
#include <Region.h>
#include <Roster.h>
#include <Screen.h> #include <Screen.h>
#include <String.h> #include <String.h>
#include <StringView.h> #include <StringView.h>
@@ -643,7 +645,7 @@ ScreenshotWindow::_TakeScreenshot()
fScreenshot = new BBitmap(frame.OffsetToCopy(B_ORIGIN), B_RGBA32, true); fScreenshot = new BBitmap(frame.OffsetToCopy(B_ORIGIN), B_RGBA32, true);
BScreen(this).ReadBitmap(fScreenshot, fIncludeMouse, &frame); BScreen(this).ReadBitmap(fScreenshot, fIncludeMouse, &frame);
if (fIncludeBorder) if (fIncludeBorder)
_MakeTabSpaceTransparent(); _MakeTabSpaceTransparent(&frame);
} else { } else {
BScreen(this).GetBitmap(&fScreenshot, fIncludeMouse); BScreen(this).GetBitmap(&fScreenshot, fIncludeMouse);
} }
@@ -791,96 +793,88 @@ ScreenshotWindow::_SaveScreenshotSilent() const
void void
ScreenshotWindow::_MakeTabSpaceTransparent() ScreenshotWindow::_MakeTabSpaceTransparent(BRect* frame)
{ {
if (!frame)
return;
if (fScreenshot->ColorSpace() != B_RGBA32) if (fScreenshot->ColorSpace() != B_RGBA32)
return; return;
if (fTabHeight == 0)
return;
// This method is fragile since it relies on the color scheme of the current
// window decorator. The code could be simplified a lot if there was a way
// to ask for, or to easily compute, the tab width of the target window.
uint8* component = static_cast<uint8*>(fScreenshot->Bits());
int32 bytesPerRow = fScreenshot->BytesPerRow();
int32 pixelsPerRow = bytesPerRow / 4;
int32 tabHeight = static_cast<int32>(fTabHeight); BRect fullFrame = *frame;
int32 tabStart = 0;
int32 tabEnd = 0; BMessage message;
bool foundTabStart = false; BMessage reply;
bool foundTabEnd = false;
app_info appInfo;
// Find the top-left corner of the window tab, by color, and support if (be_roster->GetActiveAppInfo(&appInfo) != B_OK)
// this guess by following a one tab high column of pixels downwards. return;
for (int32 x = 0; x < pixelsPerRow; x++) {
if (component[0] == 152 && component[1] == 152 && component[2] == 152) { BMessenger messenger(appInfo.signature, appInfo.team);
foundTabStart = true; if (!messenger.IsValid())
return;
for (int32 y = 0; y < tabHeight; y++) {
component += bytesPerRow; bool foundActiveWindow = false;
int32 index = 0;
if (!(component[0] == 152 && component[1] == 152
&& component[2] == 152)) { while (true) {
foundTabStart = false; message.MakeEmpty();
} message.what = B_GET_PROPERTY;
} message.AddSpecifier("Active");
component -= bytesPerRow * tabHeight; message.AddSpecifier("Window", index);
if (foundTabStart) { reply.MakeEmpty();
tabStart = x; messenger.SendMessage(&message, &reply);
if (reply.what == B_MESSAGE_NOT_UNDERSTOOD)
break;
bool result;
if (reply.FindBool("result", &result) == B_OK) {
foundActiveWindow = result;
if (foundActiveWindow)
break; break;
}
} }
component += 4; index++;
} }
component = static_cast<uint8*>(fScreenshot->Bits());
// Find the top-right corner of the window tab. if (!foundActiveWindow)
for (int32 x = 0; x < pixelsPerRow; x++) {
if (component[0] == 108 && component[1] == 108 && component[2] == 108) {
foundTabEnd = true;
for (int32 y = 0; y < tabHeight; y++) {
component += bytesPerRow;
if (!(component[0] == 108 && component[1] == 108
&& component[2] == 108)) {
foundTabEnd = false;
}
}
component -= bytesPerRow * tabHeight;
if (foundTabEnd) {
tabEnd = x;
break;
}
}
component += 4;
}
if (!foundTabEnd || !foundTabStart)
return;
if (tabStart > tabEnd)
return; return;
BView view(fScreenshot->Bounds(), "bitmapView", B_FOLLOW_ALL_SIDES, 0); message.MakeEmpty();
message.what = B_GET_PROPERTY;
message.AddSpecifier("TabFrame");
message.AddSpecifier("Window", index);
reply.MakeEmpty();
messenger.SendMessage(&message, &reply);
BRect tabFrame;
if (reply.FindRect("result", &tabFrame) != B_OK)
return;
if (!fullFrame.Contains(tabFrame))
return;
BRegion tabSpace(fullFrame);
fullFrame.OffsetBy(0, fTabHeight);
tabSpace.Exclude(fullFrame);
tabSpace.Exclude(tabFrame);
fullFrame.OffsetBy(0, -fTabHeight);
tabSpace.OffsetBy(-fullFrame.left, -fullFrame.top);
BScreen screen;
BRect screenFrame = screen.Frame();
tabSpace.OffsetBy(-screenFrame.left, -screenFrame.top);
BView view(fScreenshot->Bounds(), "bitmap", B_FOLLOW_ALL_SIDES, 0);
fScreenshot->AddChild(&view); fScreenshot->AddChild(&view);
if(view.Looper() && view.Looper()->Lock()) { if(view.Looper() && view.Looper()->Lock()) {
view.SetDrawingMode(B_OP_COPY); view.SetDrawingMode(B_OP_COPY);
view.SetHighColor(B_TRANSPARENT_32_BIT); view.SetHighColor(B_TRANSPARENT_32_BIT);
if (tabStart > 0) for (int i = 0; i < tabSpace.CountRects(); i++)
view.FillRect(BRect(0, 0, tabStart - 1, tabHeight - 1)); view.FillRect(tabSpace.RectAt(i));
if (tabEnd < pixelsPerRow - 1) {
view.FillRect(BRect(tabEnd + 1, 0, pixelsPerRow - 1,
tabHeight - 1));
}
view.Sync(); view.Sync();
view.Looper()->Unlock(); view.Looper()->Unlock();
} }
+1 -1
View File
@@ -53,7 +53,7 @@ private:
void _TakeScreenshot(); void _TakeScreenshot();
status_t _GetActiveWindowFrame(BRect* frame); status_t _GetActiveWindowFrame(BRect* frame);
void _MakeTabSpaceTransparent(); void _MakeTabSpaceTransparent(BRect* frame);
status_t _SaveScreenshot(); status_t _SaveScreenshot();
void _SaveScreenshotSilent() const; void _SaveScreenshotSilent() const;