app_server: Implement B_OUTLINE_RESIZE

- Allows applications to be resized without the window contents resizing with the window frame.
- Due to the nature of out-of-tree decorators using private APIs, this will require all pre-existing decorators to be rebuilt
- Newer decorators won't work on older versions of Haiku...
- Also has some formatting with license headers.
- Fixes #2724

Change-Id: Id0b45e7bbc0b636e6dffbd396eb584bf348b5296
Reviewed-on: https://review.haiku-os.org/c/haiku/+/344
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: Jacob Secunda <[email protected]>
This commit is contained in:
Tri-Edge AI
2021-03-19 10:17:01 +00:00
committed by Adrien Destugues
parent 29034cf270
commit 773d5303d1
11 changed files with 449 additions and 124 deletions
+31 -10
View File
@@ -1,16 +1,18 @@
/*
* Copyright 2001-2016, Haiku.
* Copyright 2001-2020, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <[email protected]>
* Stephan Aßmus <[email protected]>
* Axel Dörfler <[email protected]>
* Andrej Spielmann <[email protected]>
* Brecht Machiels <[email protected]>
* Clemens Zeidler <[email protected]>
* Ingo Weinhold <[email protected]>
* Joseph Groover <[email protected]>
* Adrian Oanca, [email protected]
* Stephan Aßmus, [email protected]
* Axel Dörfler, [email protected]
* Andrej Spielmann, [email protected]
* Brecht Machiels, [email protected]
* Clemens Zeidler, [email protected]
* Ingo Weinhold, [email protected]
* Joseph Groover, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
@@ -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)
{
+12 -8
View File
@@ -1,15 +1,17 @@
/*
* Copyright 2001-2015, Haiku.
* Copyright 2001-2020, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <[email protected]>
* Stephan Aßmus <[email protected]>
* Axel Dörfler <[email protected]>
* Andrej Spielmann, <[email protected]>
* Brecht Machiels <[email protected]>
* Clemens Zeidler <[email protected]>
* Joseph Groover <[email protected]>
* Adrian Oanca, [email protected]
* Stephan Aßmus, [email protected]
* Axel Dörfler, [email protected]
* Andrej Spielmann, [email protected]
* Brecht Machiels, [email protected]
* Clemens Zeidler, [email protected]
* Joseph Groover, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
#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,
+45 -7
View File
@@ -1,14 +1,16 @@
/*
* Copyright 2001-2011, Haiku, Inc.
* Copyright 2001-2020, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <[email protected]>
* Adi Oanca <[email protected]>
* Stephan Aßmus <[email protected]>
* Axel Dörfler <[email protected]>
* Brecht Machiels <[email protected]>
* Clemens Zeidler <[email protected]>
* DarkWyrm, [email protected]
* Adi Oanca, [email protected]
* Stephan Aßmus, [email protected]
* Axel Dörfler, [email protected]
* Brecht Machiels, [email protected]
* Clemens Zeidler, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
@@ -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)
{
+11 -7
View File
@@ -1,14 +1,16 @@
/*
* Copyright 2001-2011, Haiku, Inc.
* Copyright 2001-2020, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <[email protected]>
* Adi Oanca <[email protected]>
* Stephan Aßmus <[email protected]>
* Axel Dörfler <[email protected]>
* Brecht Machiels <[email protected]>
* Clemens Zeidler <[email protected]>
* DarkWyrm, [email protected]
* Adi Oanca, [email protected]
* Stephan Aßmus, [email protected]
* Axel Dörfler, [email protected]
* Brecht Machiels, [email protected]
* Clemens Zeidler, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
#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);
+108 -3
View File
@@ -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, [email protected]
* Ingo Weinhold, [email protected]
* Clemens Zeidler, [email protected]
* Joseph Groover <[email protected]>
* Joseph Groover, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
@@ -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()
{
+24 -3
View File
@@ -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, [email protected]
* Ingo Weinhold, [email protected]
* Clemens Zeidler, [email protected]
* Joseph Groover <[email protected]>
* Joseph Groover, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
#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<Decorator::Tab> fTabList;
+96 -65
View File
@@ -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, [email protected]
* Ingo Weinhold, [email protected]
* Clemens Zeidler, [email protected]
* Joseph Groover <[email protected]>
* Joseph Groover, [email protected]
* Tri-Edge AI
* Jacob Secunda, [email protected]
*/
@@ -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,
+6 -2
View File
@@ -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 <looncraz@looncraz.net>
* 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,
@@ -1,15 +1,17 @@
/*
* Copyright 2001-2010, Haiku, Inc.
* Copyright 2001-2020, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* 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>
* 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 <math.h>
#include <PortLink.h>
#include <WindowPrivate.h>
#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;
+59 -4
View File
@@ -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 <looncraz@looncraz.net>
* 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;
+6 -3
View File
@@ -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 <looncraz@looncraz.net>
* 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,