Add multi tab support to the default decorator as discussed on the mailing list. Windows can be stacked on top of one another. All windows using the same decorator instance. This makes it easier to draw the stacked tabs and makes it possible to design more fancy looks for stacked windows. This also helps to fix some issues in S&T, e.g. when activating one window in a stacked group all windows have to be activated to ensure that all tabs are on top. This causes some flickering in tracker.
* Each Window has a reference counted WindowStack class which can be shared between stacked Windows. To keep the Decorator separated from Window there is another tab list in the Decorator now. The index of the stacked Window in the window stack is the same as the index of the tab in the Decorator. Properties like title or window focus are managed on a per tab basis now. This mean when you set the title in the Decorator you also have to specify the tab id which is equal to the window position in the stack. * When drawing the decorator its important that only the top window is doing the drawing. Also the top window drawing engine should be used. Actually that is only a problem directly after a window is stacked and the other window has still a none empty dirty region. In this case we clear the dirty region of this window and stop the drawing (the top window will draw everything). * Track if shifting of a tab is still ongoing, i.e. mouse still down. * The key event filter called the DesktopListener without holding the window write lock. This probably caused #7801 and #7796. * Commented out assert's in Window::SetScreen and Window::Screen. Add TODO because I'm not sure about the screen access. This breaks all existing decorators again, sorry guys! Haven't looked into any other then the default decorator (and the SAT decorator). Will not fix the others in the near future so go for it! Since applications should be able to rely on S&T features the other decorator must be able to handle multiple tabs as well. A simple solution would be to draw all title bars in multiple rows. That probably looks quit poorly. Think the better solution would be to draw a tab interface in the title bar, e.g. like in KDE. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42478 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -65,15 +65,16 @@ DecorAddOn::AllocateDecorator(Desktop* desktop, DrawingEngine* engine,
|
||||
DesktopSettings settings(desktop);
|
||||
Decorator* decorator;
|
||||
decorator = _AllocateDecorator(settings, rect, look, flags);
|
||||
|
||||
desktop->UnlockSingleWindow();
|
||||
|
||||
if (!decorator)
|
||||
return NULL;
|
||||
|
||||
decorator->SetDrawingEngine(engine);
|
||||
decorator->SetTitle(title);
|
||||
if (decorator->AddTab(title) == false) {
|
||||
delete decorator;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decorator->SetDrawingEngine(engine);
|
||||
return decorator;
|
||||
}
|
||||
|
||||
|
||||
+363
-175
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku.
|
||||
* Copyright 2001-2011, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -22,6 +22,22 @@
|
||||
#include "DrawingEngine.h"
|
||||
|
||||
|
||||
Decorator::Tab::Tab()
|
||||
:
|
||||
zoomRect(),
|
||||
closeRect(),
|
||||
minimizeRect(),
|
||||
|
||||
closePressed(false),
|
||||
zoomPressed(false),
|
||||
minimizePressed(false),
|
||||
isFocused(false),
|
||||
title("")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Constructor
|
||||
|
||||
Does general initialization of internal data members and creates a colorset
|
||||
@@ -41,19 +57,12 @@ Decorator::Decorator(DesktopSettings& settings, BRect rect, window_look look,
|
||||
fLook(look),
|
||||
fFlags(flags),
|
||||
|
||||
fZoomRect(),
|
||||
fCloseRect(),
|
||||
fMinimizeRect(),
|
||||
fTabRect(),
|
||||
fTitleBarRect(),
|
||||
fFrame(rect),
|
||||
fResizeRect(),
|
||||
fBorderRect(),
|
||||
|
||||
fClosePressed(false),
|
||||
fZoomPressed(false),
|
||||
fMinimizePressed(false),
|
||||
fIsFocused(false),
|
||||
fTitle(""),
|
||||
fTopTab(NULL),
|
||||
|
||||
fFootprintValid(false)
|
||||
{
|
||||
@@ -71,6 +80,89 @@ Decorator::~Decorator()
|
||||
}
|
||||
|
||||
|
||||
Decorator::Tab*
|
||||
Decorator::AddTab(const char* title, int32 index, BRegion* updateRegion)
|
||||
{
|
||||
Decorator::Tab* tab = _AllocateNewTab();
|
||||
if (tab == NULL)
|
||||
return NULL;
|
||||
tab->title = title;
|
||||
|
||||
bool ok = false;
|
||||
if (index >= 0) {
|
||||
if (fTabList.AddItem(tab, index) == true)
|
||||
ok = true;
|
||||
} else if (fTabList.AddItem(tab) == true)
|
||||
ok = true;
|
||||
|
||||
if (ok == false) {
|
||||
delete tab;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_AddTab(index, updateRegion) == false) {
|
||||
fTabList.RemoveItem(tab);
|
||||
delete tab;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fTopTab == NULL)
|
||||
fTopTab = tab;
|
||||
|
||||
_InvalidateFootprint();
|
||||
return tab;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::RemoveTab(int32 index, BRegion* updateRegion)
|
||||
{
|
||||
Decorator::Tab* tab = fTabList.RemoveItemAt(index);
|
||||
if (tab == NULL)
|
||||
return false;
|
||||
|
||||
_RemoveTab(index, updateRegion);
|
||||
|
||||
delete tab;
|
||||
_InvalidateFootprint();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion)
|
||||
{
|
||||
if (_MoveTab(from, to, isMoving, updateRegion) == false)
|
||||
return false;
|
||||
if (fTabList.MoveItem(from, to) == false) {
|
||||
// move the tab back
|
||||
_MoveTab(from, to, isMoving, updateRegion);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Decorator::TabAt(const BPoint& where) const
|
||||
{
|
||||
for (int32 i = 0; i < fTabList.CountItems(); i++) {
|
||||
Decorator::Tab* tab = fTabList.ItemAt(i);
|
||||
if (tab->tabRect.Contains(where))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Decorator::SetTopTap(int32 tab)
|
||||
{
|
||||
fTopTab = fTabList.ItemAt(tab);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Assigns a display driver to the decorator
|
||||
\param driver A valid DrawingEngine object
|
||||
*/
|
||||
@@ -132,71 +224,6 @@ Decorator::SetLook(DesktopSettings& settings, window_look look,
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Sets the close button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
void
|
||||
Decorator::SetClose(bool pressed)
|
||||
{
|
||||
if (pressed != fClosePressed) {
|
||||
fClosePressed = pressed;
|
||||
DrawClose();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Sets the minimize button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
void
|
||||
Decorator::SetMinimize(bool pressed)
|
||||
{
|
||||
if (pressed != fMinimizePressed) {
|
||||
fMinimizePressed = pressed;
|
||||
DrawMinimize();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Sets the zoom button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
void
|
||||
Decorator::SetZoom(bool pressed)
|
||||
{
|
||||
if (pressed != fZoomPressed) {
|
||||
fZoomPressed = pressed;
|
||||
DrawZoom();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Updates the value of the decorator title
|
||||
\param string New title value
|
||||
*/
|
||||
void
|
||||
Decorator::SetTitle(const char* string, BRegion* updateRegion)
|
||||
{
|
||||
fTitle.SetTo(string);
|
||||
_SetTitle(string, updateRegion);
|
||||
|
||||
_InvalidateFootprint();
|
||||
// the border very likely changed
|
||||
|
||||
// TODO: redraw?
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the decorator's window look
|
||||
\return the decorator's window look
|
||||
*/
|
||||
@@ -217,16 +244,6 @@ Decorator::Flags() const
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the decorator's title
|
||||
\return the decorator's title
|
||||
*/
|
||||
const char*
|
||||
Decorator::Title() const
|
||||
{
|
||||
return fTitle.String();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the decorator's border rectangle
|
||||
\return the decorator's border rectangle
|
||||
*/
|
||||
@@ -237,52 +254,149 @@ Decorator::BorderRect() const
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
Decorator::TitleBarRect() const
|
||||
{
|
||||
return fTitleBarRect;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the decorator's tab rectangle
|
||||
\return the decorator's tab rectangle
|
||||
*/
|
||||
BRect
|
||||
Decorator::TabRect() const
|
||||
Decorator::TabRect(int32 tab) const
|
||||
{
|
||||
return fTabRect;
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return BRect();
|
||||
return decoratorTab->tabRect;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the value of the close button
|
||||
\return true if down, false if up
|
||||
BRect
|
||||
Decorator::TabRect(Decorator::Tab* tab) const
|
||||
{
|
||||
return tab->tabRect;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Sets the close button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
bool
|
||||
Decorator::GetClose()
|
||||
{
|
||||
return fClosePressed;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the value of the minimize button
|
||||
\return true if down, false if up
|
||||
*/
|
||||
bool
|
||||
Decorator::GetMinimize()
|
||||
{
|
||||
return fMinimizePressed;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the value of the zoom button
|
||||
\return true if down, false if up
|
||||
*/
|
||||
bool
|
||||
Decorator::GetZoom()
|
||||
{
|
||||
return fZoomPressed;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth,
|
||||
int32* maxHeight) const
|
||||
Decorator::SetClose(int32 tab, bool pressed)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
|
||||
if (pressed != decoratorTab->closePressed) {
|
||||
decoratorTab->closePressed = pressed;
|
||||
DrawClose(tab);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Sets the minimize button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
void
|
||||
Decorator::SetMinimize(int32 tab, bool pressed)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
|
||||
if (pressed != decoratorTab->minimizePressed) {
|
||||
decoratorTab->minimizePressed = pressed;
|
||||
DrawMinimize(tab);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Sets the zoom button's value.
|
||||
|
||||
Note that this does not update the button's look - it just updates the
|
||||
internal button value
|
||||
|
||||
\param is_down Whether the button is down or not
|
||||
*/
|
||||
void
|
||||
Decorator::SetZoom(int32 tab, bool pressed)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
|
||||
if (pressed != decoratorTab->zoomPressed) {
|
||||
decoratorTab->zoomPressed = pressed;
|
||||
DrawZoom(tab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Updates the value of the decorator title
|
||||
\param string New title value
|
||||
*/
|
||||
void
|
||||
Decorator::SetTitle(int32 tab, const char* string, BRegion* updateRegion)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
|
||||
decoratorTab->title.SetTo(string);
|
||||
_SetTitle(decoratorTab, string, updateRegion);
|
||||
|
||||
_InvalidateFootprint();
|
||||
// the border very likely changed
|
||||
|
||||
// TODO: redraw?
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the decorator's title
|
||||
\return the decorator's title
|
||||
*/
|
||||
const char*
|
||||
Decorator::Title(int32 tab) const
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return "";
|
||||
return decoratorTab->title;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
Decorator::Title(Decorator::Tab* tab) const
|
||||
{
|
||||
return tab->title;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::SetTabLocation(int32 tab, float location, bool isShifting,
|
||||
BRegion* updateRegion)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return false;
|
||||
if (_SetTabLocation(decoratorTab, location, isShifting, updateRegion)) {
|
||||
_InvalidateFootprint();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Changes the focus value of the decorator
|
||||
|
||||
@@ -292,14 +406,41 @@ Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth,
|
||||
\param active True if active, false if not
|
||||
*/
|
||||
void
|
||||
Decorator::SetFocus(bool active)
|
||||
Decorator::SetFocus(int32 tab, bool active)
|
||||
{
|
||||
fIsFocused = active;
|
||||
_SetFocus();
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
decoratorTab->isFocused = active;
|
||||
_SetFocus(decoratorTab);
|
||||
// TODO: maybe it would be cleaner to handle the redraw here.
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::IsFocus(int32 tab) const
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return false;
|
||||
return decoratorTab->isFocused;
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
Decorator::IsFocus(Decorator::Tab* tab) const
|
||||
{
|
||||
return tab->isFocused;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth,
|
||||
int32* maxHeight) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - virtual methods
|
||||
|
||||
|
||||
@@ -339,14 +480,25 @@ Decorator::GetFootprint()
|
||||
- \c REGION_RIGHT_BOTTOM_CORNER The right-bottom corner.
|
||||
*/
|
||||
Decorator::Region
|
||||
Decorator::RegionAt(BPoint where) const
|
||||
Decorator::RegionAt(BPoint where, int32& tabIndex) const
|
||||
{
|
||||
if (fCloseRect.Contains(where))
|
||||
return REGION_CLOSE_BUTTON;
|
||||
if (fZoomRect.Contains(where))
|
||||
return REGION_ZOOM_BUTTON;
|
||||
if (fTabRect.Contains(where))
|
||||
return REGION_TAB;
|
||||
tabIndex = -1;
|
||||
|
||||
for (int32 i = 0; i < fTabList.CountItems(); i++) {
|
||||
Decorator::Tab* tab = fTabList.ItemAt(i);
|
||||
if (tab->closeRect.Contains(where)) {
|
||||
tabIndex = i;
|
||||
return REGION_CLOSE_BUTTON;
|
||||
}
|
||||
if (tab->zoomRect.Contains(where)) {
|
||||
tabIndex = i;
|
||||
return REGION_ZOOM_BUTTON;
|
||||
}
|
||||
if (tab->tabRect.Contains(where)) {
|
||||
tabIndex = i;
|
||||
return REGION_TAB;
|
||||
}
|
||||
}
|
||||
|
||||
return REGION_NONE;
|
||||
}
|
||||
@@ -411,17 +563,6 @@ Decorator::ResizeBy(BPoint offset, BRegion* dirty)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::SetTabLocation(float location, BRegion* updateRegion)
|
||||
{
|
||||
if (_SetTabLocation(location, updateRegion)) {
|
||||
_InvalidateFootprint();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Sets a specific highlight for a decorator region.
|
||||
|
||||
Can be overridden by derived classes, but the base class version must be
|
||||
@@ -434,7 +575,8 @@ Decorator::SetTabLocation(float location, BRegion* updateRegion)
|
||||
\return \c true, if the highlight could be applied.
|
||||
*/
|
||||
bool
|
||||
Decorator::SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty)
|
||||
Decorator::SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty,
|
||||
int32 tab)
|
||||
{
|
||||
int32 index = (int32)region - 1;
|
||||
if (index < 0 || index >= REGION_COUNT - 1)
|
||||
@@ -479,7 +621,7 @@ void
|
||||
Decorator::Draw(BRect rect)
|
||||
{
|
||||
_DrawFrame(rect & fFrame);
|
||||
_DrawTab(rect & fTabRect);
|
||||
_DrawTabs(rect & fTitleBarRect);
|
||||
}
|
||||
|
||||
|
||||
@@ -488,15 +630,7 @@ void
|
||||
Decorator::Draw()
|
||||
{
|
||||
_DrawFrame(fFrame);
|
||||
_DrawTab(fTabRect);
|
||||
}
|
||||
|
||||
|
||||
//! Draws the close button
|
||||
void
|
||||
Decorator::DrawClose()
|
||||
{
|
||||
_DrawClose(fCloseRect);
|
||||
_DrawTabs(fTitleBarRect);
|
||||
}
|
||||
|
||||
|
||||
@@ -508,39 +642,63 @@ Decorator::DrawFrame()
|
||||
}
|
||||
|
||||
|
||||
//! draws the minimize button
|
||||
//! draws the tab, title, and buttons
|
||||
void
|
||||
Decorator::DrawMinimize()
|
||||
Decorator::DrawTab(int32 tabIndex)
|
||||
{
|
||||
_DrawTab(fMinimizeRect);
|
||||
Decorator::Tab* tab = fTabList.ItemAt(tabIndex);
|
||||
if (tab == NULL)
|
||||
return;
|
||||
|
||||
_DrawTab(tab, tab->tabRect);
|
||||
_DrawZoom(tab, tab->zoomRect);
|
||||
_DrawMinimize(tab, tab->minimizeRect);
|
||||
_DrawTitle(tab, tab->tabRect);
|
||||
_DrawClose(tab, tab->closeRect);
|
||||
}
|
||||
|
||||
|
||||
//! draws the tab, title, and buttons
|
||||
//! Draws the close button
|
||||
void
|
||||
Decorator::DrawTab()
|
||||
Decorator::DrawClose(int32 tab)
|
||||
{
|
||||
_DrawTab(fTabRect);
|
||||
_DrawZoom(fZoomRect);
|
||||
_DrawMinimize(fMinimizeRect);
|
||||
_DrawTitle(fTabRect);
|
||||
_DrawClose(fCloseRect);
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
_DrawClose(decoratorTab, decoratorTab->closeRect);
|
||||
}
|
||||
|
||||
|
||||
//! draws the minimize button
|
||||
void
|
||||
Decorator::DrawMinimize(int32 tab)
|
||||
{
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
_DrawTab(decoratorTab, decoratorTab->minimizeRect);
|
||||
}
|
||||
|
||||
|
||||
//! draws the title
|
||||
void
|
||||
Decorator::DrawTitle()
|
||||
Decorator::DrawTitle(int32 tab)
|
||||
{
|
||||
_DrawTitle(fTabRect);
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
_DrawTitle(decoratorTab, decoratorTab->tabRect);
|
||||
}
|
||||
|
||||
|
||||
//! draws the zoom button
|
||||
void
|
||||
Decorator::DrawZoom()
|
||||
Decorator::DrawZoom(int32 tab)
|
||||
{
|
||||
_DrawZoom(fZoomRect);
|
||||
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
|
||||
if (decoratorTab == NULL)
|
||||
return;
|
||||
_DrawZoom(decoratorTab, decoratorTab->zoomRect);
|
||||
}
|
||||
|
||||
|
||||
@@ -582,6 +740,24 @@ Decorator::_DrawFrame(BRect rect)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Decorator::_DrawTabs(BRect rect)
|
||||
{
|
||||
Decorator::Tab* focusTab = NULL;
|
||||
for (int32 i = 0; i < fTabList.CountItems(); i++) {
|
||||
Decorator::Tab* tab = fTabList.ItemAt(i);
|
||||
if (tab->isFocused) {
|
||||
focusTab = tab;
|
||||
continue;
|
||||
}
|
||||
_DrawTab(tab, rect);
|
||||
}
|
||||
if (focusTab != NULL)
|
||||
_DrawTab(focusTab, rect);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Actually draws the tab
|
||||
|
||||
This function is called when the tab itself needs drawn. Other items,
|
||||
@@ -590,7 +766,7 @@ Decorator::_DrawFrame(BRect rect)
|
||||
\param rect Area of the tab to update
|
||||
*/
|
||||
void
|
||||
Decorator::_DrawTab(BRect rect)
|
||||
Decorator::_DrawTab(Decorator::Tab* tab, BRect rect)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -603,7 +779,7 @@ Decorator::_DrawTab(BRect rect)
|
||||
\param rect Area of the button to update
|
||||
*/
|
||||
void
|
||||
Decorator::_DrawClose(BRect rect)
|
||||
Decorator::_DrawClose(Decorator::Tab* tab, BRect rect)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -618,7 +794,7 @@ Decorator::_DrawClose(BRect rect)
|
||||
\param rect area of the title to update
|
||||
*/
|
||||
void
|
||||
Decorator::_DrawTitle(BRect rect)
|
||||
Decorator::_DrawTitle(Decorator::Tab* tab, BRect rect)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -631,7 +807,7 @@ Decorator::_DrawTitle(BRect rect)
|
||||
\param rect Area of the button to update
|
||||
*/
|
||||
void
|
||||
Decorator::_DrawZoom(BRect rect)
|
||||
Decorator::_DrawZoom(Decorator::Tab* tab, BRect rect)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -644,14 +820,22 @@ Decorator::_DrawZoom(BRect rect)
|
||||
\param rect Area of the button to update
|
||||
*/
|
||||
void
|
||||
Decorator::_DrawMinimize(BRect rect)
|
||||
Decorator::_DrawMinimize(Decorator::Tab* tab, BRect rect)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Decorator::_SetTabLocation(Decorator::Tab* tab, float location, bool isShifting,
|
||||
BRegion* /*updateRegion*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! Hook function called when the decorator changes focus
|
||||
void
|
||||
Decorator::_SetFocus()
|
||||
Decorator::_SetFocus(Decorator::Tab* tab)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -680,11 +864,15 @@ Decorator::_SetFlags(uint32 flags, BRegion* updateRegion)
|
||||
void
|
||||
Decorator::_MoveBy(BPoint offset)
|
||||
{
|
||||
fZoomRect.OffsetBy(offset);
|
||||
fCloseRect.OffsetBy(offset);
|
||||
fMinimizeRect.OffsetBy(offset);
|
||||
fMinimizeRect.OffsetBy(offset);
|
||||
fTabRect.OffsetBy(offset);
|
||||
for (int32 i = 0; i < fTabList.CountItems(); i++) {
|
||||
Decorator::Tab* tab = fTabList.ItemAt(i);
|
||||
|
||||
tab->zoomRect.OffsetBy(offset);
|
||||
tab->closeRect.OffsetBy(offset);
|
||||
tab->minimizeRect.OffsetBy(offset);
|
||||
tab->tabRect.OffsetBy(offset);
|
||||
}
|
||||
fTitleBarRect.OffsetBy(offset);
|
||||
fFrame.OffsetBy(offset);
|
||||
fResizeRect.OffsetBy(offset);
|
||||
fBorderRect.OffsetBy(offset);
|
||||
|
||||
+93
-64
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku.
|
||||
* Copyright 2001-2011, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -27,6 +27,25 @@ class BRegion;
|
||||
|
||||
class Decorator {
|
||||
public:
|
||||
class Tab {
|
||||
public:
|
||||
Tab();
|
||||
virtual ~Tab() {}
|
||||
|
||||
BRect zoomRect;
|
||||
BRect closeRect;
|
||||
BRect minimizeRect;
|
||||
BRect tabRect;
|
||||
|
||||
bool closePressed : 1;
|
||||
bool zoomPressed : 1;
|
||||
bool minimizePressed : 1;
|
||||
|
||||
bool isFocused : 1;
|
||||
|
||||
BString title;
|
||||
};
|
||||
|
||||
enum Region {
|
||||
REGION_NONE,
|
||||
|
||||
@@ -61,6 +80,19 @@ public:
|
||||
window_look look, uint32 flags);
|
||||
virtual ~Decorator();
|
||||
|
||||
virtual Decorator::Tab* AddTab(const char* title, int32 index = -1,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual bool RemoveTab(int32 index,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual bool MoveTab(int32 from, int32 to, bool isMoving,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual int32 TabAt(const BPoint& where) const;
|
||||
Decorator::Tab* TabAt(int32 index)
|
||||
{ return fTabList.ItemAt(index); }
|
||||
int32 CountTabs() const
|
||||
{ return fTabList.CountItems(); }
|
||||
void SetTopTap(int32 tab);
|
||||
|
||||
void SetDrawingEngine(DrawingEngine *driver);
|
||||
inline DrawingEngine* GetDrawingEngine() const
|
||||
{ return fDrawingEngine; }
|
||||
@@ -72,52 +104,50 @@ public:
|
||||
void SetFlags(uint32 flags,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
void SetClose(bool pressed);
|
||||
void SetMinimize(bool pressed);
|
||||
void SetZoom(bool pressed);
|
||||
|
||||
void SetTitle(const char* string,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
window_look Look() const;
|
||||
uint32 Flags() const;
|
||||
|
||||
const char* Title() const;
|
||||
|
||||
BRect BorderRect() const;
|
||||
BRect TabRect() const;
|
||||
BRect TitleBarRect() const;
|
||||
BRect TabRect(int32 tab) const;
|
||||
BRect TabRect(Decorator::Tab* tab) const;
|
||||
|
||||
bool GetClose();
|
||||
bool GetMinimize();
|
||||
bool GetZoom();
|
||||
void SetClose(int32 tab, bool pressed);
|
||||
void SetMinimize(int32 tab, bool pressed);
|
||||
void SetZoom(int32 tab, bool pressed);
|
||||
|
||||
const char* Title(int32 tab) const;
|
||||
const char* Title(Decorator::Tab* tab) const;
|
||||
void SetTitle(int32 tab, const char* string,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
void SetFocus(int32 tab, bool focussed);
|
||||
bool IsFocus(int32 tab) const;
|
||||
bool IsFocus(Decorator::Tab* tab) const;
|
||||
|
||||
/*! \return true if tab location updated, false if out of bounds
|
||||
or unsupported */
|
||||
bool SetTabLocation(int32 tab, float location,
|
||||
bool isShifting, BRegion* updateRegion = NULL);
|
||||
virtual float TabLocation(int32 tab) const
|
||||
{ return 0.0; }
|
||||
|
||||
virtual Region RegionAt(BPoint where, int32& tab) const;
|
||||
|
||||
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const;
|
||||
|
||||
void SetFocus(bool focussed);
|
||||
bool IsFocus()
|
||||
{ return fIsFocused; };
|
||||
|
||||
const BRegion& GetFootprint();
|
||||
|
||||
virtual Region RegionAt(BPoint where) const;
|
||||
|
||||
void MoveBy(float x, float y);
|
||||
void MoveBy(BPoint offset);
|
||||
void ResizeBy(float x, float y, BRegion* dirty);
|
||||
void ResizeBy(BPoint offset, BRegion* dirty);
|
||||
|
||||
/*! \return true if tab location updated, false if out of bounds
|
||||
or unsupported
|
||||
*/
|
||||
bool SetTabLocation(float location,
|
||||
BRegion* /*updateRegion*/ = NULL);
|
||||
virtual float TabLocation() const
|
||||
{ return 0.0; }
|
||||
|
||||
virtual bool SetRegionHighlight(Region region, uint8 highlight,
|
||||
BRegion* dirty);
|
||||
inline uint8 RegionHighlight(Region region) const;
|
||||
BRegion* dirty, int32 tab = -1);
|
||||
inline uint8 RegionHighlight(Region region,
|
||||
int32 tab = -1) const;
|
||||
|
||||
bool SetSettings(const BMessage& settings,
|
||||
BRegion* updateRegion = NULL);
|
||||
@@ -125,30 +155,39 @@ public:
|
||||
|
||||
virtual void Draw(BRect rect);
|
||||
virtual void Draw();
|
||||
virtual void DrawClose();
|
||||
virtual void DrawClose(int32 tab);
|
||||
virtual void DrawMinimize(int32 tab);
|
||||
virtual void DrawTab(int32 tab);
|
||||
virtual void DrawTitle(int32 tab);
|
||||
virtual void DrawZoom(int32 tab);
|
||||
virtual void DrawFrame();
|
||||
virtual void DrawMinimize();
|
||||
virtual void DrawTab();
|
||||
virtual void DrawTitle();
|
||||
virtual void DrawZoom();
|
||||
|
||||
rgb_color UIColor(color_which which);
|
||||
|
||||
virtual void ExtendDirtyRegion(Region region, BRegion& dirty);
|
||||
|
||||
protected:
|
||||
int32 _TitleWidth() const
|
||||
{ return fTitle.CountChars(); }
|
||||
|
||||
virtual void _DoLayout();
|
||||
|
||||
virtual void _DrawFrame(BRect rect);
|
||||
virtual void _DrawTab(BRect rect);
|
||||
|
||||
virtual void _DrawClose(BRect rect);
|
||||
virtual void _DrawTitle(BRect rect);
|
||||
virtual void _DrawZoom(BRect rect);
|
||||
virtual void _DrawMinimize(BRect rect);
|
||||
virtual void _DrawTabs(BRect rect);
|
||||
virtual void _DrawTab(Decorator::Tab* tab, BRect rect);
|
||||
virtual void _DrawClose(Decorator::Tab* tab, BRect rect);
|
||||
virtual void _DrawTitle(Decorator::Tab* tab, BRect rect);
|
||||
virtual void _DrawZoom(Decorator::Tab* tab, BRect rect);
|
||||
virtual void _DrawMinimize(Decorator::Tab* tab, BRect rect);
|
||||
|
||||
virtual Decorator::Tab* _AllocateNewTab() = 0;
|
||||
|
||||
virtual void _SetTitle(Decorator::Tab* tab, const char* string,
|
||||
BRegion* updateRegion = NULL) = 0;
|
||||
int32 _TitleWidth(Decorator::Tab* tab) const
|
||||
{ return tab->title.CountChars(); }
|
||||
|
||||
virtual bool _SetTabLocation(Decorator::Tab* tab, float location,
|
||||
bool isShifting, BRegion* updateRegion = NULL);
|
||||
virtual void _SetFocus(Decorator::Tab* tab);
|
||||
|
||||
virtual void _FontsChanged(DesktopSettings& settings,
|
||||
BRegion* updateRegion = NULL);
|
||||
@@ -157,20 +196,19 @@ protected:
|
||||
virtual void _SetFlags(uint32 flags,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
virtual void _SetTitle(const char* string,
|
||||
BRegion* updateRegion = NULL) = 0;
|
||||
|
||||
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 bool _AddTab(int32 index = -1,
|
||||
BRegion* updateRegion = NULL) = 0;
|
||||
virtual bool _RemoveTab(int32 index,
|
||||
BRegion* updateRegion = NULL) = 0;
|
||||
virtual bool _MoveTab(int32 from, int32 to, bool isMoving,
|
||||
BRegion* updateRegion = NULL) = 0;
|
||||
|
||||
virtual void _GetFootprint(BRegion *region);
|
||||
void _InvalidateFootprint();
|
||||
|
||||
@@ -180,23 +218,14 @@ protected:
|
||||
window_look fLook;
|
||||
uint32 fFlags;
|
||||
|
||||
BRect fZoomRect;
|
||||
BRect fCloseRect;
|
||||
BRect fMinimizeRect;
|
||||
BRect fTabRect;
|
||||
BRect fTitleBarRect;
|
||||
BRect fFrame;
|
||||
BRect fResizeRect;
|
||||
BRect fBorderRect;
|
||||
|
||||
Decorator::Tab* fTopTab;
|
||||
BObjectList<Decorator::Tab> fTabList;
|
||||
private:
|
||||
bool fClosePressed : 1;
|
||||
bool fZoomPressed : 1;
|
||||
bool fMinimizePressed : 1;
|
||||
|
||||
bool fIsFocused : 1;
|
||||
|
||||
BString fTitle;
|
||||
|
||||
BRegion fFootprint;
|
||||
bool fFootprintValid : 1;
|
||||
|
||||
@@ -205,7 +234,7 @@ private:
|
||||
|
||||
|
||||
uint8
|
||||
Decorator::RegionHighlight(Region region) const
|
||||
Decorator::RegionHighlight(Region region, int32 tab) const
|
||||
{
|
||||
int32 index = (int32)region - 1;
|
||||
return index >= 0 && index < REGION_COUNT - 1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku, Inc.
|
||||
* Copyright 2001-2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -22,13 +22,33 @@ class ServerBitmap;
|
||||
|
||||
class DefaultDecorator: public Decorator {
|
||||
public:
|
||||
class Tab : public Decorator::Tab {
|
||||
public:
|
||||
Tab();
|
||||
|
||||
uint32 tabOffset;
|
||||
float tabLocation;
|
||||
float textOffset;
|
||||
|
||||
BString truncatedTitle;
|
||||
int32 truncatedTitleLength;
|
||||
|
||||
bool buttonFocus : 1;
|
||||
|
||||
bool isHighlighted : 1;
|
||||
ServerBitmap* closeBitmaps[4];
|
||||
ServerBitmap* zoomBitmaps[4];
|
||||
|
||||
float minTabSize;
|
||||
float maxTabSize;
|
||||
};
|
||||
|
||||
DefaultDecorator(DesktopSettings& settings,
|
||||
BRect frame, window_look look,
|
||||
uint32 flags);
|
||||
virtual ~DefaultDecorator();
|
||||
|
||||
virtual float TabLocation() const
|
||||
{ return (float)fTabOffset; }
|
||||
virtual float TabLocation(int32 tab) const;
|
||||
|
||||
virtual bool GetSettings(BMessage* settings) const;
|
||||
|
||||
@@ -38,10 +58,11 @@ public:
|
||||
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const;
|
||||
|
||||
virtual Region RegionAt(BPoint where) const;
|
||||
virtual Region RegionAt(BPoint where, int32& tab) const;
|
||||
|
||||
virtual bool SetRegionHighlight(Region region,
|
||||
uint8 highlight, BRegion* dirty);
|
||||
uint8 highlight, BRegion* dirty,
|
||||
int32 tab = -1);
|
||||
|
||||
virtual void ExtendDirtyRegion(Region region,
|
||||
BRegion& dirty);
|
||||
@@ -83,16 +104,22 @@ protected:
|
||||
|
||||
protected:
|
||||
virtual void _DoLayout();
|
||||
virtual void _DoTabLayout();
|
||||
void _DistributeTabSize(float delta);
|
||||
|
||||
virtual Decorator::Tab* _AllocateNewTab();
|
||||
DefaultDecorator::Tab* _TabAt(int32 index) const;
|
||||
|
||||
virtual void _DrawFrame(BRect r);
|
||||
virtual void _DrawTab(BRect r);
|
||||
virtual void _DrawTab(Decorator::Tab* tab, BRect r);
|
||||
|
||||
virtual void _DrawClose(BRect r);
|
||||
virtual void _DrawTitle(BRect r);
|
||||
virtual void _DrawZoom(BRect r);
|
||||
virtual void _DrawClose(Decorator::Tab* tab, BRect r);
|
||||
virtual void _DrawTitle(Decorator::Tab* tab, BRect r);
|
||||
virtual void _DrawZoom(Decorator::Tab* tab, BRect r);
|
||||
|
||||
virtual void _SetTitle(const char* string,
|
||||
virtual void _SetTitle(Decorator::Tab* tab, const char* string,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual void _SetFocus(Decorator::Tab* tab);
|
||||
|
||||
virtual void _FontsChanged(DesktopSettings& settings,
|
||||
BRegion* updateRegion);
|
||||
@@ -102,17 +129,23 @@ protected:
|
||||
virtual void _SetFlags(uint32 flags,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
virtual void _SetFocus();
|
||||
|
||||
virtual void _MoveBy(BPoint offset);
|
||||
virtual void _ResizeBy(BPoint offset, BRegion* dirty);
|
||||
|
||||
virtual bool _SetTabLocation(float location,
|
||||
virtual bool _SetTabLocation(Decorator::Tab* tab,
|
||||
float location, bool isShifting,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
virtual bool _SetSettings(const BMessage& settings,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
virtual bool _AddTab(int32 index = -1,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual bool _RemoveTab(int32 index,
|
||||
BRegion* updateRegion = NULL);
|
||||
virtual bool _MoveTab(int32 from, int32 to, bool isMoving,
|
||||
BRegion* updateRegion = NULL);
|
||||
|
||||
virtual void _GetFootprint(BRegion *region);
|
||||
|
||||
void _GetButtonSizeAndOffset(const BRect& tabRect,
|
||||
@@ -120,9 +153,11 @@ protected:
|
||||
float* inset) const;
|
||||
|
||||
// DefaultDecorator customization points
|
||||
virtual void DrawButtons(const BRect& invalid);
|
||||
virtual void DrawButtons(Decorator::Tab* tab,
|
||||
const BRect& invalid);
|
||||
virtual void GetComponentColors(Component component,
|
||||
uint8 highlight, ComponentColors _colors);
|
||||
uint8 highlight, ComponentColors _colors,
|
||||
Decorator::Tab* tab = NULL);
|
||||
|
||||
private:
|
||||
void _UpdateFont(DesktopSettings& settings);
|
||||
@@ -131,14 +166,20 @@ private:
|
||||
void _DrawBlendedRect(DrawingEngine *engine,
|
||||
BRect rect, bool down,
|
||||
const ComponentColors& colors);
|
||||
void _LayoutTabItems(const BRect& tabRect);
|
||||
void _LayoutTabItems(Decorator::Tab* tab,
|
||||
const BRect& tabRect);
|
||||
void _InvalidateBitmaps();
|
||||
ServerBitmap* _GetBitmapForButton(Component item, bool down,
|
||||
int32 width, int32 height);
|
||||
ServerBitmap* _GetBitmapForButton(Decorator::Tab* tab,
|
||||
Component item, bool down, int32 width,
|
||||
int32 height);
|
||||
|
||||
void _GetComponentColors(Component component,
|
||||
ComponentColors _colors);
|
||||
ComponentColors _colors,
|
||||
Decorator::Tab* tab = NULL);
|
||||
|
||||
inline float _DefaultTextOffset() const;
|
||||
|
||||
void _CalculateTabsRegion();
|
||||
protected:
|
||||
static const rgb_color kFrameColors[4];
|
||||
static const rgb_color kFocusFrameColors[2];
|
||||
@@ -156,10 +197,6 @@ protected:
|
||||
const rgb_color kNonFocusTabColorShadow;
|
||||
const rgb_color kNonFocusTextColor;
|
||||
|
||||
bool fButtonFocus;
|
||||
ServerBitmap* fCloseBitmaps[4];
|
||||
ServerBitmap* fZoomBitmaps[4];
|
||||
|
||||
// Individual rects for handling window frame
|
||||
// rendering the proper way
|
||||
BRect fRightBorder;
|
||||
@@ -169,14 +206,8 @@ protected:
|
||||
|
||||
int32 fBorderWidth;
|
||||
|
||||
uint32 fTabOffset;
|
||||
float fTabLocation;
|
||||
float fTextOffset;
|
||||
|
||||
float fMinTabSize;
|
||||
float fMaxTabSize;
|
||||
BString fTruncatedTitle;
|
||||
int32 fTruncatedTitleLength;
|
||||
BRegion fTabsRegion;
|
||||
BRect fOldMovingTab;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "ClickTarget.h"
|
||||
#include "Desktop.h"
|
||||
#include "DefaultDecorator.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "Window.h"
|
||||
|
||||
@@ -286,16 +287,58 @@ struct DefaultWindowBehaviour::SlideTabState : MouseTrackingState {
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~SlideTabState()
|
||||
{
|
||||
fDesktop->SetWindowTabLocation(fWindow, fWindow->TabLocation(), false);
|
||||
}
|
||||
|
||||
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
|
||||
{
|
||||
float loc = fWindow->TabLocation();
|
||||
float location = fWindow->TabLocation();
|
||||
// TODO: change to [0:1]
|
||||
loc += delta.x;
|
||||
if (fDesktop->SetWindowTabLocation(fWindow, loc))
|
||||
location += delta.x;
|
||||
AdjustMultiTabLocation(location, true);
|
||||
if (fDesktop->SetWindowTabLocation(fWindow, location, true))
|
||||
delta.y = 0;
|
||||
else
|
||||
delta = BPoint(0, 0);
|
||||
}
|
||||
|
||||
void AdjustMultiTabLocation(float location, bool isShifting)
|
||||
{
|
||||
::Decorator* decorator = fWindow->Decorator();
|
||||
if (decorator == NULL || decorator->CountTabs() <= 1)
|
||||
return;
|
||||
|
||||
// TODO does not work for none continuous shifts
|
||||
int32 windowIndex = fWindow->PositionInStack();
|
||||
DefaultDecorator::Tab* movingTab = static_cast<DefaultDecorator::Tab*>(
|
||||
decorator->TabAt(windowIndex));
|
||||
int32 neighbourIndex = windowIndex;
|
||||
if (movingTab->tabOffset > location)
|
||||
neighbourIndex--;
|
||||
else
|
||||
neighbourIndex++;
|
||||
|
||||
DefaultDecorator::Tab* neighbourTab
|
||||
= static_cast<DefaultDecorator::Tab*>(decorator->TabAt(
|
||||
neighbourIndex));
|
||||
if (neighbourTab == NULL)
|
||||
return;
|
||||
|
||||
if (movingTab->tabOffset > location) {
|
||||
if (location >
|
||||
neighbourTab->tabOffset + neighbourTab->tabRect.Width() / 2)
|
||||
return;
|
||||
} else {
|
||||
if (location + movingTab->tabRect.Width() <
|
||||
neighbourTab->tabOffset + neighbourTab->tabRect.Width() / 2)
|
||||
return;
|
||||
}
|
||||
|
||||
fWindow->MoveToStackPosition(neighbourIndex, isShifting);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -423,9 +466,10 @@ private:
|
||||
|
||||
struct DefaultWindowBehaviour::DecoratorButtonState : State {
|
||||
DecoratorButtonState(DefaultWindowBehaviour& behavior,
|
||||
Decorator::Region button)
|
||||
int32 tab, Decorator::Region button)
|
||||
:
|
||||
State(behavior),
|
||||
fTab(tab),
|
||||
fButton(button)
|
||||
{
|
||||
}
|
||||
@@ -452,22 +496,23 @@ struct DefaultWindowBehaviour::DecoratorButtonState : State {
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
int32 tab;
|
||||
switch (fButton) {
|
||||
case Decorator::REGION_CLOSE_BUTTON:
|
||||
decorator->SetClose(false);
|
||||
if (fBehavior._RegionFor(message) == fButton)
|
||||
decorator->SetClose(fTab, false);
|
||||
if (fBehavior._RegionFor(message, tab) == fButton)
|
||||
fWindow->ServerWindow()->NotifyQuitRequested();
|
||||
break;
|
||||
|
||||
case Decorator::REGION_ZOOM_BUTTON:
|
||||
decorator->SetZoom(false);
|
||||
if (fBehavior._RegionFor(message) == fButton)
|
||||
decorator->SetZoom(fTab, false);
|
||||
if (fBehavior._RegionFor(message, tab) == fButton)
|
||||
fWindow->ServerWindow()->NotifyZoom();
|
||||
break;
|
||||
|
||||
case Decorator::REGION_MINIMIZE_BUTTON:
|
||||
decorator->SetMinimize(false);
|
||||
if (fBehavior._RegionFor(message) == fButton)
|
||||
decorator->SetMinimize(fTab, false);
|
||||
if (fBehavior._RegionFor(message, tab) == fButton)
|
||||
fWindow->ServerWindow()->NotifyMinimize(true);
|
||||
break;
|
||||
|
||||
@@ -500,20 +545,21 @@ private:
|
||||
engine->LockParallelAccess();
|
||||
engine->ConstrainClippingRegion(visibleBorder);
|
||||
|
||||
int32 tab;
|
||||
Decorator::Region hitRegion = message != NULL
|
||||
? fBehavior._RegionFor(message) : fButton;
|
||||
? fBehavior._RegionFor(message, tab) : fButton;
|
||||
|
||||
switch (fButton) {
|
||||
case Decorator::REGION_CLOSE_BUTTON:
|
||||
decorator->SetClose(hitRegion == fButton);
|
||||
decorator->SetClose(fTab, hitRegion == fButton);
|
||||
break;
|
||||
|
||||
case Decorator::REGION_ZOOM_BUTTON:
|
||||
decorator->SetZoom(hitRegion == fButton);
|
||||
decorator->SetZoom(fTab, hitRegion == fButton);
|
||||
break;
|
||||
|
||||
case Decorator::REGION_MINIMIZE_BUTTON:
|
||||
decorator->SetMinimize(hitRegion == fButton);
|
||||
decorator->SetMinimize(fTab, hitRegion == fButton);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -526,6 +572,7 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
int32 fTab;
|
||||
Decorator::Region fButton;
|
||||
};
|
||||
|
||||
@@ -669,6 +716,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
Decorator* decorator = fWindow->Decorator();
|
||||
|
||||
Decorator::Region hitRegion = Decorator::REGION_NONE;
|
||||
int32 tab = -1;
|
||||
Action action = ACTION_NONE;
|
||||
|
||||
bool inBorderRegion = false;
|
||||
@@ -688,7 +736,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
hitRegion = Decorator::REGION_LEFT_BORDER;
|
||||
} else {
|
||||
// click on the decorator -- get the exact region
|
||||
hitRegion = _RegionFor(message);
|
||||
hitRegion = _RegionFor(message, tab);
|
||||
}
|
||||
|
||||
// translate the region into an action
|
||||
@@ -697,7 +745,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
|
||||
// left mouse button
|
||||
switch (hitRegion) {
|
||||
case Decorator::REGION_TAB:
|
||||
case Decorator::REGION_TAB: {
|
||||
// tab sliding in any case if either shift key is held down
|
||||
// except sliding up-down by moving mouse left-right would
|
||||
// look strange
|
||||
@@ -708,6 +756,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
}
|
||||
action = ACTION_DRAG;
|
||||
break;
|
||||
}
|
||||
|
||||
case Decorator::REGION_LEFT_BORDER:
|
||||
case Decorator::REGION_RIGHT_BORDER:
|
||||
@@ -809,7 +858,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
case ACTION_ZOOM:
|
||||
case ACTION_MINIMIZE:
|
||||
_NextState(
|
||||
new (std::nothrow) DecoratorButtonState(*this, hitRegion));
|
||||
new (std::nothrow) DecoratorButtonState(*this, tab, hitRegion));
|
||||
STRACE_CLICK(("===> ACTION_CLOSE/ZOOM/MINIMIZE\n"));
|
||||
break;
|
||||
|
||||
@@ -910,7 +959,7 @@ DefaultWindowBehaviour::_IsWindowModifier(int32 modifiers) const
|
||||
|
||||
|
||||
Decorator::Region
|
||||
DefaultWindowBehaviour::_RegionFor(const BMessage* message) const
|
||||
DefaultWindowBehaviour::_RegionFor(const BMessage* message, int32& tab) const
|
||||
{
|
||||
Decorator* decorator = fWindow->Decorator();
|
||||
if (decorator == NULL)
|
||||
@@ -920,7 +969,7 @@ DefaultWindowBehaviour::_RegionFor(const BMessage* message) const
|
||||
if (message->FindPoint("where", &where) != B_OK)
|
||||
return Decorator::REGION_NONE;
|
||||
|
||||
return decorator->RegionAt(where);
|
||||
return decorator->RegionAt(where, tab);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,8 @@ private:
|
||||
|
||||
private:
|
||||
bool _IsWindowModifier(int32 modifiers) const;
|
||||
Decorator::Region _RegionFor(const BMessage* message) const;
|
||||
Decorator::Region _RegionFor(const BMessage* message,
|
||||
int32& tab) const;
|
||||
|
||||
void _SetBorderHighlights(int8 horizontal,
|
||||
int8 vertical, bool active);
|
||||
|
||||
+16
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku.
|
||||
* Copyright 2001-2011, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -581,6 +581,7 @@ Desktop::BroadcastToAllWindows(int32 code)
|
||||
filter_result
|
||||
Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
if (LockAllWindows()) {
|
||||
Window* window = MouseEventWindow();
|
||||
if (window == NULL)
|
||||
@@ -591,13 +592,13 @@ Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers)
|
||||
window->ModifiersChanged(modifiers);
|
||||
}
|
||||
|
||||
if (NotifyKeyPressed(what, key, modifiers))
|
||||
result = B_SKIP_MESSAGE;
|
||||
|
||||
UnlockAllWindows();
|
||||
}
|
||||
|
||||
if (NotifyKeyPressed(what, key, modifiers))
|
||||
return B_SKIP_MESSAGE;
|
||||
|
||||
return B_DISPATCH_MESSAGE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1115,15 +1116,12 @@ Desktop::ActivateWindow(Window* window)
|
||||
}
|
||||
}
|
||||
|
||||
// we don't need to redraw what is currently
|
||||
// visible of the window
|
||||
BRegion clean(window->VisibleRegion());
|
||||
WindowList windows(kWorkingList);
|
||||
|
||||
Window* frontmost = window->Frontmost();
|
||||
|
||||
CurrentWindows().RemoveWindow(window);
|
||||
windows.AddWindow(window);
|
||||
window->MoveToTopStackLayer();
|
||||
|
||||
if (frontmost != NULL && frontmost->IsModal()) {
|
||||
// all modal windows follow their subsets to the front
|
||||
@@ -1335,6 +1333,10 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
|
||||
if (!LockAllWindows())
|
||||
return;
|
||||
|
||||
Window* topWindow = window->TopLayerStackWindow();
|
||||
if (topWindow)
|
||||
window = topWindow;
|
||||
|
||||
if (workspace == -1)
|
||||
workspace = fCurrentWorkspace;
|
||||
if (!window->IsVisible() || workspace != fCurrentWorkspace) {
|
||||
@@ -1472,16 +1474,16 @@ Desktop::ResizeWindowBy(Window* window, float x, float y)
|
||||
|
||||
|
||||
bool
|
||||
Desktop::SetWindowTabLocation(Window* window, float location)
|
||||
Desktop::SetWindowTabLocation(Window* window, float location, bool isShifting)
|
||||
{
|
||||
AutoWriteLocker _(fWindowLock);
|
||||
|
||||
BRegion dirty;
|
||||
bool changed = window->SetTabLocation(location, dirty);
|
||||
bool changed = window->SetTabLocation(location, isShifting, dirty);
|
||||
if (changed)
|
||||
RebuildAndRedrawAfterWindowChange(window, dirty);
|
||||
|
||||
NotifyWindowTabLocationChanged(window, location);
|
||||
NotifyWindowTabLocationChanged(window, location, isShifting);
|
||||
|
||||
return changed;
|
||||
}
|
||||
@@ -1763,7 +1765,7 @@ Desktop::WindowAt(BPoint where)
|
||||
for (Window* window = CurrentWindows().LastWindow(); window;
|
||||
window = window->PreviousWindow(fCurrentWorkspace)) {
|
||||
if (window->IsVisible() && window->VisibleRegion().Contains(where))
|
||||
return window;
|
||||
return window->StackedWindowAt(where);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -3177,6 +3179,7 @@ void
|
||||
Desktop::RebuildAndRedrawAfterWindowChange(Window* changedWindow,
|
||||
BRegion& dirty)
|
||||
{
|
||||
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
|
||||
if (!changedWindow->IsVisible() || dirty.CountRects() == 0)
|
||||
return;
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
void ResizeWindowBy(Window* window, float x,
|
||||
float y);
|
||||
bool SetWindowTabLocation(Window* window,
|
||||
float location);
|
||||
float location, bool isShifting);
|
||||
bool SetWindowDecoratorSettings(Window* window,
|
||||
const BMessage& settings);
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ DesktopObservable::NotifyWindowMinimized(Window* window, bool minimize)
|
||||
|
||||
void
|
||||
DesktopObservable::NotifyWindowTabLocationChanged(Window* window,
|
||||
float location)
|
||||
float location, bool isShifting)
|
||||
{
|
||||
if (fWeAreInvoking)
|
||||
return;
|
||||
@@ -252,7 +252,7 @@ DesktopObservable::NotifyWindowTabLocationChanged(Window* window,
|
||||
|
||||
for (DesktopListener* listener = fDesktopListenerList.First();
|
||||
listener != NULL; listener = fDesktopListenerList.GetNext(listener))
|
||||
listener->WindowTabLocationChanged(window, location);
|
||||
listener->WindowTabLocationChanged(window, location, isShifting);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
bool minimize) = 0;
|
||||
|
||||
virtual void WindowTabLocationChanged(Window* window,
|
||||
float location) = 0;
|
||||
float location, bool isShifting) = 0;
|
||||
virtual void SizeLimitsChanged(Window* window,
|
||||
int32 minWidth, int32 maxWidth,
|
||||
int32 minHeight, int32 maxHeight) = 0;
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
bool minimize);
|
||||
|
||||
void NotifyWindowTabLocationChanged(Window* window,
|
||||
float location);
|
||||
float location, bool isShifting);
|
||||
void NotifySizeLimitsChanged(Window* window,
|
||||
int32 minWidth, int32 maxWidth,
|
||||
int32 minHeight, int32 maxHeight);
|
||||
|
||||
+413
-81
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku, Inc.
|
||||
* Copyright 2001-2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
@@ -14,6 +14,17 @@
|
||||
|
||||
#include "Window.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <DirectWindow.h>
|
||||
#include <PortLink.h>
|
||||
#include <View.h>
|
||||
#include <ViewPrivate.h>
|
||||
#include <WindowPrivate.h>
|
||||
|
||||
#include "ClickTarget.h"
|
||||
#include "Decorator.h"
|
||||
#include "DecorManager.h"
|
||||
@@ -28,17 +39,6 @@
|
||||
#include "Workspace.h"
|
||||
#include "WorkspacesView.h"
|
||||
|
||||
#include <ViewPrivate.h>
|
||||
#include <WindowPrivate.h>
|
||||
|
||||
#include <Debug.h>
|
||||
#include <DirectWindow.h>
|
||||
#include <PortLink.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// Toggle debug output
|
||||
//#define DEBUG_WINDOW
|
||||
@@ -91,7 +91,6 @@ Window::Window(const BRect& frame, const char *name,
|
||||
fRegionPool(),
|
||||
|
||||
fWindowBehaviour(NULL),
|
||||
fDecorator(NULL),
|
||||
fTopView(NULL),
|
||||
fWindow(window),
|
||||
fDrawingEngine(drawingEngine),
|
||||
@@ -120,6 +119,8 @@ Window::Window(const BRect& frame, const char *name,
|
||||
|
||||
fWorkspacesViewCount(0)
|
||||
{
|
||||
_InitWindowStack();
|
||||
|
||||
// make sure our arguments are valid
|
||||
if (!IsValidLook(fLook))
|
||||
fLook = B_TITLED_WINDOW_LOOK;
|
||||
@@ -128,11 +129,12 @@ Window::Window(const BRect& frame, const char *name,
|
||||
|
||||
SetFlags(flags, NULL);
|
||||
|
||||
if (fLook != B_NO_BORDER_WINDOW_LOOK) {
|
||||
fDecorator = gDecorManager.AllocateDecorator(this);
|
||||
if (fDecorator) {
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
|
||||
&fMaxWidth, &fMaxHeight);
|
||||
if (fLook != B_NO_BORDER_WINDOW_LOOK && fCurrentStack.Get() != NULL) {
|
||||
// allocates a decorator
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator != NULL) {
|
||||
decorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||
&fMaxHeight);
|
||||
}
|
||||
}
|
||||
fWindowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
|
||||
@@ -169,8 +171,9 @@ Window::~Window()
|
||||
delete fTopView;
|
||||
}
|
||||
|
||||
DetachFromWindowStack(false);
|
||||
|
||||
delete fWindowBehaviour;
|
||||
delete fDecorator;
|
||||
delete fDrawingEngine;
|
||||
|
||||
gDecorManager.CleanupForWindow(this);
|
||||
@@ -220,8 +223,9 @@ Window::GetBorderRegion(BRegion* region)
|
||||
// TODO: if someone needs to call this from
|
||||
// the outside, the clipping needs to be readlocked!
|
||||
|
||||
if (fDecorator)
|
||||
*region = fDecorator->GetFootprint();
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator)
|
||||
*region = decorator->GetFootprint();
|
||||
else
|
||||
region->MakeEmpty();
|
||||
}
|
||||
@@ -272,7 +276,7 @@ Window::_PropagatePosition()
|
||||
|
||||
|
||||
void
|
||||
Window::MoveBy(int32 x, int32 y)
|
||||
Window::MoveBy(int32 x, int32 y, bool moveStack)
|
||||
{
|
||||
// this function is only called from the desktop thread
|
||||
|
||||
@@ -296,14 +300,27 @@ Window::MoveBy(int32 x, int32 y)
|
||||
|
||||
fEffectiveDrawingRegionValid = false;
|
||||
|
||||
if (fDecorator)
|
||||
fDecorator->MoveBy(x, y);
|
||||
|
||||
if (fTopView != NULL) {
|
||||
fTopView->MoveBy(x, y, NULL);
|
||||
fTopView->UpdateOverlay();
|
||||
}
|
||||
|
||||
::Decorator* decorator = Decorator();
|
||||
if (moveStack && decorator)
|
||||
decorator->MoveBy(x, y);
|
||||
|
||||
WindowStack* stack = GetWindowStack();
|
||||
if (moveStack && stack) {
|
||||
for (int32 i = 0; i < stack->CountWindows(); i++) {
|
||||
Window* window = stack->WindowList().ItemAt(i);
|
||||
if (window == this)
|
||||
continue;
|
||||
window->MoveBy(x, y, false);
|
||||
|
||||
//fDesktop->RebuildAndRedrawAfterWindowChange(window, dirty);
|
||||
}
|
||||
}
|
||||
|
||||
// the desktop will take care of dirty regions
|
||||
|
||||
// dispatch a message to the client informing about the changed size
|
||||
@@ -315,7 +332,7 @@ Window::MoveBy(int32 x, int32 y)
|
||||
|
||||
|
||||
void
|
||||
Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion, bool resizeStack)
|
||||
{
|
||||
// this function is only called from the desktop thread
|
||||
|
||||
@@ -345,19 +362,29 @@ Window::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
fContentRegionValid = false;
|
||||
fEffectiveDrawingRegionValid = false;
|
||||
|
||||
if (fDecorator) {
|
||||
fDecorator->ResizeBy(x, y, dirtyRegion);
|
||||
if (fTopView != NULL) {
|
||||
fTopView->ResizeBy(x, y, dirtyRegion);
|
||||
fTopView->UpdateOverlay();
|
||||
}
|
||||
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator && resizeStack) {
|
||||
decorator->ResizeBy(x, y, dirtyRegion);
|
||||
//if (dirtyRegion) {
|
||||
//fDrawingEngine->FillRegion(*dirtyRegion, (rgb_color){ 255, 255, 0, 255 });
|
||||
//snooze(40000);
|
||||
//}
|
||||
}
|
||||
|
||||
if (fTopView != NULL) {
|
||||
fTopView->ResizeBy(x, y, dirtyRegion);
|
||||
fTopView->UpdateOverlay();
|
||||
WindowStack* stack = GetWindowStack();
|
||||
if (resizeStack && stack) {
|
||||
for (int32 i = 0; i < stack->CountWindows(); i++) {
|
||||
Window* window = stack->WindowList().ItemAt(i);
|
||||
if (window == this)
|
||||
continue;
|
||||
window->ResizeBy(x, y, dirtyRegion, false);
|
||||
}
|
||||
}
|
||||
|
||||
//if (dirtyRegion)
|
||||
//fDrawingEngine->FillRegion(*dirtyRegion, (rgb_color){ 0, 255, 255, 255 });
|
||||
|
||||
@@ -543,20 +570,32 @@ Window::PreviousWindow(int32 index) const
|
||||
}
|
||||
|
||||
|
||||
::Decorator*
|
||||
Window::Decorator() const
|
||||
{
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return NULL;
|
||||
return fCurrentStack->Decorator();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::ReloadDecor()
|
||||
{
|
||||
::Decorator* decorator = NULL;
|
||||
WindowBehaviour* windowBehaviour = NULL;
|
||||
|
||||
WindowStack* stack = GetWindowStack();
|
||||
if (stack == NULL)
|
||||
return false;
|
||||
|
||||
if (fLook != B_NO_BORDER_WINDOW_LOOK) {
|
||||
// we need a new decorator
|
||||
decorator = gDecorManager.AllocateDecorator(this);
|
||||
if (decorator == NULL)
|
||||
return false;
|
||||
int32 index = PositionInStack();
|
||||
if (IsFocus())
|
||||
decorator->SetFocus(true);
|
||||
decorator->SetFocus(index, true);
|
||||
}
|
||||
|
||||
windowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
|
||||
@@ -565,8 +604,7 @@ Window::ReloadDecor()
|
||||
return false;
|
||||
}
|
||||
|
||||
delete fDecorator;
|
||||
fDecorator = decorator;
|
||||
stack->SetDecorator(decorator);
|
||||
|
||||
delete fWindowBehaviour;
|
||||
fWindowBehaviour = windowBehaviour;
|
||||
@@ -578,7 +616,8 @@ Window::ReloadDecor()
|
||||
void
|
||||
Window::SetScreen(const ::Screen* screen)
|
||||
{
|
||||
ASSERT_MULTI_WRITE_LOCKED(fDesktop->ScreenLocker());
|
||||
// TODO this assert fails in Desktop::ShowWindow
|
||||
//ASSERT_MULTI_WRITE_LOCKED(fDesktop->ScreenLocker());
|
||||
fScreen = screen;
|
||||
}
|
||||
|
||||
@@ -586,7 +625,8 @@ Window::SetScreen(const ::Screen* screen)
|
||||
const ::Screen*
|
||||
Window::Screen() const
|
||||
{
|
||||
ASSERT_MULTI_READ_LOCKED(fDesktop->ScreenLocker());
|
||||
// TODO this assert also fails
|
||||
//ASSERT_MULTI_READ_LOCKED(fDesktop->ScreenLocker());
|
||||
return fScreen;
|
||||
}
|
||||
|
||||
@@ -640,7 +680,7 @@ Window::DrawingRegionChanged(View* view) const
|
||||
void
|
||||
Window::ProcessDirtyRegion(BRegion& region)
|
||||
{
|
||||
// if this is exectuted in the desktop thread,
|
||||
// if this is executed in the desktop thread,
|
||||
// it means that the window thread currently
|
||||
// blocks to get the read lock, if it is
|
||||
// executed from the window thread, it should
|
||||
@@ -669,8 +709,13 @@ Window::ProcessDirtyRegion(BRegion& region)
|
||||
void
|
||||
Window::RedrawDirtyRegion()
|
||||
{
|
||||
// executed from ServerWindow with the read lock held
|
||||
if (TopLayerStackWindow() != this) {
|
||||
fDirtyRegion.MakeEmpty();
|
||||
fDirtyCause = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// executed from ServerWindow with the read lock held
|
||||
if (IsVisible()) {
|
||||
_DrawBorder();
|
||||
|
||||
@@ -961,22 +1006,27 @@ Window::SetTitle(const char* name, BRegion& dirty)
|
||||
|
||||
fTitle = name;
|
||||
|
||||
if (fDecorator)
|
||||
fDecorator->SetTitle(name, &dirty);
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator) {
|
||||
int32 index = PositionInStack();
|
||||
decorator->SetTitle(index, name, &dirty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Window::SetFocus(bool focus)
|
||||
{
|
||||
::Decorator* decorator = Decorator();
|
||||
|
||||
// executed from Desktop thread
|
||||
// it holds the clipping write lock,
|
||||
// so the window thread cannot be
|
||||
// accessing fIsFocus
|
||||
|
||||
BRegion* dirty = NULL;
|
||||
if (fDecorator)
|
||||
dirty = fRegionPool.GetRegion(fDecorator->GetFootprint());
|
||||
if (decorator)
|
||||
dirty = fRegionPool.GetRegion(decorator->GetFootprint());
|
||||
if (dirty) {
|
||||
dirty->IntersectWith(&fVisibleRegion);
|
||||
fDesktop->MarkDirty(*dirty);
|
||||
@@ -984,8 +1034,10 @@ Window::SetFocus(bool focus)
|
||||
}
|
||||
|
||||
fIsFocus = focus;
|
||||
if (fDecorator)
|
||||
fDecorator->SetFocus(focus);
|
||||
if (decorator) {
|
||||
int32 index = PositionInStack();
|
||||
decorator->SetFocus(index, focus);
|
||||
}
|
||||
|
||||
Activated(focus);
|
||||
}
|
||||
@@ -1066,8 +1118,9 @@ Window::SetSizeLimits(int32 minWidth, int32 maxWidth, int32 minHeight,
|
||||
fMaxHeight = maxHeight;
|
||||
|
||||
// give the Decorator a say in this too
|
||||
if (fDecorator) {
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator) {
|
||||
decorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||
&fMaxHeight);
|
||||
}
|
||||
|
||||
@@ -1087,10 +1140,13 @@ Window::GetSizeLimits(int32* minWidth, int32* maxWidth,
|
||||
|
||||
|
||||
bool
|
||||
Window::SetTabLocation(float location, BRegion& dirty)
|
||||
Window::SetTabLocation(float location, bool isShifting, BRegion& dirty)
|
||||
{
|
||||
if (fDecorator)
|
||||
return fDecorator->SetTabLocation(location, &dirty);
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator) {
|
||||
int32 index = PositionInStack();
|
||||
return decorator->SetTabLocation(index, location, isShifting, &dirty);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1099,8 +1155,11 @@ Window::SetTabLocation(float location, BRegion& dirty)
|
||||
float
|
||||
Window::TabLocation() const
|
||||
{
|
||||
if (fDecorator)
|
||||
return fDecorator->TabLocation();
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator) {
|
||||
int32 index = PositionInStack();
|
||||
return decorator->TabLocation(index);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -1116,8 +1175,10 @@ Window::SetDecoratorSettings(const BMessage& settings, BRegion& dirty)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fDecorator)
|
||||
return fDecorator->SetSettings(settings, &dirty);
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator)
|
||||
return decorator->SetSettings(settings, &dirty);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1128,8 +1189,9 @@ Window::GetDecoratorSettings(BMessage* settings)
|
||||
if (fDesktop)
|
||||
fDesktop->GetDecoratorSettings(this, *settings);
|
||||
|
||||
if (fDecorator)
|
||||
return fDecorator->GetSettings(settings);
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator)
|
||||
return decorator->GetSettings(settings);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1138,9 +1200,10 @@ Window::GetDecoratorSettings(BMessage* settings)
|
||||
void
|
||||
Window::FontsChanged(BRegion* updateRegion)
|
||||
{
|
||||
if (fDecorator != NULL) {
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator != NULL) {
|
||||
DesktopSettings settings(fDesktop);
|
||||
fDecorator->FontsChanged(settings, updateRegion);
|
||||
decorator->FontsChanged(settings, updateRegion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,11 +1211,14 @@ Window::FontsChanged(BRegion* updateRegion)
|
||||
void
|
||||
Window::SetLook(window_look look, BRegion* updateRegion)
|
||||
{
|
||||
if (fDecorator == NULL && look != B_NO_BORDER_WINDOW_LOOK) {
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator == NULL && look != B_NO_BORDER_WINDOW_LOOK) {
|
||||
// we need a new decorator
|
||||
fDecorator = gDecorManager.AllocateDecorator(this);
|
||||
if (IsFocus())
|
||||
fDecorator->SetFocus(true);
|
||||
decorator = gDecorManager.AllocateDecorator(this);
|
||||
if (IsFocus()) {
|
||||
int32 index = PositionInStack();
|
||||
decorator->SetFocus(index, true);
|
||||
}
|
||||
}
|
||||
|
||||
fLook = look;
|
||||
@@ -1163,20 +1229,19 @@ Window::SetLook(window_look look, BRegion* updateRegion)
|
||||
// ...and therefor the drawing region is
|
||||
// likely not valid anymore either
|
||||
|
||||
if (fDecorator != NULL) {
|
||||
if (decorator != NULL) {
|
||||
DesktopSettings settings(fDesktop);
|
||||
fDecorator->SetLook(settings, look, updateRegion);
|
||||
decorator->SetLook(settings, look, updateRegion);
|
||||
|
||||
// we might need to resize the window!
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||
decorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||
&fMaxHeight);
|
||||
_ObeySizeLimits();
|
||||
}
|
||||
|
||||
if (look == B_NO_BORDER_WINDOW_LOOK) {
|
||||
if (look == B_NO_BORDER_WINDOW_LOOK && fCurrentStack.Get() != NULL) {
|
||||
// we don't need a decorator for this window
|
||||
delete fDecorator;
|
||||
fDecorator = NULL;
|
||||
fCurrentStack->SetDecorator(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1216,16 +1281,15 @@ Window::SetFlags(uint32 flags, BRegion* updateRegion)
|
||||
if ((fFlags & B_SAME_POSITION_IN_ALL_WORKSPACES) != 0)
|
||||
_PropagatePosition();
|
||||
|
||||
if (fDecorator == NULL)
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator == NULL)
|
||||
return;
|
||||
|
||||
fDecorator->SetFlags(flags, updateRegion);
|
||||
decorator->SetFlags(flags, updateRegion);
|
||||
|
||||
// we might need to resize the window!
|
||||
if (fDecorator) {
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
||||
_ObeySizeLimits();
|
||||
}
|
||||
decorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
||||
_ObeySizeLimits();
|
||||
|
||||
// TODO: not sure if we want to do this
|
||||
#if 0
|
||||
@@ -1672,8 +1736,8 @@ Window::_DrawBorder()
|
||||
// this is executed in the window thread, but only
|
||||
// in respond to a REDRAW message having been received, the
|
||||
// clipping lock is held for reading
|
||||
|
||||
if (!fDecorator)
|
||||
::Decorator* decorator = Decorator();
|
||||
if (!decorator)
|
||||
return;
|
||||
|
||||
// construct the region of the border that needs redrawing
|
||||
@@ -1686,13 +1750,13 @@ Window::_DrawBorder()
|
||||
// intersect with the dirty region
|
||||
dirtyBorderRegion->IntersectWith(&fDirtyRegion);
|
||||
|
||||
DrawingEngine* engine = fDecorator->GetDrawingEngine();
|
||||
DrawingEngine* engine = decorator->GetDrawingEngine();
|
||||
if (dirtyBorderRegion->CountRects() > 0 && engine->LockParallelAccess()) {
|
||||
engine->ConstrainClippingRegion(dirtyBorderRegion);
|
||||
bool copyToFrontEnabled = engine->CopyToFrontEnabled();
|
||||
engine->SetCopyToFrontEnabled(true);
|
||||
|
||||
fDecorator->Draw(dirtyBorderRegion->Frame());
|
||||
decorator->Draw(dirtyBorderRegion->Frame());
|
||||
|
||||
engine->SetCopyToFrontEnabled(copyToFrontEnabled);
|
||||
|
||||
@@ -1887,8 +1951,9 @@ Window::_UpdateContentRegion()
|
||||
fContentRegion.Set(fFrame);
|
||||
|
||||
// resize handle
|
||||
if (fDecorator)
|
||||
fContentRegion.Exclude(&fDecorator->GetFootprint());
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator)
|
||||
fContentRegion.Exclude(&decorator->GetFootprint());
|
||||
|
||||
fContentRegionValid = true;
|
||||
}
|
||||
@@ -1991,3 +2056,270 @@ Window::UpdateSession::AddCause(uint8 cause)
|
||||
{
|
||||
fCause |= cause;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Window::PositionInStack() const
|
||||
{
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return -1;
|
||||
return fCurrentStack->WindowList().IndexOf(this);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::DetachFromWindowStack(bool ownStackNeeded)
|
||||
{
|
||||
// The lock must normally be held but is not held when closing the window.
|
||||
//ASSERT_MULTI_WRITE_LOCKED(fDesktop->WindowLocker());
|
||||
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return false;
|
||||
if (fCurrentStack->CountWindows() == 1)
|
||||
return true;
|
||||
|
||||
int32 index = PositionInStack();
|
||||
|
||||
if (fCurrentStack->RemoveWindow(this) == false)
|
||||
return false;
|
||||
|
||||
BRegion dirty;
|
||||
::Decorator* decorator = fCurrentStack->Decorator();
|
||||
if (decorator != NULL)
|
||||
decorator->RemoveTab(index, &dirty);
|
||||
|
||||
Window* remainingTop = fCurrentStack->TopLayerWindow();
|
||||
if (remainingTop != NULL) {
|
||||
decorator->SetDrawingEngine(remainingTop->fDrawingEngine);
|
||||
// propagate focus to the decorator
|
||||
remainingTop->SetFocus(remainingTop->IsFocus());
|
||||
}
|
||||
|
||||
fCurrentStack = NULL;
|
||||
if (ownStackNeeded == true)
|
||||
_InitWindowStack();
|
||||
// propagate focus to the new decorator
|
||||
SetFocus(IsFocus());
|
||||
|
||||
fDesktop->RebuildAndRedrawAfterWindowChange(this, dirty);
|
||||
if (remainingTop != NULL)
|
||||
fDesktop->MarkDirty(remainingTop->VisibleRegion());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::AddWindowToStack(Window* window)
|
||||
{
|
||||
ASSERT_MULTI_WRITE_LOCKED(fDesktop->WindowLocker());
|
||||
|
||||
WindowStack* stack = GetWindowStack();
|
||||
if (stack == NULL)
|
||||
return false;
|
||||
|
||||
// first collect dirt from the window to add
|
||||
BRegion dirty;
|
||||
::Decorator* otherDecorator = window->Decorator();
|
||||
if (otherDecorator != NULL)
|
||||
dirty.Include(otherDecorator->TitleBarRect());
|
||||
::Decorator* decorator = stack->Decorator();
|
||||
if (decorator != NULL)
|
||||
dirty.Include(decorator->TitleBarRect());
|
||||
|
||||
int32 position = PositionInStack() + 1;
|
||||
if (position >= stack->CountWindows())
|
||||
position = -1;
|
||||
if (stack->AddWindow(window, position) == false)
|
||||
return false;
|
||||
window->DetachFromWindowStack(false);
|
||||
window->fCurrentStack.SetTo(stack);
|
||||
|
||||
if (decorator != NULL)
|
||||
decorator->AddTab(window->Title(), position, &dirty);
|
||||
|
||||
fDesktop->RebuildAndRedrawAfterWindowChange(TopLayerStackWindow(), dirty);
|
||||
window->SetFocus(window->IsFocus());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Window*
|
||||
Window::StackedWindowAt(const BPoint& where)
|
||||
{
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator == NULL)
|
||||
return NULL;
|
||||
|
||||
int tab = decorator->TabAt(where);
|
||||
// if we have a decorator we also have a stack
|
||||
Window* window = fCurrentStack->WindowAt(tab);
|
||||
if (window != NULL)
|
||||
return window;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Window*
|
||||
Window::TopLayerStackWindow()
|
||||
{
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return this;
|
||||
return fCurrentStack->TopLayerWindow();
|
||||
}
|
||||
|
||||
|
||||
WindowStack*
|
||||
Window::GetWindowStack()
|
||||
{
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return _InitWindowStack();
|
||||
return fCurrentStack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Window::MoveToTopStackLayer()
|
||||
{
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator == NULL)
|
||||
return false;
|
||||
decorator->SetDrawingEngine(fDrawingEngine);
|
||||
decorator->SetTopTap(PositionInStack());
|
||||
return fCurrentStack->MoveToTopLayer(this);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Window::MoveToStackPosition(int32 to, bool isMoving)
|
||||
{
|
||||
if (fCurrentStack.Get() == NULL)
|
||||
return false;
|
||||
int32 index = PositionInStack();
|
||||
if (fCurrentStack->Move(index, to) == false)
|
||||
return false;
|
||||
|
||||
BRegion dirty;
|
||||
::Decorator* decorator = Decorator();
|
||||
if (decorator && decorator->MoveTab(index, to, isMoving, &dirty) == false)
|
||||
return false;
|
||||
|
||||
fDesktop->RebuildAndRedrawAfterWindowChange(this, dirty);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
WindowStack*
|
||||
Window::_InitWindowStack()
|
||||
{
|
||||
fCurrentStack = NULL;
|
||||
::Decorator* decorator = NULL;
|
||||
if (fLook != B_NO_BORDER_WINDOW_LOOK)
|
||||
decorator = gDecorManager.AllocateDecorator(this);
|
||||
|
||||
WindowStack* stack = new(std::nothrow) WindowStack(decorator);
|
||||
if (stack == NULL)
|
||||
return NULL;
|
||||
|
||||
if (stack->AddWindow(this) != true) {
|
||||
delete stack;
|
||||
return NULL;
|
||||
}
|
||||
fCurrentStack.SetTo(stack, true);
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
||||
WindowStack::WindowStack(::Decorator* decorator)
|
||||
:
|
||||
fDecorator(decorator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
WindowStack::~WindowStack()
|
||||
{
|
||||
delete fDecorator;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WindowStack::SetDecorator(::Decorator* decorator)
|
||||
{
|
||||
delete fDecorator;
|
||||
fDecorator = decorator;
|
||||
}
|
||||
|
||||
|
||||
::Decorator*
|
||||
WindowStack::Decorator()
|
||||
{
|
||||
return fDecorator;
|
||||
}
|
||||
|
||||
|
||||
Window*
|
||||
WindowStack::TopLayerWindow() const
|
||||
{
|
||||
return fWindowLayerOrder.ItemAt(fWindowLayerOrder.CountItems() - 1);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
WindowStack::CountWindows()
|
||||
{
|
||||
return fWindowList.CountItems();
|
||||
}
|
||||
|
||||
|
||||
Window*
|
||||
WindowStack::WindowAt(int32 index)
|
||||
{
|
||||
return fWindowList.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowStack::AddWindow(Window* window, int32 position)
|
||||
{
|
||||
if (position >= 0) {
|
||||
if (fWindowList.AddItem(window, position) == false)
|
||||
return false;
|
||||
} else if (fWindowList.AddItem(window) == false)
|
||||
return false;
|
||||
|
||||
if (fWindowLayerOrder.AddItem(window) == false) {
|
||||
fWindowList.RemoveItem(window);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowStack::RemoveWindow(Window* window)
|
||||
{
|
||||
if (fWindowList.RemoveItem(window) == false)
|
||||
return false;
|
||||
|
||||
fWindowLayerOrder.RemoveItem(window);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowStack::MoveToTopLayer(Window* window)
|
||||
{
|
||||
int32 index = fWindowLayerOrder.IndexOf(window);
|
||||
return fWindowLayerOrder.MoveItem(index,
|
||||
fWindowLayerOrder.CountItems() - 1);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowStack::Move(int32 from, int32 to)
|
||||
{
|
||||
return fWindowList.MoveItem(from, to);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku, Inc.
|
||||
* Copyright 2001-2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
@@ -20,9 +20,46 @@
|
||||
#include "WindowList.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class Window;
|
||||
|
||||
|
||||
typedef BObjectList<Window> StackWindows;
|
||||
|
||||
|
||||
class WindowStack : public BReferenceable {
|
||||
public:
|
||||
WindowStack(::Decorator* decorator);
|
||||
~WindowStack();
|
||||
|
||||
void SetDecorator(::Decorator* decorator);
|
||||
::Decorator* Decorator();
|
||||
|
||||
const StackWindows& WindowList() const { return fWindowList; }
|
||||
const StackWindows& LayerOrder() const { return fWindowLayerOrder; }
|
||||
|
||||
Window* TopLayerWindow() const;
|
||||
|
||||
int32 CountWindows();
|
||||
Window* WindowAt(int32 index);
|
||||
bool AddWindow(Window* window,
|
||||
int32 position = -1);
|
||||
bool RemoveWindow(Window* window);
|
||||
|
||||
bool MoveToTopLayer(Window* window);
|
||||
bool Move(int32 from, int32 to);
|
||||
private:
|
||||
::Decorator* fDecorator;
|
||||
|
||||
StackWindows fWindowList;
|
||||
StackWindows fWindowLayerOrder;
|
||||
};
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
class PortLink;
|
||||
};
|
||||
@@ -65,7 +102,7 @@ public:
|
||||
Window* PreviousWindow(int32 index) const;
|
||||
|
||||
::Desktop* Desktop() const { return fDesktop; }
|
||||
::Decorator* Decorator() const { return fDecorator; }
|
||||
::Decorator* Decorator() const;
|
||||
::ServerWindow* ServerWindow() const { return fWindow; }
|
||||
::EventTarget& EventTarget() const
|
||||
{ return fWindow->EventTarget(); }
|
||||
@@ -88,9 +125,10 @@ public:
|
||||
void GetBorderRegion(BRegion* region);
|
||||
void GetContentRegion(BRegion* region);
|
||||
|
||||
void MoveBy(int32 x, int32 y);
|
||||
void MoveBy(int32 x, int32 y, bool moveStack = true);
|
||||
void ResizeBy(int32 x, int32 y,
|
||||
BRegion* dirtyRegion);
|
||||
BRegion* dirtyRegion,
|
||||
bool resizeStack = true);
|
||||
|
||||
void ScrollViewBy(View* view, int32 dx, int32 dy);
|
||||
|
||||
@@ -191,7 +229,8 @@ public:
|
||||
int32* minHeight, int32* maxHeight) const;
|
||||
|
||||
// 0.0 -> left .... 1.0 -> right
|
||||
bool SetTabLocation(float location, BRegion& dirty);
|
||||
bool SetTabLocation(float location, bool isShifting,
|
||||
BRegion& dirty);
|
||||
float TabLocation() const;
|
||||
|
||||
bool SetDecoratorSettings(const BMessage& settings,
|
||||
@@ -254,6 +293,19 @@ public:
|
||||
static uint32 ValidWindowFlags();
|
||||
static uint32 ValidWindowFlags(window_feel feel);
|
||||
|
||||
// Window stack methods.
|
||||
WindowStack* GetWindowStack();
|
||||
|
||||
bool DetachFromWindowStack(
|
||||
bool ownStackNeeded = true);
|
||||
bool AddWindowToStack(Window* window);
|
||||
Window* StackedWindowAt(const BPoint& where);
|
||||
Window* TopLayerStackWindow();
|
||||
|
||||
int32 PositionInStack() const;
|
||||
bool MoveToTopStackLayer();
|
||||
bool MoveToStackPosition(int32 index,
|
||||
bool isMoving);
|
||||
protected:
|
||||
void _ShiftPartOfRegion(BRegion* region,
|
||||
BRegion* regionToShift, int32 xOffset,
|
||||
@@ -307,7 +359,6 @@ protected:
|
||||
BObjectList<Window> fSubsets;
|
||||
|
||||
WindowBehaviour* fWindowBehaviour;
|
||||
::Decorator* fDecorator;
|
||||
View* fTopView;
|
||||
::ServerWindow* fWindow;
|
||||
DrawingEngine* fDrawingEngine;
|
||||
@@ -377,6 +428,12 @@ protected:
|
||||
int32 fWorkspacesViewCount;
|
||||
|
||||
friend class DecorManager;
|
||||
|
||||
private:
|
||||
WindowStack* _InitWindowStack();
|
||||
|
||||
BReference<WindowStack> fCurrentStack;
|
||||
};
|
||||
|
||||
|
||||
#endif // WINDOW_H
|
||||
|
||||
@@ -177,7 +177,7 @@ WorkspacesView::_DrawWindow(DrawingEngine* drawingEngine,
|
||||
Decorator *decorator = window->Decorator();
|
||||
BRect tabFrame(0, 0, 0, 0);
|
||||
if (decorator != NULL)
|
||||
tabFrame = decorator->TabRect();
|
||||
tabFrame = decorator->TitleBarRect();
|
||||
|
||||
tabFrame = _WindowFrame(workspaceFrame, screenFrame,
|
||||
tabFrame, tabFrame.LeftTop() - offset);
|
||||
|
||||
Reference in New Issue
Block a user