diff --git a/src/servers/app/Decorator.cpp b/src/servers/app/Decorator.cpp index d63209e3e5..bfd76c5968 100644 --- a/src/servers/app/Decorator.cpp +++ b/src/servers/app/Decorator.cpp @@ -49,7 +49,9 @@ Decorator::Decorator(DesktopSettings& settings, BRect rect, window_look look, fZoomPressed(false), fMinimizePressed(false), fIsFocused(false), - fTitle("") + fTitle(""), + + fFootprintValid(false) { } @@ -97,6 +99,10 @@ Decorator::SetFlags(uint32 flags, BRegion* updateRegion) flags |= B_NOT_H_RESIZABLE | B_NOT_V_RESIZABLE; fFlags = flags; + + fFootprintValid = false; + // the border might have changed (smaller/larger tab) + _SetFlags(flags, updateRegion); } @@ -105,6 +111,8 @@ Decorator::SetFlags(uint32 flags, BRegion* updateRegion) void Decorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion) { + fFootprintValid = false; + _FontsChanged(settings, updateRegion); } @@ -116,6 +124,10 @@ Decorator::SetLook(DesktopSettings& settings, window_look look, BRegion* updateRect) { fLook = look; + + fFootprintValid = false; + // the border very likely changed + _SetLook(settings, look, updateRect); } @@ -176,6 +188,12 @@ Decorator::SetTitle(const char* string, BRegion* updateRegion) { fTitle.SetTo(string); _DoLayout(); + + fFootprintValid = false; + // the border very likely changed + + _SetTitle(string, updateRegion); + // TODO: redraw? } @@ -286,16 +304,16 @@ Decorator::SetFocus(bool active) // #pragma mark - virtual methods -/*! \brief Returns the "footprint" of the entire window, including decorator - - This function is required by all subclasses. - - \param region Region to be changed to represent the window's screen - footprint +/*! \brief Returns a cached footprint if available otherwise recalculate it */ -void -Decorator::GetFootprint(BRegion *region) +const BRegion& +Decorator::GetFootprint() { + if (!fFootprintValid) { + _GetFootprint(&fFootprint); + fFootprintValid = true; + } + return fFootprint; } @@ -366,14 +384,10 @@ Decorator::MoveBy(float x, float y) void Decorator::MoveBy(BPoint offset) { - fZoomRect.OffsetBy(offset); - fCloseRect.OffsetBy(offset); - fMinimizeRect.OffsetBy(offset); - fMinimizeRect.OffsetBy(offset); - fTabRect.OffsetBy(offset); - fFrame.OffsetBy(offset); - fResizeRect.OffsetBy(offset); - fBorderRect.OffsetBy(offset); + if (fFootprintValid) + fFootprint.OffsetBy(offset.x, offset.y); + + _MoveBy(offset); } @@ -394,9 +408,32 @@ Decorator::ResizeBy(float x, float y, BRegion* dirty) } +void +Decorator::ResizeBy(BPoint offset, BRegion* dirty) +{ + fFootprintValid = false; + _ResizeBy(offset, dirty); +} + + +bool +Decorator::SetTabLocation(float location, BRegion* updateRegion) +{ + if (_SetTabLocation(location, updateRegion)) { + fFootprintValid = false; + return true; + } + return false; +} + + bool Decorator::SetSettings(const BMessage& settings, BRegion* updateRegion) { + if (_SetSettings(settings, updateRegion)) { + fFootprintValid = false; + return true; + } return false; } @@ -580,3 +617,62 @@ void Decorator::_SetFocus() { } + + +void +Decorator::_FontsChanged(DesktopSettings& settings, BRegion* updateRegion) +{ +} + + +void +Decorator::_SetLook(DesktopSettings& settings, window_look look, + BRegion* updateRect) +{ +} + + +void +Decorator::_SetFlags(uint32 flags, BRegion* updateRegion) +{ +} + + +void +Decorator::_SetTitle(const char* string, BRegion* updateRegion) +{ +} + + +void +Decorator::_MoveBy(BPoint offset) +{ + fZoomRect.OffsetBy(offset); + fCloseRect.OffsetBy(offset); + fMinimizeRect.OffsetBy(offset); + fMinimizeRect.OffsetBy(offset); + fTabRect.OffsetBy(offset); + fFrame.OffsetBy(offset); + fResizeRect.OffsetBy(offset); + fBorderRect.OffsetBy(offset); +} + + +bool +Decorator::_SetSettings(const BMessage& settings, BRegion* updateRegion) +{ + return false; +} + + +/*! \brief Returns the "footprint" of the entire window, including decorator + + This function is required by all subclasses. + + \param region Region to be changed to represent the window's screen + footprint +*/ +void +Decorator::_GetFootprint(BRegion *region) +{ +} diff --git a/src/servers/app/Decorator.h b/src/servers/app/Decorator.h index 3b632baba7..38f6801418 100644 --- a/src/servers/app/Decorator.h +++ b/src/servers/app/Decorator.h @@ -54,18 +54,18 @@ public: inline DrawingEngine* GetDrawingEngine() const { return fDrawingEngine; } - virtual void FontsChanged(DesktopSettings& settings, + void FontsChanged(DesktopSettings& settings, BRegion* updateRegion = NULL); - virtual void SetLook(DesktopSettings& settings, window_look look, + void SetLook(DesktopSettings& settings, window_look look, BRegion* updateRegion = NULL); - virtual void SetFlags(uint32 flags, + void SetFlags(uint32 flags, BRegion* updateRegion = NULL); void SetClose(bool pressed); void SetMinimize(bool pressed); void SetZoom(bool pressed); - virtual void SetTitle(const char* string, + void SetTitle(const char* string, BRegion* updateRegion = NULL); window_look Look() const; @@ -87,26 +87,25 @@ public: bool IsFocus() { return fIsFocused; }; - virtual void GetFootprint(BRegion *region); + const BRegion& GetFootprint(); virtual click_type Clicked(BPoint where, int32 buttons, int32 modifiers); void MoveBy(float x, float y); - virtual void MoveBy(BPoint offset); + void MoveBy(BPoint offset); void ResizeBy(float x, float y, BRegion* dirty); - virtual void ResizeBy(BPoint offset, BRegion* dirty) = 0; + void ResizeBy(BPoint offset, BRegion* dirty); /*! \return true if tab location updated, false if out of bounds or unsupported */ - virtual bool SetTabLocation(float location, - BRegion* /*updateRegion*/ = NULL) - { return false; } + bool SetTabLocation(float location, + BRegion* /*updateRegion*/ = NULL); virtual float TabLocation() const { return 0.0; } - virtual bool SetSettings(const BMessage& settings, + bool SetSettings(const BMessage& settings, BRegion* updateRegion = NULL); virtual bool GetSettings(BMessage* settings) const; @@ -135,7 +134,28 @@ protected: virtual void _DrawZoom(BRect rect); virtual void _DrawMinimize(BRect rect); + virtual void _FontsChanged(DesktopSettings& settings, + BRegion* updateRegion = NULL); + virtual void _SetLook(DesktopSettings& settings, + window_look look, BRegion* updateRegion = NULL); + virtual void _SetFlags(uint32 flags, + BRegion* updateRegion = NULL); + + virtual void _SetTitle(const char* string, + BRegion* updateRegion = NULL); + virtual void _SetFocus(); + virtual void _MoveBy(BPoint offset); + virtual void _ResizeBy(BPoint offset, BRegion* dirty) = 0; + + virtual bool _SetTabLocation(float location, + BRegion* /*updateRegion*/ = NULL) + { return false; } + + virtual bool _SetSettings(const BMessage& settings, + BRegion* updateRegion = NULL); + + virtual void _GetFootprint(BRegion *region); DrawingEngine* fDrawingEngine; DrawState fDrawState; @@ -159,6 +179,9 @@ private: bool fIsFocused : 1; BString fTitle; + + BRegion fFootprint; + bool fFootprintValid : 1; }; #endif // DECORATOR_H diff --git a/src/servers/app/DefaultDecorator.cpp b/src/servers/app/DefaultDecorator.cpp index 0ec5139a94..bdf098abaf 100644 --- a/src/servers/app/DefaultDecorator.cpp +++ b/src/servers/app/DefaultDecorator.cpp @@ -144,291 +144,6 @@ DefaultDecorator::SetTitle(const char* string, BRegion* updateRegion) } -void -DefaultDecorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion) -{ - // get previous extent - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } - - _UpdateFont(settings); - _InvalidateBitmaps(); - _DoLayout(); - - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } -} - - -void -DefaultDecorator::SetLook(DesktopSettings& settings, window_look look, - BRegion* updateRegion) -{ - // TODO: we could be much smarter about the update region - - // get previous extent - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } - - fLook = look; - - _UpdateFont(settings); - _InvalidateBitmaps(); - _DoLayout(); - - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } -} - - -void -DefaultDecorator::SetFlags(uint32 flags, BRegion* updateRegion) -{ - // TODO: we could be much smarter about the update region - - // get previous extent - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } - - Decorator::SetFlags(flags, updateRegion); - _DoLayout(); - - if (updateRegion != NULL) { - BRegion extent; - GetFootprint(&extent); - updateRegion->Include(&extent); - } -} - - -void -DefaultDecorator::MoveBy(BPoint offset) -{ - STRACE(("DefaultDecorator: Move By (%.1f, %.1f)\n", offset.x, offset.y)); - // Move all internal rectangles the appropriate amount - fFrame.OffsetBy(offset); - fCloseRect.OffsetBy(offset); - fTabRect.OffsetBy(offset); - fResizeRect.OffsetBy(offset); - fZoomRect.OffsetBy(offset); - fBorderRect.OffsetBy(offset); - - fLeftBorder.OffsetBy(offset); - fRightBorder.OffsetBy(offset); - fTopBorder.OffsetBy(offset); - fBottomBorder.OffsetBy(offset); -} - - -void -DefaultDecorator::ResizeBy(BPoint offset, BRegion* dirty) -{ - STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", offset.x, offset.y)); - // Move all internal rectangles the appropriate amount - fFrame.right += offset.x; - fFrame.bottom += offset.y; - - // Handle invalidation of resize rect - if (dirty && !(fFlags & B_NOT_RESIZABLE)) { - BRect realResizeRect; - switch (fLook) { - case B_DOCUMENT_WINDOW_LOOK: - realResizeRect = fResizeRect; - // Resize rect at old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // Resize rect at new location - dirty->Include(realResizeRect); - break; - case B_TITLED_WINDOW_LOOK: - case B_FLOATING_WINDOW_LOOK: - case B_MODAL_WINDOW_LOOK: - case kLeftTitledWindowLook: - // The bottom border resize line - realResizeRect.Set(fRightBorder.right - kBorderResizeLength, fBottomBorder.top, - fRightBorder.right - kBorderResizeLength, fBottomBorder.bottom - 1); - // Old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // New location - dirty->Include(realResizeRect); - - // The right border resize line - realResizeRect.Set(fRightBorder.left, fBottomBorder.bottom - kBorderResizeLength, - fRightBorder.right - 1, fBottomBorder.bottom - kBorderResizeLength); - // Old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // New location - dirty->Include(realResizeRect); - break; - default: - break; - } - } - - fResizeRect.OffsetBy(offset); - - fBorderRect.right += offset.x; - fBorderRect.bottom += offset.y; - - fLeftBorder.bottom += offset.y; - fTopBorder.right += offset.x; - - fRightBorder.OffsetBy(offset.x, 0.0); - fRightBorder.bottom += offset.y; - - fBottomBorder.OffsetBy(0.0, offset.y); - fBottomBorder.right += offset.x; - - if (dirty) { - if (offset.x > 0.0) { - BRect t(fRightBorder.left - offset.x, fTopBorder.top, - fRightBorder.right, fTopBorder.bottom); - dirty->Include(t); - t.Set(fRightBorder.left - offset.x, fBottomBorder.top, - fRightBorder.right, fBottomBorder.bottom); - dirty->Include(t); - dirty->Include(fRightBorder); - } else if (offset.x < 0.0) { - dirty->Include(BRect(fRightBorder.left, fTopBorder.top, - fRightBorder.right, fBottomBorder.bottom)); - } - if (offset.y > 0.0) { - BRect t(fLeftBorder.left, fLeftBorder.bottom - offset.y, - fLeftBorder.right, fLeftBorder.bottom); - dirty->Include(t); - t.Set(fRightBorder.left, fRightBorder.bottom - offset.y, - fRightBorder.right, fRightBorder.bottom); - dirty->Include(t); - dirty->Include(fBottomBorder); - } else if (offset.y < 0.0) { - dirty->Include(fBottomBorder); - } - } - - // resize tab and layout tab items - if (fTabRect.IsValid()) { - BRect oldTabRect(fTabRect); - - float tabSize; - float maxLocation; - if (fLook != kLeftTitledWindowLook) { - tabSize = fRightBorder.right - fLeftBorder.left; - } else { - tabSize = fBottomBorder.bottom - fTopBorder.top; - } - maxLocation = tabSize - fMaxTabSize; - if (maxLocation < 0) - maxLocation = 0; - - float tabOffset = floorf(fTabLocation * maxLocation); - float delta = tabOffset - fTabOffset; - fTabOffset = (uint32)tabOffset; - if (fLook != kLeftTitledWindowLook) - fTabRect.OffsetBy(delta, 0.0); - else - fTabRect.OffsetBy(0.0, delta); - - if (tabSize < fMinTabSize) - tabSize = fMinTabSize; - if (tabSize > fMaxTabSize) - tabSize = fMaxTabSize; - - if (fLook != kLeftTitledWindowLook && tabSize != fTabRect.Width()) { - fTabRect.right = fTabRect.left + tabSize; - } else if (fLook == kLeftTitledWindowLook - && tabSize != fTabRect.Height()) { - fTabRect.bottom = fTabRect.top + tabSize; - } - - if (oldTabRect != fTabRect) { - _LayoutTabItems(fTabRect); - - if (dirty) { - // NOTE: the tab rect becoming smaller only would - // handled be the Desktop anyways, so it is sufficient - // to include it into the dirty region in it's - // final state - BRect redraw(fTabRect); - if (delta != 0.0) { - redraw = redraw | oldTabRect; - if (fLook != kLeftTitledWindowLook) - redraw.bottom++; - else - redraw.right++; - } - dirty->Include(redraw); - } - } - } -} - - -bool -DefaultDecorator::SetTabLocation(float location, BRegion* updateRegion) -{ - STRACE(("DefaultDecorator: Set Tab Location(%.1f)\n", location)); - if (!fTabRect.IsValid()) - return false; - - if (location < 0) - location = 0; - - float maxLocation - = fRightBorder.right - fLeftBorder.left - fTabRect.Width(); - if (location > maxLocation) - location = maxLocation; - - float delta = location - fTabOffset; - if (delta == 0.0) - return false; - - // redraw old rect (1 pix on the border also must be updated) - BRect trect(fTabRect); - trect.bottom++; - updateRegion->Include(trect); - - fTabRect.OffsetBy(delta, 0); - fTabOffset = (int32)location; - _LayoutTabItems(fTabRect); - - fTabLocation = maxLocation > 0.0 ? fTabOffset / maxLocation : 0.0; - - // redraw new rect as well - trect = fTabRect; - trect.bottom++; - updateRegion->Include(trect); - return true; -} - - -bool -DefaultDecorator::SetSettings(const BMessage& settings, BRegion* updateRegion) -{ - float tabLocation; - if (settings.FindFloat("tab location", &tabLocation) == B_OK) - return SetTabLocation(tabLocation, updateRegion); - - return false; -} - - bool DefaultDecorator::GetSettings(BMessage* settings) const { @@ -490,40 +205,6 @@ DefaultDecorator::GetSizeLimits(int32* minWidth, int32* minHeight, } -void -DefaultDecorator::GetFootprint(BRegion* region) -{ - STRACE(("DefaultDecorator: Get Footprint\n")); - // This function calculates the decorator's footprint in coordinates - // relative to the view. This is most often used to set a Window - // object's visible region. - if (!region) - return; - - region->MakeEmpty(); - - if (fLook == B_NO_BORDER_WINDOW_LOOK) - return; - - region->Include(fTopBorder); - region->Include(fLeftBorder); - region->Include(fRightBorder); - region->Include(fBottomBorder); - - if (fLook == B_BORDERED_WINDOW_LOOK) - return; - - region->Include(fTabRect); - - if (fLook == B_DOCUMENT_WINDOW_LOOK) { - // include the rectangular resize knob on the bottom right - float knobSize = kResizeKnobSize - fBorderWidth; - region->Include(BRect(fFrame.right - knobSize, fFrame.bottom - knobSize, - fFrame.right, fFrame.bottom)); - } -} - - click_type DefaultDecorator::Clicked(BPoint point, int32 buttons, int32 modifiers) { @@ -1085,6 +766,58 @@ DefaultDecorator::_DrawZoom(BRect rect) } +void +DefaultDecorator::_FontsChanged(DesktopSettings& settings, + BRegion* updateRegion) +{ + // get previous extent + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); + + _UpdateFont(settings); + _InvalidateBitmaps(); + _DoLayout(); + + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); +} + + +void +DefaultDecorator::_SetLook(DesktopSettings& settings, window_look look, + BRegion* updateRegion) +{ + // TODO: we could be much smarter about the update region + + // get previous extent + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); + + _UpdateFont(settings); + _InvalidateBitmaps(); + _DoLayout(); + + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); +} + + +void +DefaultDecorator::_SetFlags(uint32 flags, BRegion* updateRegion) +{ + // TODO: we could be much smarter about the update region + + // get previous extent + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); + + _DoLayout(); + + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); +} + + void DefaultDecorator::_SetFocus() { @@ -1122,6 +855,253 @@ DefaultDecorator::_SetColors() } +void +DefaultDecorator::_MoveBy(BPoint offset) +{ + STRACE(("DefaultDecorator: Move By (%.1f, %.1f)\n", offset.x, offset.y)); + // Move all internal rectangles the appropriate amount + fFrame.OffsetBy(offset); + fCloseRect.OffsetBy(offset); + fTabRect.OffsetBy(offset); + fResizeRect.OffsetBy(offset); + fZoomRect.OffsetBy(offset); + fBorderRect.OffsetBy(offset); + + fLeftBorder.OffsetBy(offset); + fRightBorder.OffsetBy(offset); + fTopBorder.OffsetBy(offset); + fBottomBorder.OffsetBy(offset); +} + + +void +DefaultDecorator::_ResizeBy(BPoint offset, BRegion* dirty) +{ + STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", offset.x, offset.y)); + // Move all internal rectangles the appropriate amount + fFrame.right += offset.x; + fFrame.bottom += offset.y; + + // Handle invalidation of resize rect + if (dirty && !(fFlags & B_NOT_RESIZABLE)) { + BRect realResizeRect; + switch (fLook) { + case B_DOCUMENT_WINDOW_LOOK: + realResizeRect = fResizeRect; + // Resize rect at old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(offset); + // Resize rect at new location + dirty->Include(realResizeRect); + break; + case B_TITLED_WINDOW_LOOK: + case B_FLOATING_WINDOW_LOOK: + case B_MODAL_WINDOW_LOOK: + case kLeftTitledWindowLook: + // The bottom border resize line + realResizeRect.Set(fRightBorder.right - kBorderResizeLength, fBottomBorder.top, + fRightBorder.right - kBorderResizeLength, fBottomBorder.bottom - 1); + // Old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(offset); + // New location + dirty->Include(realResizeRect); + + // The right border resize line + realResizeRect.Set(fRightBorder.left, fBottomBorder.bottom - kBorderResizeLength, + fRightBorder.right - 1, fBottomBorder.bottom - kBorderResizeLength); + // Old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(offset); + // New location + dirty->Include(realResizeRect); + break; + default: + break; + } + } + + fResizeRect.OffsetBy(offset); + + fBorderRect.right += offset.x; + fBorderRect.bottom += offset.y; + + fLeftBorder.bottom += offset.y; + fTopBorder.right += offset.x; + + fRightBorder.OffsetBy(offset.x, 0.0); + fRightBorder.bottom += offset.y; + + fBottomBorder.OffsetBy(0.0, offset.y); + fBottomBorder.right += offset.x; + + if (dirty) { + if (offset.x > 0.0) { + BRect t(fRightBorder.left - offset.x, fTopBorder.top, + fRightBorder.right, fTopBorder.bottom); + dirty->Include(t); + t.Set(fRightBorder.left - offset.x, fBottomBorder.top, + fRightBorder.right, fBottomBorder.bottom); + dirty->Include(t); + dirty->Include(fRightBorder); + } else if (offset.x < 0.0) { + dirty->Include(BRect(fRightBorder.left, fTopBorder.top, + fRightBorder.right, fBottomBorder.bottom)); + } + if (offset.y > 0.0) { + BRect t(fLeftBorder.left, fLeftBorder.bottom - offset.y, + fLeftBorder.right, fLeftBorder.bottom); + dirty->Include(t); + t.Set(fRightBorder.left, fRightBorder.bottom - offset.y, + fRightBorder.right, fRightBorder.bottom); + dirty->Include(t); + dirty->Include(fBottomBorder); + } else if (offset.y < 0.0) { + dirty->Include(fBottomBorder); + } + } + + // resize tab and layout tab items + if (fTabRect.IsValid()) { + BRect oldTabRect(fTabRect); + + float tabSize; + float maxLocation; + if (fLook != kLeftTitledWindowLook) { + tabSize = fRightBorder.right - fLeftBorder.left; + } else { + tabSize = fBottomBorder.bottom - fTopBorder.top; + } + maxLocation = tabSize - fMaxTabSize; + if (maxLocation < 0) + maxLocation = 0; + + float tabOffset = floorf(fTabLocation * maxLocation); + float delta = tabOffset - fTabOffset; + fTabOffset = (uint32)tabOffset; + if (fLook != kLeftTitledWindowLook) + fTabRect.OffsetBy(delta, 0.0); + else + fTabRect.OffsetBy(0.0, delta); + + if (tabSize < fMinTabSize) + tabSize = fMinTabSize; + if (tabSize > fMaxTabSize) + tabSize = fMaxTabSize; + + if (fLook != kLeftTitledWindowLook && tabSize != fTabRect.Width()) { + fTabRect.right = fTabRect.left + tabSize; + } else if (fLook == kLeftTitledWindowLook + && tabSize != fTabRect.Height()) { + fTabRect.bottom = fTabRect.top + tabSize; + } + + if (oldTabRect != fTabRect) { + _LayoutTabItems(fTabRect); + + if (dirty) { + // NOTE: the tab rect becoming smaller only would + // handled be the Desktop anyways, so it is sufficient + // to include it into the dirty region in it's + // final state + BRect redraw(fTabRect); + if (delta != 0.0) { + redraw = redraw | oldTabRect; + if (fLook != kLeftTitledWindowLook) + redraw.bottom++; + else + redraw.right++; + } + dirty->Include(redraw); + } + } + } +} + + +bool +DefaultDecorator::_SetTabLocation(float location, BRegion* updateRegion) +{ + STRACE(("DefaultDecorator: Set Tab Location(%.1f)\n", location)); + if (!fTabRect.IsValid()) + return false; + + if (location < 0) + location = 0; + + float maxLocation + = fRightBorder.right - fLeftBorder.left - fTabRect.Width(); + if (location > maxLocation) + location = maxLocation; + + float delta = location - fTabOffset; + if (delta == 0.0) + return false; + + // redraw old rect (1 pix on the border also must be updated) + BRect trect(fTabRect); + trect.bottom++; + updateRegion->Include(trect); + + fTabRect.OffsetBy(delta, 0); + fTabOffset = (int32)location; + _LayoutTabItems(fTabRect); + + fTabLocation = maxLocation > 0.0 ? fTabOffset / maxLocation : 0.0; + + // redraw new rect as well + trect = fTabRect; + trect.bottom++; + updateRegion->Include(trect); + return true; +} + + +bool +DefaultDecorator::_SetSettings(const BMessage& settings, BRegion* updateRegion) +{ + float tabLocation; + if (settings.FindFloat("tab location", &tabLocation) == B_OK) + return SetTabLocation(tabLocation, updateRegion); + + return false; +} + + +void +DefaultDecorator::_GetFootprint(BRegion *region) +{ + STRACE(("DefaultDecorator: Get Footprint\n")); + // This function calculates the decorator's footprint in coordinates + // relative to the view. This is most often used to set a Window + // object's visible region. + if (!region) + return; + + region->MakeEmpty(); + + if (fLook == B_NO_BORDER_WINDOW_LOOK) + return; + + region->Include(fTopBorder); + region->Include(fLeftBorder); + region->Include(fRightBorder); + region->Include(fBottomBorder); + + if (fLook == B_BORDERED_WINDOW_LOOK) + return; + + region->Include(fTabRect); + + if (fLook == B_DOCUMENT_WINDOW_LOOK) { + // include the rectangular resize knob on the bottom right + float knobSize = kResizeKnobSize - fBorderWidth; + region->Include(BRect(fFrame.right - knobSize, fFrame.bottom - knobSize, + fFrame.right, fFrame.bottom)); + } +} + + void DefaultDecorator::_UpdateFont(DesktopSettings& settings) { diff --git a/src/servers/app/DefaultDecorator.h b/src/servers/app/DefaultDecorator.h index 2c53ef3a22..03b7f611cc 100644 --- a/src/servers/app/DefaultDecorator.h +++ b/src/servers/app/DefaultDecorator.h @@ -27,24 +27,10 @@ public: virtual void SetTitle(const char* string, BRegion* updateRegion = NULL); - virtual void FontsChanged(DesktopSettings& settings, - BRegion* updateRegion); - virtual void SetLook(DesktopSettings& settings, - window_look look, - BRegion* updateRegion = NULL); - virtual void SetFlags(uint32 flags, - BRegion* updateRegion = NULL); - virtual void MoveBy(BPoint offset); - virtual void ResizeBy(BPoint offset, BRegion* dirty); - - virtual bool SetTabLocation(float location, - BRegion* updateRegion = NULL); virtual float TabLocation() const { return (float)fTabOffset; } - virtual bool SetSettings(const BMessage& settings, - BRegion* updateRegion = NULL); virtual bool GetSettings(BMessage* settings) const; virtual void Draw(BRect updateRect); @@ -53,8 +39,6 @@ public: virtual void GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth, int32* maxHeight) const; - virtual void GetFootprint(BRegion* region); - virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers); @@ -68,9 +52,28 @@ protected: virtual void _DrawTitle(BRect r); virtual void _DrawZoom(BRect r); + virtual void _FontsChanged(DesktopSettings& settings, + BRegion* updateRegion); + virtual void _SetLook(DesktopSettings& settings, + window_look look, + BRegion* updateRegion = NULL); + virtual void _SetFlags(uint32 flags, + BRegion* updateRegion = NULL); + virtual void _SetFocus(); virtual void _SetColors(); + virtual void _MoveBy(BPoint offset); + virtual void _ResizeBy(BPoint offset, BRegion* dirty); + + virtual bool _SetTabLocation(float location, + BRegion* updateRegion = NULL); + + virtual bool _SetSettings(const BMessage& settings, + BRegion* updateRegion = NULL); + + virtual void _GetFootprint(BRegion *region); + private: void _UpdateFont(DesktopSettings& settings); void _DrawButtonBitmap(ServerBitmap* bitmap, diff --git a/src/servers/app/DefaultWindowBehaviour.cpp b/src/servers/app/DefaultWindowBehaviour.cpp index 08e5615e0f..62c95fa22f 100644 --- a/src/servers/app/DefaultWindowBehaviour.cpp +++ b/src/servers/app/DefaultWindowBehaviour.cpp @@ -48,7 +48,9 @@ bool DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where) { int32 modifiers = _ExtractModifiers(message); - bool inBorderRegion = fWindow->BorderRegion().Contains(where); + bool inBorderRegion = false; + if (fWindow->Decorator()) + inBorderRegion = fWindow->Decorator()->GetFootprint().Contains(where); bool windowModifier = (fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0 && (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY @@ -457,9 +459,7 @@ DefaultWindowBehaviour::_AlterDeltaForSnap(BPoint& delta, bigtime_t now) BRect screenFrame = fWindow->Screen()->Frame(); if (fDecorator) { - BRegion reg; - fDecorator->GetFootprint(®); - frame = reg.Frame(); + frame = fDecorator->GetFootprint().Frame(); offsetWithinFrame.x = fWindow->Frame().left - frame.left; offsetWithinFrame.y = fWindow->Frame().top - frame.top; } diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 6c7df87a65..b094d38d98 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -79,12 +79,10 @@ Window::Window(const BRect& frame, const char *name, fDirtyRegion(), fDirtyCause(0), - fBorderRegion(), fContentRegion(), fEffectiveDrawingRegion(), fVisibleContentRegionValid(false), - fBorderRegionValid(false), fContentRegionValid(false), fEffectiveDrawingRegionValid(false), @@ -221,16 +219,10 @@ Window::GetBorderRegion(BRegion* region) // TODO: if someone needs to call this from // the outside, the clipping needs to be readlocked! - if (!fBorderRegionValid) { - if (fDecorator) - fDecorator->GetFootprint(&fBorderRegion); - else - fBorderRegion.MakeEmpty(); - - fBorderRegionValid = true; - } - - *region = fBorderRegion; + if (fDecorator) + *region = fDecorator->GetFootprint(); + else + region->MakeEmpty(); } @@ -293,8 +285,6 @@ Window::MoveBy(int32 x, int32 y) // processed yet fDirtyRegion.OffsetBy(x, y); - if (fBorderRegionValid) - fBorderRegion.OffsetBy(x, y); if (fContentRegionValid) fContentRegion.OffsetBy(x, y); @@ -351,7 +341,6 @@ Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion) fFrame.right += x; fFrame.bottom += y; - fBorderRegionValid = false; fContentRegionValid = false; fEffectiveDrawingRegionValid = false; @@ -765,10 +754,6 @@ Window::MouseDown(BMessage* message, BPoint where, int32* _viewToken) { DesktopSettings desktopSettings(fDesktop); - // TODO: move into Decorator - if (!fBorderRegionValid) - GetBorderRegion(&fBorderRegion); - bool eventEaten = fWindowBehaviour->MouseDown(message, where); if (!eventEaten) { // click was inside the window contents @@ -898,12 +883,8 @@ Window::SetTitle(const char* name, BRegion& dirty) fTitle = name; - if (fDecorator) { + if (fDecorator) fDecorator->SetTitle(name, &dirty); - - fBorderRegionValid = false; - // the border very likely changed - } } @@ -915,7 +896,9 @@ Window::SetFocus(bool focus) // so the window thread cannot be // accessing fIsFocus - BRegion* dirty = fRegionPool.GetRegion(fBorderRegion); + BRegion* dirty = NULL; + if (fDecorator) + dirty = fRegionPool.GetRegion(fDecorator->GetFootprint()); if (dirty) { dirty->IntersectWith(&fVisibleRegion); fDesktop->MarkDirty(*dirty); @@ -1028,13 +1011,10 @@ Window::GetSizeLimits(int32* minWidth, int32* maxWidth, bool Window::SetTabLocation(float location, BRegion& dirty) { - bool ret = false; - if (fDecorator) { - ret = fDecorator->SetTabLocation(location, &dirty); - // the border region changed if ret is true - fBorderRegionValid = fBorderRegionValid && !ret; - } - return ret; + if (fDecorator) + return fDecorator->SetTabLocation(location, &dirty); + + return false; } @@ -1050,13 +1030,9 @@ Window::TabLocation() const bool Window::SetDecoratorSettings(const BMessage& settings, BRegion& dirty) { - bool ret = false; - if (fDecorator) { - ret = fDecorator->SetSettings(settings, &dirty); - // the border region changed if ret is true - fBorderRegionValid = fBorderRegionValid && !ret; - } - return ret; + if (fDecorator) + return fDecorator->SetSettings(settings, &dirty); + return false; } @@ -1076,7 +1052,6 @@ Window::FontsChanged(BRegion* updateRegion) if (fDecorator != NULL) { DesktopSettings settings(fDesktop); fDecorator->FontsChanged(settings, updateRegion); - fBorderRegionValid = false; } } @@ -1094,8 +1069,6 @@ Window::SetLook(window_look look, BRegion* updateRegion) fLook = look; - fBorderRegionValid = false; - // the border very likely changed fContentRegionValid = false; // mabye a resize handle was added... fEffectiveDrawingRegionValid = false; @@ -1160,9 +1133,6 @@ Window::SetFlags(uint32 flags, BRegion* updateRegion) fDecorator->SetFlags(flags, updateRegion); - fBorderRegionValid = false; - // the border might have changed (smaller/larger tab) - // we might need to resize the window! if (fDecorator) { fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight); @@ -1829,12 +1799,8 @@ Window::_UpdateContentRegion() fContentRegion.Set(fFrame); // resize handle - if (fDecorator) { - if (!fBorderRegionValid) - GetBorderRegion(&fBorderRegion); - - fContentRegion.Exclude(&fBorderRegion); - } + if (fDecorator) + fContentRegion.Exclude(&fDecorator->GetFootprint()); fContentRegionValid = true; } diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h index 242b7197ad..c93150ed49 100644 --- a/src/servers/app/Window.h +++ b/src/servers/app/Window.h @@ -247,7 +247,6 @@ public: static uint32 ValidWindowFlags(); static uint32 ValidWindowFlags(window_feel feel); - BRegion& BorderRegion() { return fBorderRegion; } protected: void _ShiftPartOfRegion(BRegion* region, BRegion* regionToShift, int32 xOffset, @@ -289,12 +288,10 @@ protected: uint32 fDirtyCause; // caching local regions - BRegion fBorderRegion; BRegion fContentRegion; BRegion fEffectiveDrawingRegion; bool fVisibleContentRegionValid : 1; - bool fBorderRegionValid : 1; bool fContentRegionValid : 1; bool fEffectiveDrawingRegionValid : 1; @@ -345,8 +342,6 @@ protected: uint8 fCause; }; - BRegion fDecoratorRegion; - UpdateSession fUpdateSessions[2]; UpdateSession* fCurrentUpdateSession; UpdateSession* fPendingUpdateSession;