diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index ef2d2dea4e..7c2304537c 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -1,16 +1,18 @@ /* - * Copyright 2001-2016, Haiku. + * Copyright 2001-2020, Haiku. * Distributed under the terms of the MIT License. * * Authors: - * Adrian Oanca - * Stephan Aßmus - * Axel Dörfler - * Andrej Spielmann - * Brecht Machiels - * Clemens Zeidler - * Ingo Weinhold - * Joseph Groover + * Adrian Oanca, adioanca@cotty.iren.ro + * Stephan Aßmus, superstippi@gmx.de + * Axel Dörfler, axeld@pinc-software.de + * Andrej Spielmann, andrej.spielmann@seh.ox.ac.uk + * Brecht Machiels, brecht@mos6581.org + * Clemens Zeidler, haiku@clemens-zeidler.de + * Ingo Weinhold, ingo_weinhold@gmx.de + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ @@ -1542,7 +1544,7 @@ Desktop::ResizeWindowBy(Window* window, float x, float y) // make sure the window cannot mark stuff dirty outside // its visible region... newDirtyRegion.IntersectWith(&window->VisibleRegion()); - // ...because we do this outself + // ...because we do this ourselves newDirtyRegion.Include(&previouslyOccupiedRegion); MarkDirty(newDirtyRegion); @@ -1559,6 +1561,25 @@ Desktop::ResizeWindowBy(Window* window, float x, float y) } +void +Desktop::SetWindowOutlinesDelta(Window* window, BPoint delta) +{ + AutoWriteLocker _(fWindowLock); + + if (!window->IsVisible()) + return; + + BRegion newDirtyRegion; + window->SetOutlinesDelta(delta, &newDirtyRegion); + + BRegion background; + _RebuildClippingForAllWindows(background); + + MarkDirty(newDirtyRegion); + _SetBackground(background); +} + + bool Desktop::SetWindowTabLocation(Window* window, float location, bool isShifting) { diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index d3ca0a02f4..9381f65443 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -1,15 +1,17 @@ /* - * Copyright 2001-2015, Haiku. + * Copyright 2001-2020, Haiku. * Distributed under the terms of the MIT License. * * Authors: - * Adrian Oanca - * Stephan Aßmus - * Axel Dörfler - * Andrej Spielmann, - * Brecht Machiels - * Clemens Zeidler - * Joseph Groover + * Adrian Oanca, adioanca@cotty.iren.ro + * Stephan Aßmus, superstippi@gmx.de + * Axel Dörfler, axeld@pinc-software.de + * Andrej Spielmann, andrej.spielmann@seh.ox.ac.uk + * Brecht Machiels, brecht@mos6581.org + * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ #ifndef DESKTOP_H #define DESKTOP_H @@ -187,6 +189,8 @@ public: int32 workspace = -1); void ResizeWindowBy(Window* window, float x, float y); + void SetWindowOutlinesDelta(Window* window, + BPoint delta); bool SetWindowTabLocation(Window* window, float location, bool isShifting); bool SetWindowDecoratorSettings(Window* window, diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 1cef1b2e62..bd2a1a8257 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -1,14 +1,16 @@ /* - * Copyright 2001-2011, Haiku, Inc. + * Copyright 2001-2020, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: - * DarkWyrm - * Adi Oanca - * Stephan Aßmus - * Axel Dörfler - * Brecht Machiels - * Clemens Zeidler + * DarkWyrm, bpmagic@columbus.rr.com + * Adi Oanca, adioanca@gmail.com + * Stephan Aßmus, superstippi@gmx.de + * Axel Dörfler, axeld@pinc-software.de + * Brecht Machiels, brecht@mos6581.org + * Clemens Zeidler, haiku@clemens-zeidler.de + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ @@ -393,6 +395,42 @@ Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion, bool resizeStack) } +void +Window::SetOutlinesDelta(BPoint delta, BRegion* dirtyRegion) +{ + float wantWidth = fFrame.IntegerWidth() + delta.x; + float wantHeight = fFrame.IntegerHeight() + delta.y; + + // enforce size limits + WindowStack* stack = GetWindowStack(); + if (stack != NULL) { + for (int32 i = 0; i < stack->CountWindows(); i++) { + Window* window = stack->WindowList().ItemAt(i); + + if (wantWidth < window->fMinWidth) + wantWidth = window->fMinWidth; + if (wantWidth > window->fMaxWidth) + wantWidth = window->fMaxWidth; + + if (wantHeight < window->fMinHeight) + wantHeight = window->fMinHeight; + if (wantHeight > window->fMaxHeight) + wantHeight = window->fMaxHeight; + } + + delta.x = wantWidth - fFrame.IntegerWidth(); + delta.y = wantHeight - fFrame.IntegerHeight(); + } + + ::Decorator* decorator = Decorator(); + + if (decorator != NULL) + decorator->SetOutlinesDelta(delta, dirtyRegion); + + _UpdateContentRegion(); +} + + void Window::ScrollViewBy(View* view, int32 dx, int32 dy) { diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h index 4b73b7b2f1..5f2a20db5c 100644 --- a/src/servers/app/Window.h +++ b/src/servers/app/Window.h @@ -1,14 +1,16 @@ /* - * Copyright 2001-2011, Haiku, Inc. + * Copyright 2001-2020, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: - * DarkWyrm - * Adi Oanca - * Stephan Aßmus - * Axel Dörfler - * Brecht Machiels - * Clemens Zeidler + * DarkWyrm, bpmagic@columbus.rr.com + * Adi Oanca, adioanca@gmail.com + * Stephan Aßmus, superstippi@gmx.de + * Axel Dörfler, axeld@pinc-software.de + * Brecht Machiels, brecht@mos6581.org + * Clemens Zeidler, haiku@clemens-zeidler.de + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ #ifndef WINDOW_H #define WINDOW_H @@ -131,6 +133,8 @@ public: void ResizeBy(int32 x, int32 y, BRegion* dirtyRegion, bool resizeStack = true); + void SetOutlinesDelta(BPoint delta, + BRegion* dirtyRegion); void ScrollViewBy(View* view, int32 dx, int32 dy); diff --git a/src/servers/app/decorator/Decorator.cpp b/src/servers/app/decorator/Decorator.cpp index 0a2d3dd494..c9eaec4afd 100644 --- a/src/servers/app/decorator/Decorator.cpp +++ b/src/servers/app/decorator/Decorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -8,7 +8,9 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ @@ -83,13 +85,20 @@ Decorator::Decorator(DesktopSettings& settings, BRect frame, fFrame(frame), fResizeRect(), fBorderRect(), + fOutlineBorderRect(), fLeftBorder(), fTopBorder(), fBottomBorder(), fRightBorder(), + fLeftOutlineBorder(), + fTopOutlineBorder(), + fBottomOutlineBorder(), + fRightOutlineBorder(), + fBorderWidth(-1), + fOutlineBorderWidth(-1), fTopTab(NULL), @@ -215,8 +224,10 @@ Decorator::SetDrawingEngine(DrawingEngine* engine) fDrawingEngine = engine; // lots of subclasses will depend on the driver for text support, so call // _DoLayout() after we have it - if (fDrawingEngine != NULL) + if (fDrawingEngine != NULL) { _DoLayout(); + _DoOutlineLayout(); + } } @@ -558,9 +569,16 @@ Decorator::GetFootprint() AutoReadLocker _(fLocker); if (!fFootprintValid) { + fFootprint.MakeEmpty(); + _GetFootprint(&fFootprint); + + if (IsOutlineResizing()) + _GetOutlineFootprint(&fFootprint); + fFootprintValid = true; } + return fFootprint; } @@ -657,6 +675,7 @@ Decorator::MoveBy(BPoint offset) fFootprint.OffsetBy(offset.x, offset.y); _MoveBy(offset); + _MoveOutlineBy(offset); } @@ -681,7 +700,18 @@ void Decorator::ResizeBy(BPoint offset, BRegion* dirty) { AutoWriteLocker _(fLocker); + _ResizeBy(offset, dirty); + _ResizeOutlineBy(offset, dirty); + + _InvalidateFootprint(); +} + + +void +Decorator::SetOutlinesDelta(BPoint delta, BRegion* dirty) +{ + _SetOutlinesDelta(delta, dirty); _InvalidateFootprint(); } @@ -1019,6 +1049,7 @@ Decorator::_FontsChanged(DesktopSettings& settings, BRegion* updateRegion) _UpdateFont(settings); _DoLayout(); + _DoOutlineLayout(); _InvalidateFootprint(); if (updateRegion != NULL) @@ -1040,6 +1071,7 @@ Decorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings, _UpdateFont(settings); _DoLayout(); + _DoOutlineLayout(); _InvalidateFootprint(); if (updateRegion != NULL) @@ -1058,6 +1090,7 @@ Decorator::_SetFlags(Decorator::Tab* tab, uint32 flags, BRegion* updateRegion) tab->flags = flags; _DoLayout(); + _DoOutlineLayout(); _InvalidateFootprint(); if (updateRegion != NULL) @@ -1083,6 +1116,65 @@ Decorator::_MoveBy(BPoint offset) } +void +Decorator::_MoveOutlineBy(BPoint offset) +{ + fOutlineBorderRect.OffsetBy(offset); + + fLeftOutlineBorder.OffsetBy(offset); + fRightOutlineBorder.OffsetBy(offset); + fTopOutlineBorder.OffsetBy(offset); + fBottomOutlineBorder.OffsetBy(offset); +} + + +void +Decorator::_ResizeOutlineBy(BPoint offset, BRegion* dirty) +{ + fOutlineBorderRect.right += offset.x; + fOutlineBorderRect.bottom += offset.y; + + fLeftOutlineBorder.bottom += offset.y; + fTopOutlineBorder.right += offset.x; + + fRightOutlineBorder.OffsetBy(offset.x, 0.0); + fRightOutlineBorder.bottom += offset.y; + + fBottomOutlineBorder.OffsetBy(0.0, offset.y); + fBottomOutlineBorder.right += offset.x; +} + + +void +Decorator::_SetOutlinesDelta(BPoint delta, BRegion* dirty) +{ + BPoint offset = delta - fOutlinesDelta; + fOutlinesDelta = delta; + + dirty->Include(fLeftOutlineBorder); + dirty->Include(fRightOutlineBorder); + dirty->Include(fTopOutlineBorder); + dirty->Include(fBottomOutlineBorder); + + fOutlineBorderRect.right += offset.x; + fOutlineBorderRect.bottom += offset.y; + + fLeftOutlineBorder.bottom += offset.y; + fTopOutlineBorder.right += offset.x; + + fRightOutlineBorder.OffsetBy(offset.x, 0.0); + fRightOutlineBorder.bottom += offset.y; + + fBottomOutlineBorder.OffsetBy(0.0, offset.y); + fBottomOutlineBorder.right += offset.x; + + dirty->Include(fLeftOutlineBorder); + dirty->Include(fRightOutlineBorder); + dirty->Include(fTopOutlineBorder); + dirty->Include(fBottomOutlineBorder); +} + + bool Decorator::_SetSettings(const BMessage& settings, BRegion* updateRegion) { @@ -1103,6 +1195,19 @@ Decorator::_GetFootprint(BRegion *region) } +void +Decorator::_GetOutlineFootprint(BRegion* region) +{ + if (region == NULL) + return; + + region->Include(fTopOutlineBorder); + region->Include(fLeftOutlineBorder); + region->Include(fRightOutlineBorder); + region->Include(fBottomOutlineBorder); +} + + void Decorator::_InvalidateFootprint() { diff --git a/src/servers/app/decorator/Decorator.h b/src/servers/app/decorator/Decorator.h index 346dbb60b1..3634afcf31 100644 --- a/src/servers/app/decorator/Decorator.h +++ b/src/servers/app/decorator/Decorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -8,7 +8,9 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ #ifndef DECORATOR_H #define DECORATOR_H @@ -175,6 +177,9 @@ public: void MoveBy(BPoint offset); void ResizeBy(float x, float y, BRegion* dirty); void ResizeBy(BPoint offset, BRegion* dirty); + void SetOutlinesDelta(BPoint delta, BRegion* dirty); + bool IsOutlineResizing() const + { return fOutlinesDelta != BPoint(0, 0); } virtual bool SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty, @@ -210,8 +215,10 @@ protected: virtual void _DoLayout() = 0; //! method for calculating layout for the decorator + virtual void _DoOutlineLayout() = 0; virtual void _DrawFrame(BRect rect) = 0; + virtual void _DrawOutlineFrame(BRect rect) = 0; virtual void _DrawTabs(BRect rect); virtual void _DrawTab(Decorator::Tab* tab, BRect rect) = 0; @@ -254,6 +261,10 @@ protected: virtual void _MoveBy(BPoint offset); virtual void _ResizeBy(BPoint offset, BRegion* dirty) = 0; + virtual void _MoveOutlineBy(BPoint offset); + virtual void _ResizeOutlineBy(BPoint offset, BRegion* dirty); + virtual void _SetOutlinesDelta(BPoint delta, BRegion* dirty); + virtual bool _SetSettings(const BMessage& settings, BRegion* updateRegion = NULL); @@ -265,7 +276,8 @@ protected: virtual bool _MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion = NULL) = 0; - virtual void _GetFootprint(BRegion *region); + virtual void _GetFootprint(BRegion* region); + virtual void _GetOutlineFootprint(BRegion* region); void _InvalidateFootprint(); void _InvalidateBitmaps(); @@ -276,19 +288,28 @@ protected: DrawingEngine* fDrawingEngine; DrawState fDrawState; + BPoint fOutlinesDelta; + // Individual rects for handling window frame // rendering the proper way BRect fTitleBarRect; BRect fFrame; BRect fResizeRect; BRect fBorderRect; + BRect fOutlineBorderRect; BRect fLeftBorder; BRect fTopBorder; BRect fBottomBorder; BRect fRightBorder; + BRect fLeftOutlineBorder; + BRect fTopOutlineBorder; + BRect fBottomOutlineBorder; + BRect fRightOutlineBorder; + int32 fBorderWidth; + int32 fOutlineBorderWidth; Decorator::Tab* fTopTab; BObjectList fTabList; diff --git a/src/servers/app/decorator/DefaultDecorator.cpp b/src/servers/app/decorator/DefaultDecorator.cpp index efd3a0594f..f76fb68acf 100644 --- a/src/servers/app/decorator/DefaultDecorator.cpp +++ b/src/servers/app/decorator/DefaultDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,7 +10,9 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ @@ -208,7 +210,7 @@ DefaultDecorator::_DrawFrame(BRect rect) return; // Draw the border frame - BRect r = BRect(fTopBorder.LeftTop(), fBottomBorder.RightBottom()); + BRect border = BRect(fTopBorder.LeftTop(), fBottomBorder.RightBottom()); switch ((int)fTopTab->look) { case B_TITLED_WINDOW_LOOK: case B_DOCUMENT_WINDOW_LOOK: @@ -220,8 +222,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); for (int8 i = 0; i < 5; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), colors[i]); + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.top + i), + BPoint(border.right - i, border.top + i), colors[i]); } if (fTitleBarRect.IsValid()) { // grey along the bottom of the tab @@ -240,8 +243,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); for (int8 i = 0; i < 5; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), colors[i]); + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.top + i), + BPoint(border.left + i, border.bottom - i), colors[i]); } } // bottom @@ -250,8 +254,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); for (int8 i = 0; i < 5; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), - BPoint(r.right - i, r.bottom - i), + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.bottom - i), + BPoint(border.right - i, border.bottom - i), colors[(4 - i) == 4 ? 5 : (4 - i)]); } } @@ -261,8 +266,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); for (int8 i = 0; i < 5; i++) { - fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), - BPoint(r.right - i, r.bottom - i), + fDrawingEngine->StrokeLine( + BPoint(border.right - i, border.top + i), + BPoint(border.right - i, border.bottom - i), colors[(4 - i) == 4 ? 5 : (4 - i)]); } } @@ -278,8 +284,10 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); for (int8 i = 0; i < 3; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), colors[i * 2]); + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.top + i), + BPoint(border.right - i, border.top + i), + colors[i * 2]); } if (fTitleBarRect.IsValid() && fTopTab->look != kLeftTitledWindowLook) { // grey along the bottom of the tab @@ -297,8 +305,10 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); for (int8 i = 0; i < 3; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), colors[i * 2]); + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.top + i), + BPoint(border.left + i, border.bottom - i), + colors[i * 2]); } if (fTopTab->look == kLeftTitledWindowLook && fTitleBarRect.IsValid()) { @@ -317,8 +327,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); for (int8 i = 0; i < 3; i++) { - fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), - BPoint(r.right - i, r.bottom - i), + fDrawingEngine->StrokeLine( + BPoint(border.left + i, border.bottom - i), + BPoint(border.right - i, border.bottom - i), colors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } } @@ -328,8 +339,9 @@ DefaultDecorator::_DrawFrame(BRect rect) _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); for (int8 i = 0; i < 3; i++) { - fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), - BPoint(r.right - i, r.bottom - i), + fDrawingEngine->StrokeLine( + BPoint(border.right - i, border.top + i), + BPoint(border.right - i, border.bottom - i), colors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } } @@ -342,7 +354,7 @@ DefaultDecorator::_DrawFrame(BRect rect) ComponentColors colors; _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); - fDrawingEngine->StrokeRect(r, colors[5]); + fDrawingEngine->StrokeRect(border, colors[5]); break; } @@ -353,52 +365,25 @@ DefaultDecorator::_DrawFrame(BRect rect) // Draw the resize knob if we're supposed to if (!(fTopTab->flags & B_NOT_RESIZABLE)) { - r = fResizeRect; - ComponentColors colors; _GetComponentColors(COMPONENT_RESIZE_CORNER, colors, fTopTab); switch ((int)fTopTab->look) { case B_DOCUMENT_WINDOW_LOOK: { - if (!rect.Intersects(r)) - break; + if (fOutlinesDelta.x != 0 || fOutlinesDelta.y != 0) { + border.Set(fFrame.right - 13, fFrame.bottom - 13, + fFrame.right + 3, fFrame.bottom + 3); - float x = r.right - 3; - float y = r.bottom - 3; - - BRect bg(x - 13, y - 13, x, y); - - BGradientLinear gradient; - gradient.SetStart(bg.LeftTop()); - gradient.SetEnd(bg.RightBottom()); - gradient.AddColor(colors[1], 0); - gradient.AddColor(colors[2], 255); - - fDrawingEngine->FillRect(bg, gradient); - - fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), - BPoint(x - 15, y - 2), colors[0]); - fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), - BPoint(x - 14, y - 1), colors[1]); - fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), - BPoint(x - 2, y - 15), colors[0]); - fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), - BPoint(x - 1, y - 14), colors[1]); - - if (fTopTab && !IsFocus(fTopTab)) - break; - - static const rgb_color kWhite - = (rgb_color){ 255, 255, 255, 255 }; - for (int8 i = 1; i <= 4; i++) { - for (int8 j = 1; j <= i; j++) { - BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1); - BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2); - fDrawingEngine->StrokePoint(pt1, colors[0]); - fDrawingEngine->StrokePoint(pt2, kWhite); - } + if (rect.Intersects(border)) + _DrawResizeKnob(border, false, colors); } + + if (rect.Intersects(fResizeRect)) { + _DrawResizeKnob(fResizeRect, fTopTab && IsFocus(fTopTab), + colors); + } + break; } @@ -407,18 +392,24 @@ DefaultDecorator::_DrawFrame(BRect rect) case B_MODAL_WINDOW_LOOK: case kLeftTitledWindowLook: { - if (!rect.Intersects(BRect(fRightBorder.right - kBorderResizeLength, - fBottomBorder.bottom - kBorderResizeLength, fRightBorder.right - 1, - fBottomBorder.bottom - 1))) + if (!rect.Intersects(BRect( + fRightBorder.right - kBorderResizeLength, + fBottomBorder.bottom - kBorderResizeLength, + fRightBorder.right - 1, + fBottomBorder.bottom - 1))) break; fDrawingEngine->StrokeLine( - BPoint(fRightBorder.left, fBottomBorder.bottom - kBorderResizeLength), - BPoint(fRightBorder.right - 1, fBottomBorder.bottom - kBorderResizeLength), + BPoint(fRightBorder.left, + fBottomBorder.bottom - kBorderResizeLength), + BPoint(fRightBorder.right - 1, + fBottomBorder.bottom - kBorderResizeLength), colors[0]); fDrawingEngine->StrokeLine( - BPoint(fRightBorder.right - kBorderResizeLength, fBottomBorder.top), - BPoint(fRightBorder.right - kBorderResizeLength, fBottomBorder.bottom - 1), + BPoint(fRightBorder.right - kBorderResizeLength, + fBottomBorder.top), + BPoint(fRightBorder.right - kBorderResizeLength, + fBottomBorder.bottom - 1), colors[0]); break; } @@ -431,6 +422,46 @@ DefaultDecorator::_DrawFrame(BRect rect) } +void +DefaultDecorator::_DrawResizeKnob(BRect rect, bool full, + const ComponentColors& colors) +{ + float x = rect.right -= 3; + float y = rect.bottom -= 3; + + BGradientLinear gradient; + gradient.SetStart(rect.LeftTop()); + gradient.SetEnd(rect.RightBottom()); + gradient.AddColor(colors[1], 0); + gradient.AddColor(colors[2], 255); + + fDrawingEngine->FillRect(rect, gradient); + + fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), + BPoint(x - 15, y - 2), colors[0]); + fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), + BPoint(x - 14, y - 1), colors[1]); + fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), + BPoint(x - 2, y - 15), colors[0]); + fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), + BPoint(x - 1, y - 14), colors[1]); + + if (!full) + return; + + static const rgb_color kWhite + = (rgb_color){ 255, 255, 255, 255 }; + for (int8 i = 1; i <= 4; i++) { + for (int8 j = 1; j <= i; j++) { + BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1); + BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2); + fDrawingEngine->StrokePoint(pt1, colors[0]); + fDrawingEngine->StrokePoint(pt2, kWhite); + } + } +} + + /*! \brief Actually draws the tab This function is called when the tab itself needs drawn. Other items, diff --git a/src/servers/app/decorator/DefaultDecorator.h b/src/servers/app/decorator/DefaultDecorator.h index 5d9448f83b..0ba448c201 100644 --- a/src/servers/app/decorator/DefaultDecorator.h +++ b/src/servers/app/decorator/DefaultDecorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,7 +10,9 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ #ifndef DEFAULT_DECORATOR_H #define DEFAULT_DECORATOR_H @@ -46,6 +48,8 @@ protected: BRect rect); virtual void _DrawMinimize(Decorator::Tab* tab, bool direct, BRect rect); + virtual void _DrawResizeKnob(BRect r, bool full, + const ComponentColors& color); private: void _DrawButtonBitmap(ServerBitmap* bitmap, diff --git a/src/servers/app/decorator/DefaultWindowBehaviour.cpp b/src/servers/app/decorator/DefaultWindowBehaviour.cpp index 5a75e2847a..70d159ee56 100644 --- a/src/servers/app/decorator/DefaultWindowBehaviour.cpp +++ b/src/servers/app/decorator/DefaultWindowBehaviour.cpp @@ -1,15 +1,17 @@ /* - * Copyright 2001-2010, Haiku, Inc. + * Copyright 2001-2020, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: - * DarkWyrm - * Adi Oanca - * Stephan Aßmus - * Axel Dörfler - * Brecht Machiels - * Clemens Zeidler - * Ingo Weinhold + * DarkWyrm, bpmagic@columbus.rr.com + * Adi Oanca, adioanca@gmail.com + * Stephan Aßmus, superstippi@gmx.de + * Axel Dörfler, axeld@pinc-software.de + * Brecht Machiels, brecht@mos6581.org + * Clemens Zeidler, haiku@clemens-zeidler.de + * Ingo Weinhold, ingo_weinhold@gmx.de + * Tri-Edge AI + * Jacob Secunda, secundja@gmail.com */ @@ -17,8 +19,10 @@ #include +#include #include +#include "AppServer.h" #include "ClickTarget.h" #include "Desktop.h" #include "DefaultDecorator.h" @@ -250,11 +254,26 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState { struct DefaultWindowBehaviour::ResizeState : MouseTrackingState { + BPoint fDelta; + ResizeState(DefaultWindowBehaviour& behavior, BPoint where, bool activateOnMouseUp) : - MouseTrackingState(behavior, where, activateOnMouseUp, false) + MouseTrackingState(behavior, where, activateOnMouseUp, true) { + fDelta = BPoint(0, 0); + } + + virtual void EnterState(State* prevState) + { + } + + virtual void ExitState(State* nextState) + { + if ((fWindow->Flags() & B_OUTLINE_RESIZE) != 0) { + fDesktop->SetWindowOutlinesDelta(fWindow, BPoint(0, 0)); + fDesktop->ResizeWindowBy(fWindow, fDelta.x, fDelta.y); + } } virtual void MouseMovedAction(BPoint& delta, bigtime_t now) @@ -267,7 +286,11 @@ struct DefaultWindowBehaviour::ResizeState : MouseTrackingState { BPoint oldRightBottom = fWindow->Frame().RightBottom(); - fDesktop->ResizeWindowBy(fWindow, delta.x, delta.y); + if ((fWindow->Flags() & B_OUTLINE_RESIZE) != 0) { + fDelta = delta; + fDesktop->SetWindowOutlinesDelta(fWindow, delta); + } else + fDesktop->ResizeWindowBy(fWindow, delta.x, delta.y); // constrain delta to true change in size delta = fWindow->Frame().RightBottom() - oldRightBottom; @@ -348,6 +371,8 @@ struct DefaultWindowBehaviour::SlideTabState : MouseTrackingState { struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState { + BPoint fDelta; + ResizeBorderState(DefaultWindowBehaviour& behavior, BPoint where, Decorator::Region region) : @@ -391,6 +416,8 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState { default: break; } + + fDelta = B_ORIGIN; } ResizeBorderState(DefaultWindowBehaviour& behavior, BPoint where, @@ -401,6 +428,7 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState { fHorizontal(horizontal), fVertical(vertical) { + fDelta = B_ORIGIN; } virtual void EnterState(State* previousState) @@ -420,6 +448,11 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState { virtual void ExitState(State* nextState) { fBehavior._ResetResizeCursor(); + + if (fWindow->Flags() & B_OUTLINE_RESIZE) { + fDesktop->SetWindowOutlinesDelta(fWindow, B_ORIGIN); + fDesktop->ResizeWindowBy(fWindow, fDelta.x, fDelta.y); + } } virtual void MouseMovedAction(BPoint& delta, bigtime_t now) @@ -436,8 +469,14 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState { // to turn out differently from what we request. BPoint oldRightBottom = fWindow->Frame().RightBottom(); - fDesktop->ResizeWindowBy(fWindow, delta.x * fHorizontal, - delta.y * fVertical); + if (fWindow->Flags() & B_OUTLINE_RESIZE) { + fDelta = delta; + fDesktop->SetWindowOutlinesDelta(fWindow, BPoint( + delta.x * fHorizontal, delta.y * fVertical)); + } else { + fDesktop->ResizeWindowBy(fWindow, delta.x * fHorizontal, + delta.y * fVertical); + } // constrain delta to true change in size delta = fWindow->Frame().RightBottom() - oldRightBottom; diff --git a/src/servers/app/decorator/TabDecorator.cpp b/src/servers/app/decorator/TabDecorator.cpp index 99d61d7d76..1ebf7391f5 100644 --- a/src/servers/app/decorator/TabDecorator.cpp +++ b/src/servers/app/decorator/TabDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,7 +10,8 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Jacob Secunda, secundaja@gmail.com */ @@ -104,6 +105,10 @@ TabDecorator::Draw(BRect updateRect) fDrawingEngine->SetDrawState(&fDrawState); _DrawFrame(updateRect & fBorderRect); + + if (IsOutlineResizing()) + _DrawOutlineFrame(updateRect & fOutlineBorderRect); + _DrawTabs(updateRect & fTitleBarRect); } @@ -117,6 +122,10 @@ TabDecorator::Draw() fDrawingEngine->SetDrawState(&fDrawState); _DrawFrame(fBorderRect); + + if (IsOutlineResizing()) + _DrawOutlineFrame(fOutlineBorderRect); + _DrawTabs(fTitleBarRect); } @@ -300,6 +309,34 @@ TabDecorator::_DoLayout() } +void +TabDecorator::_DoOutlineLayout() +{ + fOutlineBorderWidth = 1; + + // calculate left/top/right/bottom outline borders + // NOTE: no overlapping, the left and right border rects + // don't include the corners! + fLeftOutlineBorder.Set(fFrame.left - fOutlineBorderWidth, fFrame.top, + fFrame.left - 1, fFrame.bottom); + + fRightOutlineBorder.Set(fFrame.right + 1, fFrame.top , + fFrame.right + fOutlineBorderWidth, fFrame.bottom); + + fTopOutlineBorder.Set(fFrame.left - fOutlineBorderWidth, + fFrame.top - fOutlineBorderWidth, + fFrame.right + fOutlineBorderWidth, fFrame.top - 1); + + fBottomOutlineBorder.Set(fFrame.left - fOutlineBorderWidth, + fFrame.bottom + 1, + fFrame.right + fOutlineBorderWidth, + fFrame.bottom + fOutlineBorderWidth); + + fOutlineBorderRect = BRect(fTopOutlineBorder.LeftTop(), + fBottomOutlineBorder.RightBottom()); +} + + void TabDecorator::_DoTabLayout() { @@ -480,6 +517,19 @@ TabDecorator::_DistributeTabSize(float delta) } +void +TabDecorator::_DrawOutlineFrame(BRect rect) +{ + drawing_mode oldMode; + + fDrawingEngine->SetDrawingMode(B_OP_ALPHA, oldMode); + fDrawingEngine->SetPattern(B_MIXED_COLORS); + fDrawingEngine->StrokeRect(rect); + + fDrawingEngine->SetDrawingMode(oldMode); +} + + void TabDecorator::_SetTitle(Decorator::Tab* tab, const char* string, BRegion* updateRegion) @@ -490,6 +540,7 @@ TabDecorator::_SetTitle(Decorator::Tab* tab, const char* string, // Get a rect of all the tabs _DoLayout(); + _DoOutlineLayout(); if (updateRegion == NULL) return; @@ -786,6 +837,8 @@ TabDecorator::_AddTab(DesktopSettings& settings, int32 index, _UpdateFont(settings); _DoLayout(); + _DoOutlineLayout(); + if (updateRegion != NULL) updateRegion->Include(fTitleBarRect); return true; @@ -797,7 +850,10 @@ TabDecorator::_RemoveTab(int32 index, BRegion* updateRegion) { BRect oldRect = TabRect(index) | TabRect(CountTabs() - 1); // Get a rect of all the tabs to the right - they will all be moved + _DoLayout(); + _DoOutlineLayout(); + if (updateRegion != NULL) { updateRegion->Include(oldRect); updateRegion->Include(fTitleBarRect); @@ -841,11 +897,10 @@ TabDecorator::_GetFootprint(BRegion *region) // 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 == NULL) return; - region->MakeEmpty(); - if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK) return; diff --git a/src/servers/app/decorator/TabDecorator.h b/src/servers/app/decorator/TabDecorator.h index 781d33a92b..ef3a5de0a2 100644 --- a/src/servers/app/decorator/TabDecorator.h +++ b/src/servers/app/decorator/TabDecorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2015 Haiku, Inc. + * Copyright 2001-2020 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,7 +10,8 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de - * Joseph Groover + * Joseph Groover, looncraz@looncraz.net + * Jacob Secunda, secundja@gmail.com */ #ifndef TAB_DECORATOR_H #define TAB_DECORATOR_H @@ -76,10 +77,12 @@ public: protected: virtual void _DoLayout(); + virtual void _DoOutlineLayout(); virtual void _DoTabLayout(); void _DistributeTabSize(float delta); virtual void _DrawFrame(BRect rect) = 0; + virtual void _DrawOutlineFrame(BRect rect); virtual void _DrawTab(Decorator::Tab* tab, BRect r) = 0; virtual void _DrawButtons(Decorator::Tab* tab, @@ -113,7 +116,7 @@ protected: virtual bool _MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion = NULL); - virtual void _GetFootprint(BRegion *region); + virtual void _GetFootprint(BRegion* region); virtual void _GetButtonSizeAndOffset(const BRect& tabRect, float* offset, float* size,