Ticket #2724: B_OUTLINE_RESIZE-1.patch

File B_OUTLINE_RESIZE-1.patch, 14.1 KB (added by TriEdgeAI, 7 years ago)
  • src/servers/app/Desktop.cpp

    From a86dcb42f20d6f418104435dabf90be70c40e96c Mon Sep 17 00:00:00 2001
    From: Tri-Edge AI <triedgeai@gmail.com>
    Date: Fri, 11 Jan 2013 21:13:33 +0200
    Subject: [PATCH] Implemented BWindow flag B_OUTLINE_RESIZE
    
    ---
     src/servers/app/Desktop.cpp                        |   21 +++-
     src/servers/app/Desktop.h                          |    2 +
     src/servers/app/Window.cpp                         |   34 +++++
     src/servers/app/Window.h                           |    2 +
     src/servers/app/decorator/Decorator.cpp            |   15 +++
     src/servers/app/decorator/Decorator.h              |    4 +
     src/servers/app/decorator/DefaultDecorator.cpp     |  133 +++++++++++++-------
     src/servers/app/decorator/DefaultDecorator.h       |    3 +
     .../app/decorator/DefaultWindowBehaviour.cpp       |   28 ++++-
     9 files changed, 195 insertions(+), 47 deletions(-)
    
    diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp
    index 845414a..dd08054 100644
    a b Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace) 
    14431443
    14441444
    14451445void
     1446Desktop::SetWindowOutlinesDelta(Window* window, BPoint delta)
     1447{
     1448    AutoWriteLocker _(fWindowLock);
     1449
     1450    if (!window->IsVisible())
     1451        return;
     1452
     1453    BRegion newDirtyRegion;
     1454    window->SetOutlinesDelta(delta, &newDirtyRegion);
     1455
     1456    BRegion background;
     1457    _RebuildClippingForAllWindows(background);
     1458
     1459    MarkDirty(newDirtyRegion);
     1460    _SetBackground(background);
     1461}
     1462
     1463
     1464void
    14461465Desktop::ResizeWindowBy(Window* window, float x, float y)
    14471466{
    14481467    if (x == 0 && y == 0)
    Desktop::ResizeWindowBy(Window* window, float x, float y) 
    14851504    // make sure the window cannot mark stuff dirty outside
    14861505    // its visible region...
    14871506    newDirtyRegion.IntersectWith(&window->VisibleRegion());
    1488     // ...because we do this outself
     1507    // ...because we do this ourself
    14891508    newDirtyRegion.Include(&previouslyOccupiedRegion);
    14901509
    14911510    MarkDirty(newDirtyRegion);
  • src/servers/app/Desktop.h

    diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h
    index daa6f78..7ee0a54 100644
    a b public: 
    172172
    173173            void                MoveWindowBy(Window* window, float x, float y,
    174174                                    int32 workspace = -1);
     175            void                SetWindowOutlinesDelta(Window* window,
     176                                    BPoint delta);
    175177            void                ResizeWindowBy(Window* window, float x,
    176178                                    float y);
    177179            bool                SetWindowTabLocation(Window* window,
  • src/servers/app/Window.cpp

    diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp
    index 117e67a..cbe8ebe 100644
    a b Window::MoveBy(int32 x, int32 y, bool moveStack) 
    334334
    335335
    336336void
     337Window::SetOutlinesDelta(BPoint delta, BRegion* dirtyRegion)
     338{
     339    float wantWidth = fFrame.IntegerWidth() + delta.x;
     340    float wantHeight = fFrame.IntegerHeight() + delta.y;
     341
     342    // enforce size limits
     343    WindowStack* stack = GetWindowStack();
     344    if (stack) {
     345        for (int32 i = 0; i < stack->CountWindows(); i++) {
     346            Window* window = stack->WindowList().ItemAt(i);
     347
     348            if (wantWidth < window->fMinWidth)
     349                wantWidth = window->fMinWidth;
     350            if (wantWidth > window->fMaxWidth)
     351                wantWidth = window->fMaxWidth;
     352
     353            if (wantHeight < window->fMinHeight)
     354                wantHeight = window->fMinHeight;
     355            if (wantHeight > window->fMaxHeight)
     356                wantHeight = window->fMaxHeight;
     357        }
     358
     359        delta.x = wantWidth - fFrame.IntegerWidth();
     360        delta.y = wantHeight - fFrame.IntegerHeight();
     361    }
     362
     363    ::Decorator* decorator = Decorator();
     364
     365    if (decorator)
     366        decorator->SetOutlinesDelta(delta, dirtyRegion);
     367}
     368
     369
     370void
    337371Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion, bool resizeStack)
    338372{
    339373    // this function is only called from the desktop thread
  • src/servers/app/Window.h

    diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h
    index 6817df2..f10da63 100644
    a b public: 
    126126            void                GetContentRegion(BRegion* region);
    127127
    128128            void                MoveBy(int32 x, int32 y, bool moveStack = true);
     129            void                SetOutlinesDelta(BPoint delta,
     130                                    BRegion* dirtyRegion);
    129131            void                ResizeBy(int32 x, int32 y,
    130132                                    BRegion* dirtyRegion,
    131133                                    bool resizeStack = true);
  • src/servers/app/decorator/Decorator.cpp

    diff --git a/src/servers/app/decorator/Decorator.cpp b/src/servers/app/decorator/Decorator.cpp
    index 1bd90bb..afdb442 100644
    a b Decorator::MoveBy(BPoint offset) 
    546546}
    547547
    548548
     549void
     550Decorator::SetOutlinesDelta(BPoint delta, BRegion* dirty)
     551{
     552    _SetOutlinesDelta(delta, dirty);
     553    _InvalidateFootprint();
     554}
     555
     556
    549557/*! \brief Resizes the decorator frame
    550558
    551559    This is a required function for subclasses to implement - the default does
    Decorator::_MoveBy(BPoint offset) 
    887895}
    888896
    889897
     898void
     899Decorator::_SetOutlinesDelta(BPoint offset, BRegion* dirty)
     900{
     901    // Implemented by subclasses.
     902}
     903
     904
    890905bool
    891906Decorator::_SetSettings(const BMessage& settings, BRegion* updateRegion)
    892907{
  • src/servers/app/decorator/Decorator.h

    diff --git a/src/servers/app/decorator/Decorator.h b/src/servers/app/decorator/Decorator.h
    index 40c740d..a27211e 100644
    a b public: 
    143143
    144144            void            MoveBy(float x, float y);
    145145            void            MoveBy(BPoint offset);
     146            void            SetOutlinesDelta(BPoint delta, BRegion* dirty);
    146147            void            ResizeBy(float x, float y, BRegion* dirty);
    147148            void            ResizeBy(BPoint offset, BRegion* dirty);
    148149
    protected: 
    204205                                BRegion* updateRegion = NULL);
    205206
    206207    virtual void            _MoveBy(BPoint offset);
     208    virtual void            _SetOutlinesDelta(BPoint offset, BRegion* dirty);
    207209    virtual void            _ResizeBy(BPoint offset, BRegion* dirty) = 0;
    208210
    209211    virtual bool            _SetSettings(const BMessage& settings,
    protected: 
    223225            DrawingEngine*  fDrawingEngine;
    224226            DrawState       fDrawState;
    225227
     228            BPoint          fOutlinesDelta;
     229
    226230            BRect           fTitleBarRect;
    227231            BRect           fFrame;
    228232            BRect           fResizeRect;
  • src/servers/app/decorator/DefaultDecorator.cpp

    diff --git a/src/servers/app/decorator/DefaultDecorator.cpp b/src/servers/app/decorator/DefaultDecorator.cpp
    index 4e1b245..896367d 100644
    a b DefaultDecorator::_DrawFrame(BRect invalid) 
    794794
    795795    // Draw the resize knob if we're supposed to
    796796    if (!(fTopTab->flags & B_NOT_RESIZABLE)) {
    797         r = fResizeRect;
    798 
    799797        ComponentColors colors;
    800798        _GetComponentColors(COMPONENT_RESIZE_CORNER, colors, fTopTab);
    801799
    802800        switch ((int)fTopTab->look) {
    803801            case B_DOCUMENT_WINDOW_LOOK:
    804802            {
    805                 if (!invalid.Intersects(r))
    806                     break;
    807 
    808                 float x = r.right - 3;
    809                 float y = r.bottom - 3;
    810 
    811                 BRect bg(x - 13, y - 13, x, y);
    812 
    813                 BGradientLinear gradient;
    814                 gradient.SetStart(bg.LeftTop());
    815                 gradient.SetEnd(bg.RightBottom());
    816                 gradient.AddColor(colors[1], 0);
    817                 gradient.AddColor(colors[2], 255);
    818 
    819                 fDrawingEngine->FillRect(bg, gradient);
     803                if (fOutlinesDelta.x != 0 || fOutlinesDelta.y != 0) {
     804                    r.Set(fFrame.right - 13, fFrame.bottom - 13,
     805                        fFrame.right + 3, fFrame.bottom + 3);
    820806
    821                 fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15),
    822                     BPoint(x - 15, y - 2), colors[0]);
    823                 fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14),
    824                     BPoint(x - 14, y - 1), colors[1]);
    825                 fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15),
    826                     BPoint(x - 2, y - 15), colors[0]);
    827                 fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14),
    828                     BPoint(x - 1, y - 14), colors[1]);
     807                    if (invalid.Intersects(r))
     808                        _DrawResizeKnob(r, false, colors);
     809                }
    829810
    830                 if (fTopTab && !IsFocus(fTopTab))
    831                     break;
     811                if (invalid.Intersects(fResizeRect))
     812                    _DrawResizeKnob(fResizeRect, fTopTab && IsFocus(fTopTab), colors);
    832813
    833                 static const rgb_color kWhite
    834                     = (rgb_color){ 255, 255, 255, 255 };
    835                 for (int8 i = 1; i <= 4; i++) {
    836                     for (int8 j = 1; j <= i; j++) {
    837                         BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1);
    838                         BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2);
    839                         fDrawingEngine->StrokePoint(pt1, colors[0]);
    840                         fDrawingEngine->StrokePoint(pt2, kWhite);
    841                     }
    842                 }
    843814                break;
    844815            }
    845816
    DefaultDecorator::_DrawFrame(BRect invalid) 
    873844
    874845
    875846void
     847DefaultDecorator::_DrawResizeKnob(BRect r, bool full, const ComponentColors& colors)
     848{
     849    float x = r.right -= 3;
     850    float y = r.bottom -= 3;
     851
     852    BGradientLinear gradient;
     853    gradient.SetStart(r.LeftTop());
     854    gradient.SetEnd(r.RightBottom());
     855    gradient.AddColor(colors[1], 0);
     856    gradient.AddColor(colors[2], 255);
     857
     858    fDrawingEngine->FillRect(r, gradient);
     859
     860    fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15),
     861        BPoint(x - 15, y - 2), colors[0]);
     862    fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14),
     863        BPoint(x - 14, y - 1), colors[1]);
     864    fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15),
     865        BPoint(x - 2, y - 15), colors[0]);
     866    fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14),
     867        BPoint(x - 1, y - 14), colors[1]);
     868
     869    if (!full)
     870        return;
     871
     872    static const rgb_color kWhite
     873        = (rgb_color){ 255, 255, 255, 255 };
     874    for (int8 i = 1; i <= 4; i++) {
     875        for (int8 j = 1; j <= i; j++) {
     876            BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1);
     877            BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2);
     878            fDrawingEngine->StrokePoint(pt1, colors[0]);
     879            fDrawingEngine->StrokePoint(pt2, kWhite);
     880        }
     881    }
     882}
     883
     884
     885void
    876886DefaultDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid)
    877887{
    878888    STRACE(("_DrawTab(%.1f,%.1f,%.1f,%.1f)\n",
    DefaultDecorator::_MoveBy(BPoint offset) 
    11511161
    11521162
    11531163void
     1164DefaultDecorator::_SetOutlinesDelta(BPoint delta, BRegion* dirty)
     1165{
     1166    BPoint offset = delta - fOutlinesDelta;
     1167    fOutlinesDelta = delta;
     1168
     1169    dirty->Include(fLeftBorder);
     1170    dirty->Include(fRightBorder);
     1171    dirty->Include(fTopBorder);
     1172    dirty->Include(fBottomBorder);
     1173
     1174    fBorderRect.right += offset.x;
     1175    fBorderRect.bottom += offset.y;
     1176
     1177    fLeftBorder.bottom += offset.y;
     1178    fTopBorder.right += offset.x;
     1179
     1180    fRightBorder.OffsetBy(offset.x, 0.0);
     1181    fRightBorder.bottom += offset.y;
     1182
     1183    fBottomBorder.OffsetBy(0.0, offset.y);
     1184    fBottomBorder.right += offset.x;
     1185
     1186    dirty->Include(fLeftBorder);
     1187    dirty->Include(fRightBorder);
     1188    dirty->Include(fTopBorder);
     1189    dirty->Include(fBottomBorder);
     1190
     1191    dirty->Exclude(fFrame);
     1192        // The key thing about B_OUTLINE_RESIZE
     1193
     1194    dirty->Include(fResizeRect);
     1195    fResizeRect.OffsetBy(offset);
     1196    dirty->Include(fResizeRect);
     1197}
     1198
     1199
     1200void
    11541201DefaultDecorator::_ResizeBy(BPoint offset, BRegion* dirty)
    11551202{
    11561203    STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", offset.x, offset.y));
    DefaultDecorator::_SetTabLocation(Decorator::Tab* _tab, float location, 
    13151362                fOldMovingTab = _tab->tabRect;
    13161363        }
    13171364    }
    1318    
     1365
    13191366    DefaultDecorator::Tab* tab = static_cast<DefaultDecorator::Tab*>(_tab);
    13201367    BRect& tabRect = tab->tabRect;
    13211368    if (tabRect.IsValid() == false)
    DefaultDecorator::_SetTabLocation(Decorator::Tab* _tab, float location, 
    13571404    rect.bottom++;
    13581405    if (updateRegion != NULL)
    13591406        updateRegion->Include(rect);
    1360    
     1407
    13611408    return true;
    13621409}
    13631410
    DefaultDecorator::_GetFootprint(BRegion *region) 
    14551502    region->Include(&fTabsRegion);
    14561503
    14571504    if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK) {
    1458         // include the rectangular resize knob on the bottom right
    1459         float knobSize = kResizeKnobSize - fBorderWidth;
    1460         region->Include(BRect(fFrame.right - knobSize, fFrame.bottom - knobSize,
    1461             fFrame.right, fFrame.bottom));
     1505        region->Include(BRect(fFrame.right - 13.0f, fFrame.bottom - 13.0f,
     1506                        fFrame.right, fFrame.bottom));
     1507
     1508        region->Include(fResizeRect);
    14621509    }
    14631510}
    14641511
  • src/servers/app/decorator/DefaultDecorator.h

    diff --git a/src/servers/app/decorator/DefaultDecorator.h b/src/servers/app/decorator/DefaultDecorator.h
    index 7f46309..ca3a67c 100644
    a b protected: 
    110110            DefaultDecorator::Tab*  _TabAt(int32 index) const;
    111111
    112112    virtual void                _DrawFrame(BRect r);
     113    virtual void                _DrawResizeKnob(BRect r, bool full,
     114                                    const ComponentColors& color);
    113115    virtual void                _DrawTab(Decorator::Tab* tab, BRect r);
    114116
    115117    virtual void                _DrawClose(Decorator::Tab* tab, bool direct,
    protected: 
    132134                                    BRegion* updateRegion = NULL);
    133135
    134136    virtual void                _MoveBy(BPoint offset);
     137    virtual void                _SetOutlinesDelta(BPoint delta, BRegion* dirty);
    135138    virtual void                _ResizeBy(BPoint offset, BRegion* dirty);
    136139
    137140    virtual bool                _SetTabLocation(Decorator::Tab* tab,
  • src/servers/app/decorator/DefaultWindowBehaviour.cpp

    diff --git a/src/servers/app/decorator/DefaultWindowBehaviour.cpp b/src/servers/app/decorator/DefaultWindowBehaviour.cpp
    index d6650d0..5681a96 100644
    a b  
    1717
    1818#include <math.h>
    1919
     20#include <PortLink.h>
    2021#include <WindowPrivate.h>
    2122
     23#include "AppServer.h"
    2224#include "ClickTarget.h"
    2325#include "Desktop.h"
    2426#include "DefaultDecorator.h"
    struct DefaultWindowBehaviour::DragState : MouseTrackingState { 
    250252
    251253
    252254struct DefaultWindowBehaviour::ResizeState : MouseTrackingState {
     255    BPoint fDelta;
     256
    253257    ResizeState(DefaultWindowBehaviour& behavior, BPoint where,
    254258        bool activateOnMouseUp)
    255259        :
    256         MouseTrackingState(behavior, where, activateOnMouseUp, false)
     260        MouseTrackingState(behavior, where, activateOnMouseUp, true)
     261    {
     262        fDelta = BPoint(0, 0);
     263    }
     264
     265    virtual void EnterState(State* prevState)
     266    {
     267
     268    }
     269
     270    virtual void ExitState(State* nextState)
    257271    {
     272        if (fWindow->Flags() & B_OUTLINE_RESIZE) {
     273            fDesktop->SetWindowOutlinesDelta(fWindow, BPoint(0, 0));
     274            fDesktop->ResizeWindowBy(fWindow, fDelta.x, fDelta.y);
     275        }
    258276    }
    259277
    260278    virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
    struct DefaultWindowBehaviour::ResizeState : MouseTrackingState { 
    267285
    268286            BPoint oldRightBottom = fWindow->Frame().RightBottom();
    269287
    270             fDesktop->ResizeWindowBy(fWindow, delta.x, delta.y);
     288            if (fWindow->Flags() & B_OUTLINE_RESIZE) {
     289                fDelta = delta;
     290                fDesktop->SetWindowOutlinesDelta(fWindow, delta);
     291            } else
     292                fDesktop->ResizeWindowBy(fWindow, delta.x, delta.y);
    271293
    272294            // constrain delta to true change in size
    273295            delta = fWindow->Frame().RightBottom() - oldRightBottom;
    struct DefaultWindowBehaviour::SlideTabState : MouseTrackingState { 
    336358                neighbourTab->tabOffset + neighbourTab->tabRect.Width() / 2)
    337359                return;
    338360        }
    339        
     361
    340362        fWindow->MoveToStackPosition(neighbourIndex, isShifting);
    341363    }
    342364};