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:
parent
4fd3a03652
commit
8f1c695124
@ -30,6 +30,8 @@
|
||||
#include <NodeInfo.h>
|
||||
#include <Path.h>
|
||||
#include <RadioButton.h>
|
||||
#include <Region.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <String.h>
|
||||
#include <StringView.h>
|
||||
@ -643,7 +645,7 @@ ScreenshotWindow::_TakeScreenshot()
|
||||
fScreenshot = new BBitmap(frame.OffsetToCopy(B_ORIGIN), B_RGBA32, true);
|
||||
BScreen(this).ReadBitmap(fScreenshot, fIncludeMouse, &frame);
|
||||
if (fIncludeBorder)
|
||||
_MakeTabSpaceTransparent();
|
||||
_MakeTabSpaceTransparent(&frame);
|
||||
} else {
|
||||
BScreen(this).GetBitmap(&fScreenshot, fIncludeMouse);
|
||||
}
|
||||
@ -791,96 +793,88 @@ ScreenshotWindow::_SaveScreenshotSilent() const
|
||||
|
||||
|
||||
void
|
||||
ScreenshotWindow::_MakeTabSpaceTransparent()
|
||||
ScreenshotWindow::_MakeTabSpaceTransparent(BRect* frame)
|
||||
{
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
if (fScreenshot->ColorSpace() != B_RGBA32)
|
||||
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);
|
||||
int32 tabStart = 0;
|
||||
int32 tabEnd = 0;
|
||||
bool foundTabStart = false;
|
||||
bool foundTabEnd = false;
|
||||
|
||||
// Find the top-left corner of the window tab, by color, and support
|
||||
// this guess by following a one tab high column of pixels downwards.
|
||||
for (int32 x = 0; x < pixelsPerRow; x++) {
|
||||
if (component[0] == 152 && component[1] == 152 && component[2] == 152) {
|
||||
foundTabStart = true;
|
||||
|
||||
for (int32 y = 0; y < tabHeight; y++) {
|
||||
component += bytesPerRow;
|
||||
|
||||
if (!(component[0] == 152 && component[1] == 152
|
||||
&& component[2] == 152)) {
|
||||
foundTabStart = false;
|
||||
}
|
||||
}
|
||||
component -= bytesPerRow * tabHeight;
|
||||
|
||||
if (foundTabStart) {
|
||||
tabStart = x;
|
||||
BRect fullFrame = *frame;
|
||||
|
||||
BMessage message;
|
||||
BMessage reply;
|
||||
|
||||
app_info appInfo;
|
||||
if (be_roster->GetActiveAppInfo(&appInfo) != B_OK)
|
||||
return;
|
||||
|
||||
BMessenger messenger(appInfo.signature, appInfo.team);
|
||||
if (!messenger.IsValid())
|
||||
return;
|
||||
|
||||
bool foundActiveWindow = false;
|
||||
int32 index = 0;
|
||||
|
||||
while (true) {
|
||||
message.MakeEmpty();
|
||||
message.what = B_GET_PROPERTY;
|
||||
message.AddSpecifier("Active");
|
||||
message.AddSpecifier("Window", index);
|
||||
|
||||
reply.MakeEmpty();
|
||||
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;
|
||||
}
|
||||
}
|
||||
component += 4;
|
||||
index++;
|
||||
}
|
||||
|
||||
component = static_cast<uint8*>(fScreenshot->Bits());
|
||||
|
||||
// Find the top-right corner of the window tab.
|
||||
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)
|
||||
if (!foundActiveWindow)
|
||||
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);
|
||||
if(view.Looper() && view.Looper()->Lock()) {
|
||||
view.SetDrawingMode(B_OP_COPY);
|
||||
view.SetHighColor(B_TRANSPARENT_32_BIT);
|
||||
|
||||
if (tabStart > 0)
|
||||
view.FillRect(BRect(0, 0, tabStart - 1, tabHeight - 1));
|
||||
for (int i = 0; i < tabSpace.CountRects(); i++)
|
||||
view.FillRect(tabSpace.RectAt(i));
|
||||
|
||||
if (tabEnd < pixelsPerRow - 1) {
|
||||
view.FillRect(BRect(tabEnd + 1, 0, pixelsPerRow - 1,
|
||||
tabHeight - 1));
|
||||
}
|
||||
view.Sync();
|
||||
view.Looper()->Unlock();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ private:
|
||||
|
||||
void _TakeScreenshot();
|
||||
status_t _GetActiveWindowFrame(BRect* frame);
|
||||
void _MakeTabSpaceTransparent();
|
||||
void _MakeTabSpaceTransparent(BRect* frame);
|
||||
|
||||
status_t _SaveScreenshot();
|
||||
void _SaveScreenshotSilent() const;
|
||||
|
Loading…
Reference in New Issue
Block a user