Move Tab code into Decorator and refactor

This commit is contained in:
John Scipione
2014-02-20 19:31:40 -05:00
parent 699dd3e776
commit cfe0652a5e
6 changed files with 576 additions and 680 deletions
+233 -133
View File
@@ -25,6 +25,8 @@
Decorator::Tab::Tab() Decorator::Tab::Tab()
: :
tabRect(),
zoomRect(), zoomRect(),
closeRect(), closeRect(),
minimizeRect(), minimizeRect(),
@@ -36,9 +38,25 @@ Decorator::Tab::Tab()
look(B_TITLED_WINDOW_LOOK), look(B_TITLED_WINDOW_LOOK),
flags(0), flags(0),
isFocused(false), isFocused(false),
title("") title(""),
{
tabOffset(0),
tabLocation(0.0f),
textOffset(10.0f),
truncatedTitle(""),
truncatedTitleLength(0),
buttonFocus(false),
isHighlighted(false),
minTabSize(0.0f),
maxTabSize(0.0f)
{
closeBitmaps[0] = closeBitmaps[1] = closeBitmaps[2] = closeBitmaps[3]
= minimizeBitmaps[0] = minimizeBitmaps[1] = minimizeBitmaps[2]
= minimizeBitmaps[3] = zoomBitmaps[0] = zoomBitmaps[1] = zoomBitmaps[2]
= zoomBitmaps[3] = NULL;
} }
@@ -48,18 +66,25 @@ Decorator::Tab::Tab()
object. object.
\param settings DesktopSettings pointer. \param settings DesktopSettings pointer.
\param rect Size of client area. \param frame Decorator frame rectangle
*/ */
Decorator::Decorator(DesktopSettings& settings, BRect rect) Decorator::Decorator(DesktopSettings& settings, BRect frame)
: :
fDrawingEngine(NULL), fDrawingEngine(NULL),
fDrawState(), fDrawState(),
fTitleBarRect(), fTitleBarRect(),
fFrame(rect), fFrame(frame),
fResizeRect(), fResizeRect(),
fBorderRect(), fBorderRect(),
fLeftBorder(),
fTopBorder(),
fBottomBorder(),
fRightBorder(),
fBorderWidth(-1),
fTopTab(NULL), fTopTab(NULL),
fFootprintValid(false) fFootprintValid(false)
@@ -172,7 +197,7 @@ Decorator::SetDrawingEngine(DrawingEngine* engine)
fDrawingEngine = engine; fDrawingEngine = engine;
// lots of subclasses will depend on the driver for text support, so call // lots of subclasses will depend on the driver for text support, so call
// _DoLayout() after we have it // _DoLayout() after we have it
if (fDrawingEngine) if (fDrawingEngine != NULL)
_DoLayout(); _DoLayout();
} }
@@ -390,6 +415,17 @@ Decorator::Title(Decorator::Tab* tab) const
} }
float
Decorator::TabLocation(int32 tab) const
{
Decorator::Tab* decoratorTab = _TabAt(tab);
if (decoratorTab == NULL)
return 0.0f;
return (float)decoratorTab->tabOffset;
}
bool bool
Decorator::SetTabLocation(int32 tab, float location, bool isShifting, Decorator::SetTabLocation(int32 tab, float location, bool isShifting,
BRegion* updateRegion) BRegion* updateRegion)
@@ -443,13 +479,6 @@ Decorator::IsFocus(Decorator::Tab* tab) const
} }
void
Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth,
int32* maxHeight) const
{
}
// #pragma mark - virtual methods // #pragma mark - virtual methods
@@ -572,6 +601,76 @@ Decorator::ResizeBy(BPoint offset, BRegion* dirty)
} }
void
Decorator::ExtendDirtyRegion(Region region, BRegion& dirty)
{
switch (region) {
case REGION_TAB:
dirty.Include(fTitleBarRect);
break;
case REGION_CLOSE_BUTTON:
if ((fTopTab->flags & B_NOT_CLOSABLE) == 0) {
for (int32 i = 0; i < fTabList.CountItems(); i++)
dirty.Include(fTabList.ItemAt(i)->closeRect);
}
break;
case REGION_MINIMIZE_BUTTON:
if ((fTopTab->flags & B_NOT_MINIMIZABLE) == 0) {
for (int32 i = 0; i < fTabList.CountItems(); i++)
dirty.Include(fTabList.ItemAt(i)->minimizeRect);
}
break;
case REGION_ZOOM_BUTTON:
if ((fTopTab->flags & B_NOT_ZOOMABLE) == 0) {
for (int32 i = 0; i < fTabList.CountItems(); i++)
dirty.Include(fTabList.ItemAt(i)->zoomRect);
}
break;
case REGION_LEFT_BORDER:
if (fLeftBorder.IsValid()) {
// fLeftBorder doesn't include the corners, so we have to add
// them manually.
BRect rect(fLeftBorder);
rect.top = fTopBorder.top;
rect.bottom = fBottomBorder.bottom;
dirty.Include(rect);
}
break;
case REGION_RIGHT_BORDER:
if (fRightBorder.IsValid()) {
// fRightBorder doesn't include the corners, so we have to add
// them manually.
BRect rect(fRightBorder);
rect.top = fTopBorder.top;
rect.bottom = fBottomBorder.bottom;
dirty.Include(rect);
}
break;
case REGION_TOP_BORDER:
dirty.Include(fTopBorder);
break;
case REGION_BOTTOM_BORDER:
dirty.Include(fBottomBorder);
break;
case REGION_RIGHT_BOTTOM_CORNER:
if ((fTopTab->flags & B_NOT_RESIZABLE) == 0)
dirty.Include(fResizeRect);
break;
default:
break;
}
}
/*! \brief Sets a specific highlight for a decorator region. /*! \brief Sets a specific highlight for a decorator region.
Can be overridden by derived classes, but the base class version must be Can be overridden by derived classes, but the base class version must be
@@ -616,38 +715,43 @@ Decorator::SetSettings(const BMessage& settings, BRegion* updateRegion)
bool bool
Decorator::GetSettings(BMessage* settings) const Decorator::GetSettings(BMessage* settings) const
{ {
return false; if (!fTitleBarRect.IsValid())
return false;
if (settings->AddRect("tab frame", fTitleBarRect) != B_OK)
return false;
if (settings->AddFloat("border width", fBorderWidth) != B_OK)
return false;
// TODO only add the location of the tab of the window who requested the
// settings
for (int32 i = 0; i < fTabList.CountItems(); i++) {
Decorator::Tab* tab = _TabAt(i);
if (settings->AddFloat("tab location", (float)tab->tabOffset) != B_OK)
return false;
}
return true;
} }
/*! \brief Updates the decorator in the rectangular area \a updateRect.
The default version updates all areas which intersect the frame and tab.
\param updateRect The rectangular area to update.
*/
void void
Decorator::Draw(BRect updateRect) Decorator::GetSizeLimits(int32* minWidth, int32* minHeight,
int32* maxWidth, int32* maxHeight) const
{ {
_DrawFrame(updateRect & fFrame); float minTabSize = 0;
_DrawTabs(updateRect & fTitleBarRect); if (CountTabs() > 0)
} minTabSize = _TabAt(0)->minTabSize;
if (fTitleBarRect.IsValid()) {
//! Forces a complete decorator update *minWidth = (int32)roundf(max_c(*minWidth,
void minTabSize - 2 * fBorderWidth));
Decorator::Draw() }
{ if (fResizeRect.IsValid()) {
_DrawFrame(fFrame); *minHeight = (int32)roundf(max_c(*minHeight,
_DrawTabs(fTitleBarRect); fResizeRect.Height() - fBorderWidth));
} }
//! draws the frame
void
Decorator::DrawFrame()
{
_DrawFrame(fFrame);
} }
@@ -667,6 +771,17 @@ Decorator::DrawTab(int32 tabIndex)
} }
//! draws the title
void
Decorator::DrawTitle(int32 tab)
{
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
if (decoratorTab == NULL)
return;
_DrawTitle(decoratorTab, decoratorTab->tabRect);
}
//! Draws the close button //! Draws the close button
void void
Decorator::DrawClose(int32 tab) Decorator::DrawClose(int32 tab)
@@ -691,17 +806,6 @@ Decorator::DrawMinimize(int32 tab)
} }
//! draws the title
void
Decorator::DrawTitle(int32 tab)
{
Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
if (decoratorTab == NULL)
return;
_DrawTitle(decoratorTab, decoratorTab->tabRect);
}
//! draws the zoom button //! draws the zoom button
void void
Decorator::DrawZoom(int32 tab) Decorator::DrawZoom(int32 tab)
@@ -722,32 +826,37 @@ Decorator::UIColor(color_which which)
} }
/*! \brief Extends a dirty region by a decorator region. float
Decorator::BorderWidth()
Must be implemented by derived classes.
\param region The decorator region.
\param dirty The dirty region to be extended.
*/
void
Decorator::ExtendDirtyRegion(Region region, BRegion& dirty)
{ {
return fBorderWidth;
} }
//! Function for calculating layout for the decorator float
void Decorator::TabHeight()
Decorator::_DoLayout()
{ {
if (fTitleBarRect.IsValid())
return fTitleBarRect.Height();
return fBorderWidth;
} }
/*! \brief Actually draws the frame // #pragma mark - Protected methods
\param rect Area of the frame to update
*/
void Decorator::Tab*
Decorator::_DrawFrame(BRect rect) Decorator::_AllocateNewTab()
{ {
Decorator::Tab* tab = new(std::nothrow) Decorator::Tab;
if (tab == NULL)
return NULL;
// Set appropriate colors based on the current focus value. In this case,
// each decorator defaults to not having the focus.
_SetFocus(tab);
return tab;
} }
@@ -763,74 +872,15 @@ Decorator::_DrawTabs(BRect rect)
} }
_DrawTab(tab, rect); _DrawTab(tab, rect);
} }
if (focusTab != NULL) if (focusTab != NULL)
_DrawTab(focusTab, rect); _DrawTab(focusTab, rect);
} }
/*! \brief Actually draws the tab //! Hook function called when the decorator changes focus
This function is called when the tab itself needs drawn. Other items,
like the window title or buttons, should not be drawn here.
\param rect Area of the tab to update
*/
void void
Decorator::_DrawTab(Decorator::Tab* tab, BRect rect) Decorator::_SetFocus(Decorator::Tab* tab)
{
}
/*! \brief Actually draws the close button
Unless a subclass has a particularly large button, it is probably
unnecessary to check the update rectangle.
\param rect Area of the button to update
*/
void
Decorator::_DrawClose(Decorator::Tab* tab, bool direct, BRect rect)
{
}
/*! \brief Actually draws the title
The main tasks for this function are to ensure that the decorator draws
the title only in its own area and drawing the title itself.
Using B_OP_COPY for drawing the title is recommended because of the marked
performance hit of the other drawing modes, but it is not a requirement.
\param rect area of the title to update
*/
void
Decorator::_DrawTitle(Decorator::Tab* tab, BRect rect)
{
}
/*! \brief Actually draws the zoom button
Unless a subclass has a particularly large button, it is probably
unnecessary to check the update rectangle.
\param rect Area of the button to update
*/
void
Decorator::_DrawZoom(Decorator::Tab* tab, bool direct, BRect rect)
{
}
/*!
\brief Actually draws the minimize button
Unless a subclass has a particularly large button, it is probably
unnecessary to check the update rectangle.
\param rect Area of the button to update
*/
void
Decorator::_DrawMinimize(Decorator::Tab* tab, bool direct, BRect rect)
{ {
} }
@@ -843,31 +893,67 @@ Decorator::_SetTabLocation(Decorator::Tab* tab, float location, bool isShifting,
} }
//! Hook function called when the decorator changes focus Decorator::Tab*
void Decorator::_TabAt(int32 index) const
Decorator::_SetFocus(Decorator::Tab* tab)
{ {
return static_cast<Decorator::Tab*>(fTabList.ItemAt(index));
} }
void void
Decorator::_FontsChanged(DesktopSettings& settings, BRegion* updateRegion) Decorator::_FontsChanged(DesktopSettings& settings, BRegion* updateRegion)
{ {
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
_InvalidateBitmaps();
_UpdateFont(settings);
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
} }
void void
Decorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings, Decorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings,
window_look look, BRegion* updateRect) window_look look, BRegion* updateRegion)
{ {
// TODO: we could be much smarter about the update region
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
tab->look = look; tab->look = look;
_UpdateFont(settings);
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
} }
void void
Decorator::_SetFlags(Decorator::Tab* tab, uint32 flags, BRegion* updateRegion) Decorator::_SetFlags(Decorator::Tab* tab, uint32 flags, BRegion* updateRegion)
{ {
// TODO: we could be much smarter about the update region
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
tab->flags = flags; tab->flags = flags;
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
} }
@@ -914,3 +1000,17 @@ Decorator::_InvalidateFootprint()
{ {
fFootprintValid = false; fFootprintValid = false;
} }
void
Decorator::_InvalidateBitmaps()
{
for (int32 i = 0; i < fTabList.CountItems(); i++) {
Decorator::Tab* tab = static_cast<Decorator::Tab*>(_TabAt(i));
for (int32 index = 0; index < 4; index++) {
tab->closeBitmaps[index] = NULL;
tab->minimizeBitmaps[index] = NULL;
tab->zoomBitmaps[index] = NULL;
}
}
}
+209 -159
View File
@@ -22,219 +22,269 @@
class DesktopSettings; class DesktopSettings;
class DrawingEngine; class DrawingEngine;
class ServerBitmap;
class ServerFont; class ServerFont;
class BRegion; class BRegion;
class Decorator { class Decorator {
public: public:
class Tab { struct Tab {
public: Tab();
Tab(); virtual ~Tab() {}
virtual ~Tab() {}
BRect zoomRect; BRect tabRect;
BRect closeRect;
BRect minimizeRect;
BRect tabRect;
bool closePressed : 1; BRect zoomRect;
bool zoomPressed : 1; BRect closeRect;
bool minimizePressed : 1; BRect minimizeRect;
window_look look; bool closePressed : 1;
uint32 flags; bool zoomPressed : 1;
bool isFocused : 1; bool minimizePressed : 1;
BString title; window_look look;
}; uint32 flags;
bool isFocused : 1;
enum Region { BString title;
REGION_NONE,
REGION_TAB, uint32 tabOffset;
float tabLocation;
float textOffset;
REGION_CLOSE_BUTTON, BString truncatedTitle;
REGION_ZOOM_BUTTON, int32 truncatedTitleLength;
REGION_MINIMIZE_BUTTON,
REGION_LEFT_BORDER, bool buttonFocus : 1;
REGION_RIGHT_BORDER,
REGION_TOP_BORDER,
REGION_BOTTOM_BORDER,
REGION_LEFT_TOP_CORNER, bool isHighlighted : 1;
REGION_LEFT_BOTTOM_CORNER,
REGION_RIGHT_TOP_CORNER,
REGION_RIGHT_BOTTOM_CORNER,
REGION_COUNT float minTabSize;
}; float maxTabSize;
enum { ServerBitmap* closeBitmaps[4];
HIGHLIGHT_NONE, ServerBitmap* minimizeBitmaps[4];
HIGHLIGHT_RESIZE_BORDER, ServerBitmap* zoomBitmaps[4];
};
HIGHLIGHT_USER_DEFINED enum Region {
}; REGION_NONE,
public: REGION_TAB,
Decorator(DesktopSettings& settings, BRect rect);
virtual ~Decorator();
virtual Decorator::Tab* AddTab(DesktopSettings& settings, const char* title, REGION_CLOSE_BUTTON,
window_look look, uint32 flags, REGION_ZOOM_BUTTON,
int32 index = -1, BRegion* updateRegion = NULL); REGION_MINIMIZE_BUTTON,
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) const
{ return fTabList.ItemAt(index); }
int32 CountTabs() const
{ return fTabList.CountItems(); }
void SetTopTab(int32 tab);
void SetDrawingEngine(DrawingEngine *driver); REGION_LEFT_BORDER,
inline DrawingEngine* GetDrawingEngine() const REGION_RIGHT_BORDER,
{ return fDrawingEngine; } REGION_TOP_BORDER,
REGION_BOTTOM_BORDER,
void FontsChanged(DesktopSettings& settings, REGION_LEFT_TOP_CORNER,
BRegion* updateRegion = NULL); REGION_LEFT_BOTTOM_CORNER,
void SetLook(int32 tab, DesktopSettings& settings, REGION_RIGHT_TOP_CORNER,
window_look look, BRegion* updateRegion = NULL); REGION_RIGHT_BOTTOM_CORNER,
void SetFlags(int32 tab, uint32 flags,
BRegion* updateRegion = NULL);
window_look Look(int32 tab) const; REGION_COUNT
uint32 Flags(int32 tab) const; };
BRect BorderRect() const; enum {
BRect TitleBarRect() const; HIGHLIGHT_NONE,
BRect TabRect(int32 tab) const; HIGHLIGHT_RESIZE_BORDER,
BRect TabRect(Decorator::Tab* tab) const;
void SetClose(int32 tab, bool pressed); HIGHLIGHT_USER_DEFINED
void SetMinimize(int32 tab, bool pressed); };
void SetZoom(int32 tab, bool pressed);
const char* Title(int32 tab) const; Decorator(DesktopSettings& settings,
const char* Title(Decorator::Tab* tab) const; BRect frame);
void SetTitle(int32 tab, const char* string, virtual ~Decorator();
BRegion* updateRegion = NULL);
void SetFocus(int32 tab, bool focussed); virtual Decorator::Tab* AddTab(DesktopSettings& settings,
bool IsFocus(int32 tab) const; const char* title, window_look look,
bool IsFocus(Decorator::Tab* tab) const; uint32 flags, 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);
/*! \return true if tab location updated, false if out of bounds virtual int32 TabAt(const BPoint& where) const;
or unsupported */ Decorator::Tab* TabAt(int32 index) const
bool SetTabLocation(int32 tab, float location, { return fTabList.ItemAt(index); }
bool isShifting, BRegion* updateRegion = NULL); int32 CountTabs() const
virtual float TabLocation(int32 tab) const { return fTabList.CountItems(); }
{ return 0.0; } void SetTopTab(int32 tab);
virtual Region RegionAt(BPoint where, int32& tab) const; void SetDrawingEngine(DrawingEngine *driver);
inline DrawingEngine* GetDrawingEngine() const
{ return fDrawingEngine; }
virtual void GetSizeLimits(int32* minWidth, int32* minHeight, void FontsChanged(DesktopSettings& settings,
int32* maxWidth, int32* maxHeight) const; BRegion* updateRegion = NULL);
void SetLook(int32 tab, DesktopSettings& settings,
window_look look,
BRegion* updateRegion = NULL);
void SetFlags(int32 tab, uint32 flags,
BRegion* updateRegion = NULL);
const BRegion& GetFootprint(); window_look Look(int32 tab) const;
uint32 Flags(int32 tab) const;
void MoveBy(float x, float y); BRect BorderRect() const;
void MoveBy(BPoint offset); BRect TitleBarRect() const;
void ResizeBy(float x, float y, BRegion* dirty); BRect TabRect(int32 tab) const;
void ResizeBy(BPoint offset, BRegion* dirty); BRect TabRect(Decorator::Tab* tab) const;
virtual bool SetRegionHighlight(Region region, uint8 highlight, void SetClose(int32 tab, bool pressed);
BRegion* dirty, int32 tab = -1); void SetMinimize(int32 tab, bool pressed);
inline uint8 RegionHighlight(Region region, void SetZoom(int32 tab, bool pressed);
int32 tab = -1) const;
bool SetSettings(const BMessage& settings, const char* Title(int32 tab) const;
BRegion* updateRegion = NULL); const char* Title(Decorator::Tab* tab) const;
virtual bool GetSettings(BMessage* settings) const; void SetTitle(int32 tab, const char* string,
BRegion* updateRegion = NULL);
virtual void Draw(BRect updateRect); void SetFocus(int32 tab, bool focussed);
virtual void Draw(); bool IsFocus(int32 tab) const;
virtual void DrawClose(int32 tab); bool IsFocus(Decorator::Tab* tab) const;
virtual void DrawMinimize(int32 tab);
virtual void DrawTab(int32 tab);
virtual void DrawTitle(int32 tab);
virtual void DrawZoom(int32 tab);
virtual void DrawFrame();
rgb_color UIColor(color_which which); virtual float TabLocation(int32 tab) const;
bool SetTabLocation(int32 tab, float location,
bool isShifting,
BRegion* updateRegion = NULL);
/*! \return true if tab location updated, false if out of
bounds or unsupported */
virtual void ExtendDirtyRegion(Region region, BRegion& dirty); virtual Region RegionAt(BPoint where, int32& tab) const;
const BRegion& GetFootprint();
void MoveBy(float x, float y);
void MoveBy(BPoint offset);
void ResizeBy(float x, float y, BRegion* dirty);
void ResizeBy(BPoint offset, BRegion* dirty);
virtual bool SetRegionHighlight(Region region,
uint8 highlight, BRegion* dirty,
int32 tab = -1);
inline uint8 RegionHighlight(Region region,
int32 tab = -1) const;
bool SetSettings(const BMessage& settings,
BRegion* updateRegion = NULL);
virtual bool GetSettings(BMessage* settings) const;
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
int32* maxWidth, int32* maxHeight) const;
virtual void ExtendDirtyRegion(Region region, BRegion& dirty);
virtual void Draw(BRect updateRect) = 0;
virtual void Draw() = 0;
virtual void DrawTab(int32 tab);
virtual void DrawTitle(int32 tab);
virtual void DrawClose(int32 tab);
virtual void DrawMinimize(int32 tab);
virtual void DrawZoom(int32 tab);
rgb_color UIColor(color_which which);
float BorderWidth();
float TabHeight();
protected: protected:
virtual void _DoLayout(); virtual Decorator::Tab* _AllocateNewTab();
virtual void _DrawFrame(BRect rect); virtual void _DoLayout() = 0;
//! method for calculating layout for the decorator
virtual void _DrawTabs(BRect rect); virtual void _DrawFrame(BRect rect) = 0;
virtual void _DrawTab(Decorator::Tab* tab, BRect rect); virtual void _DrawTabs(BRect rect);
virtual void _DrawTitle(Decorator::Tab* tab, BRect rect);
//! direct means drawing without double buffering
virtual void _DrawClose(Decorator::Tab* tab, bool direct,
BRect rect);
virtual void _DrawZoom(Decorator::Tab* tab, bool direct,
BRect rect);
virtual void _DrawMinimize(Decorator::Tab* tab, bool direct,
BRect rect);
virtual Decorator::Tab* _AllocateNewTab() = 0; virtual void _DrawTab(Decorator::Tab* tab, BRect rect) = 0;
virtual void _DrawTitle(Decorator::Tab* tab,
BRect rect) = 0;
virtual void _SetTitle(Decorator::Tab* tab, const char* string, virtual void _DrawButtons(Decorator::Tab* tab,
BRegion* updateRegion = NULL) = 0; const BRect& invalid) = 0;
int32 _TitleWidth(Decorator::Tab* tab) const virtual void _DrawClose(Decorator::Tab* tab, bool direct,
{ return tab->title.CountChars(); } BRect rect) = 0;
virtual void _DrawMinimize(Decorator::Tab* tab, bool direct,
BRect rect) = 0;
virtual void _DrawZoom(Decorator::Tab* tab, bool direct,
BRect rect) = 0;
virtual bool _SetTabLocation(Decorator::Tab* tab, float location, virtual void _SetTitle(Decorator::Tab* tab,
bool isShifting, BRegion* updateRegion = NULL); const char* string,
virtual void _SetFocus(Decorator::Tab* tab); BRegion* updateRegion = NULL) = 0;
int32 _TitleWidth(Decorator::Tab* tab) const
{ return tab->title.CountChars(); }
virtual void _FontsChanged(DesktopSettings& settings, virtual void _SetFocus(Decorator::Tab* tab);
BRegion* updateRegion = NULL); virtual bool _SetTabLocation(Decorator::Tab* tab,
virtual void _SetLook(Decorator::Tab* tab, DesktopSettings& settings, float location, bool isShifting,
window_look look, BRegion* updateRegion = NULL); BRegion* updateRegion = NULL);
virtual void _SetFlags(Decorator::Tab* tab, uint32 flags,
BRegion* updateRegion = NULL);
virtual void _MoveBy(BPoint offset); virtual Decorator::Tab* _TabAt(int32 index) const;
virtual void _ResizeBy(BPoint offset, BRegion* dirty) = 0;
virtual bool _SetSettings(const BMessage& settings, virtual void _FontsChanged(DesktopSettings& settings,
BRegion* updateRegion = NULL); BRegion* updateRegion = NULL);
virtual void _UpdateFont(DesktopSettings& settings) = 0;
virtual bool _AddTab(DesktopSettings& settings, virtual void _SetLook(Decorator::Tab* tab,
int32 index = -1, DesktopSettings& settings,
BRegion* updateRegion = NULL) = 0; window_look look,
virtual bool _RemoveTab(int32 index, BRegion* updateRegion = NULL);
BRegion* updateRegion = NULL) = 0; virtual void _SetFlags(Decorator::Tab* tab, uint32 flags,
virtual bool _MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion = NULL);
BRegion* updateRegion = NULL) = 0;
virtual void _GetFootprint(BRegion *region); virtual void _MoveBy(BPoint offset);
void _InvalidateFootprint(); virtual void _ResizeBy(BPoint offset, BRegion* dirty) = 0;
DrawingEngine* fDrawingEngine; virtual bool _SetSettings(const BMessage& settings,
DrawState fDrawState; BRegion* updateRegion = NULL);
BRect fTitleBarRect; virtual bool _AddTab(DesktopSettings& settings,
BRect fFrame; int32 index = -1,
BRect fResizeRect; BRegion* updateRegion = NULL) = 0;
BRect fBorderRect; virtual bool _RemoveTab(int32 index,
BRegion* updateRegion = NULL) = 0;
virtual bool _MoveTab(int32 from, int32 to, bool isMoving,
BRegion* updateRegion = NULL) = 0;
Decorator::Tab* fTopTab; virtual void _GetFootprint(BRegion *region);
void _InvalidateFootprint();
void _InvalidateBitmaps();
DrawingEngine* fDrawingEngine;
DrawState fDrawState;
// Individual rects for handling window frame
// rendering the proper way
BRect fTitleBarRect;
BRect fFrame;
BRect fResizeRect;
BRect fBorderRect;
BRect fLeftBorder;
BRect fTopBorder;
BRect fBottomBorder;
BRect fRightBorder;
int32 fBorderWidth;
Decorator::Tab* fTopTab;
BObjectList<Decorator::Tab> fTabList; BObjectList<Decorator::Tab> fTabList;
private:
BRegion fFootprint;
bool fFootprintValid : 1;
uint8 fRegionHighlights[REGION_COUNT - 1]; private:
BRegion fFootprint;
bool fFootprintValid : 1;
uint8 fRegionHighlights[REGION_COUNT - 1];
}; };
+63 -49
View File
@@ -91,36 +91,7 @@ DefaultDecorator::~DefaultDecorator()
} }
// #pragma mark - // #pragma mark - Public methods
void
DefaultDecorator::Draw(BRect updateRect)
{
STRACE(("DefaultDecorator: Draw(%.1f,%.1f,%.1f,%.1f)\n",
updateRect.left, updateRect.top, updateRect.right, updateRect.bottom));
// We need to draw a few things: the tab, the resize knob, the borders,
// and the buttons
fDrawingEngine->SetDrawState(&fDrawState);
_DrawFrame(updateRect);
_DrawTabs(updateRect);
}
void
DefaultDecorator::Draw()
{
STRACE(("DefaultDecorator: Draw()"));
// Easy way to draw everything - no worries about drawing only certain
// things
fDrawingEngine->SetDrawState(&fDrawState);
_DrawFrame(BRect(fTopBorder.LeftTop(), fBottomBorder.RightBottom()));
_DrawTabs(fTitleBarRect);
}
/*! Returns the frame colors for the specified decorator component. /*! Returns the frame colors for the specified decorator component.
@@ -136,7 +107,7 @@ void
DefaultDecorator::GetComponentColors(Component component, uint8 highlight, DefaultDecorator::GetComponentColors(Component component, uint8 highlight,
ComponentColors _colors, Decorator::Tab* _tab) ComponentColors _colors, Decorator::Tab* _tab)
{ {
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
switch (component) { switch (component) {
case COMPONENT_TAB: case COMPONENT_TAB:
if (tab && tab->buttonFocus) { if (tab && tab->buttonFocus) {
@@ -214,10 +185,10 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight,
void void
DefaultDecorator::_DrawFrame(BRect invalid) DefaultDecorator::_DrawFrame(BRect rect)
{ {
STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, STRACE(("_DrawFrame(%f,%f,%f,%f)\n", rect.left, rect.top,
invalid.right, invalid.bottom)); rect.right, rect.bottom));
// NOTE: the DrawingEngine needs to be locked for the entire // NOTE: the DrawingEngine needs to be locked for the entire
// time for the clipping to stay valid for this decorator // time for the clipping to stay valid for this decorator
@@ -225,7 +196,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK) if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK)
return; return;
if (BorderWidth() <= 0) if (fBorderWidth <= 0)
return; return;
// Draw the border frame // Draw the border frame
@@ -236,7 +207,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
case B_MODAL_WINDOW_LOOK: case B_MODAL_WINDOW_LOOK:
{ {
// top // top
if (invalid.Intersects(fTopBorder)) { if (rect.Intersects(fTopBorder)) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab);
@@ -256,7 +227,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// left // left
if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -BorderWidth()))) { if (rect.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab);
@@ -266,7 +237,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// bottom // bottom
if (invalid.Intersects(fBottomBorder)) { if (rect.Intersects(fBottomBorder)) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab);
@@ -277,7 +248,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// right // right
if (invalid.Intersects(fRightBorder.InsetByCopy(0, -BorderWidth()))) { if (rect.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab);
@@ -294,7 +265,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
case kLeftTitledWindowLook: case kLeftTitledWindowLook:
{ {
// top // top
if (invalid.Intersects(fTopBorder)) { if (rect.Intersects(fTopBorder)) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab);
@@ -313,7 +284,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// left // left
if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -BorderWidth()))) { if (rect.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab);
@@ -333,7 +304,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// bottom // bottom
if (invalid.Intersects(fBottomBorder)) { if (rect.Intersects(fBottomBorder)) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab);
@@ -344,7 +315,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
} }
// right // right
if (invalid.Intersects(fRightBorder.InsetByCopy(0, -BorderWidth()))) { if (rect.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) {
ComponentColors colors; ComponentColors colors;
_GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab);
@@ -382,7 +353,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
switch ((int)fTopTab->look) { switch ((int)fTopTab->look) {
case B_DOCUMENT_WINDOW_LOOK: case B_DOCUMENT_WINDOW_LOOK:
{ {
if (!invalid.Intersects(r)) if (!rect.Intersects(r))
break; break;
float x = r.right - 3; float x = r.right - 3;
@@ -428,7 +399,7 @@ DefaultDecorator::_DrawFrame(BRect invalid)
case B_MODAL_WINDOW_LOOK: case B_MODAL_WINDOW_LOOK:
case kLeftTitledWindowLook: case kLeftTitledWindowLook:
{ {
if (!invalid.Intersects(BRect(fRightBorder.right - kBorderResizeLength, if (!rect.Intersects(BRect(fRightBorder.right - kBorderResizeLength,
fBottomBorder.bottom - kBorderResizeLength, fRightBorder.right - 1, fBottomBorder.bottom - kBorderResizeLength, fRightBorder.right - 1,
fBottomBorder.bottom - 1))) fBottomBorder.bottom - 1)))
break; break;
@@ -452,6 +423,14 @@ DefaultDecorator::_DrawFrame(BRect invalid)
} }
/*! \brief Actually draws the tab
This function is called when the tab itself needs drawn. Other items,
like the window title or buttons, should not be drawn here.
\param tab The \a tab to update.
\param rect The area of the \a tab to update.
*/
void void
DefaultDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid) DefaultDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid)
{ {
@@ -522,17 +501,27 @@ DefaultDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid)
_DrawTitle(tab, tabRect); _DrawTitle(tab, tabRect);
DrawButtons(tab, invalid); _DrawButtons(tab, invalid);
} }
/*! \brief Actually draws the title
The main tasks for this function are to ensure that the decorator draws
the title only in its own area and drawing the title itself.
Using B_OP_COPY for drawing the title is recommended because of the marked
performance hit of the other drawing modes, but it is not a requirement.
\param tab The \a tab to update.
\param rect area of the title to update.
*/
void void
DefaultDecorator::_DrawTitle(Decorator::Tab* _tab, BRect rect) DefaultDecorator::_DrawTitle(Decorator::Tab* _tab, BRect rect)
{ {
STRACE(("_DrawTitle(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right, STRACE(("_DrawTitle(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right,
rect.bottom)); rect.bottom));
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
const BRect& tabRect = tab->tabRect; const BRect& tabRect = tab->tabRect;
const BRect& closeRect = tab->closeRect; const BRect& closeRect = tab->closeRect;
@@ -571,13 +560,22 @@ DefaultDecorator::_DrawTitle(Decorator::Tab* _tab, BRect rect)
} }
/*! \brief Actually draws the close button
Unless a subclass has a particularly large button, it is probably
unnecessary to check the update rectangle.
\param _tab The \a tab to update.
\param direct Draw without double buffering.
\param rect The area of the button to update.
*/
void void
DefaultDecorator::_DrawClose(Decorator::Tab* _tab, bool direct, BRect rect) DefaultDecorator::_DrawClose(Decorator::Tab* _tab, bool direct, BRect rect)
{ {
STRACE(("_DrawClose(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right, STRACE(("_DrawClose(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right,
rect.bottom)); rect.bottom));
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
int32 index = (tab->buttonFocus ? 0 : 1) + (tab->closePressed ? 0 : 2); int32 index = (tab->buttonFocus ? 0 : 1) + (tab->closePressed ? 0 : 2);
ServerBitmap* bitmap = tab->closeBitmaps[index]; ServerBitmap* bitmap = tab->closeBitmaps[index];
@@ -591,6 +589,15 @@ DefaultDecorator::_DrawClose(Decorator::Tab* _tab, bool direct, BRect rect)
} }
/*! \brief Actually draws the zoom button
Unless a subclass has a particularly large button, it is probably
unnecessary to check the update rectangle.
\param _tab The \a tab to update.
\param direct Draw without double buffering.
\param rect The area of the button to update.
*/
void void
DefaultDecorator::_DrawZoom(Decorator::Tab* _tab, bool direct, BRect rect) DefaultDecorator::_DrawZoom(Decorator::Tab* _tab, bool direct, BRect rect)
{ {
@@ -600,7 +607,7 @@ DefaultDecorator::_DrawZoom(Decorator::Tab* _tab, bool direct, BRect rect)
if (rect.IntegerWidth() < 1) if (rect.IntegerWidth() < 1)
return; return;
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
int32 index = (tab->buttonFocus ? 0 : 1) + (tab->zoomPressed ? 0 : 2); int32 index = (tab->buttonFocus ? 0 : 1) + (tab->zoomPressed ? 0 : 2);
ServerBitmap* bitmap = tab->zoomBitmaps[index]; ServerBitmap* bitmap = tab->zoomBitmaps[index];
if (bitmap == NULL) { if (bitmap == NULL) {
@@ -613,6 +620,13 @@ DefaultDecorator::_DrawZoom(Decorator::Tab* _tab, bool direct, BRect rect)
} }
void
DefaultDecorator::_DrawMinimize(Decorator::Tab* tab, bool direct, BRect rect)
{
// This decorator doesn't have this button
}
// #pragma mark - Private methods // #pragma mark - Private methods
+6 -6
View File
@@ -28,21 +28,21 @@ public:
BRect frame); BRect frame);
virtual ~DefaultDecorator(); virtual ~DefaultDecorator();
virtual void Draw(BRect updateRect);
virtual void Draw();
virtual void GetComponentColors(Component component, virtual void GetComponentColors(Component component,
uint8 highlight, ComponentColors _colors, uint8 highlight, ComponentColors _colors,
Decorator::Tab* tab = NULL); Decorator::Tab* tab = NULL);
protected: protected:
virtual void _DrawFrame(BRect r); virtual void _DrawFrame(BRect rect);
virtual void _DrawTab(Decorator::Tab* tab, BRect r); virtual void _DrawTab(Decorator::Tab* tab, BRect r);
virtual void _DrawTitle(Decorator::Tab* tab, BRect r); virtual void _DrawTitle(Decorator::Tab* tab, BRect r);
virtual void _DrawClose(Decorator::Tab* tab, bool direct, virtual void _DrawClose(Decorator::Tab* tab, bool direct,
BRect r); BRect rect);
virtual void _DrawZoom(Decorator::Tab* tab, bool direct, virtual void _DrawZoom(Decorator::Tab* tab, bool direct,
BRect r); BRect rect);
virtual void _DrawMinimize(Decorator::Tab* tab, bool direct,
BRect rect);
private: private:
void _DrawButtonBitmap(ServerBitmap* bitmap, void _DrawButtonBitmap(ServerBitmap* bitmap,
+59 -267
View File
@@ -54,24 +54,6 @@ int_equal(float x, float y)
} }
TabDecorator::Tab::Tab()
:
tabOffset(0),
tabLocation(0.0f),
textOffset(10.0f),
truncatedTitle(""),
truncatedTitleLength(0),
buttonFocus(false),
isHighlighted(false),
minTabSize(0.0f),
maxTabSize(0.0f)
{
closeBitmaps[0] = closeBitmaps[1] = closeBitmaps[2] = closeBitmaps[3]
= zoomBitmaps[0] = zoomBitmaps[1] = zoomBitmaps[2] = zoomBitmaps[3]
= NULL;
}
static const float kBorderResizeLength = 22.0; static const float kBorderResizeLength = 22.0;
static const float kResizeKnobSize = 18.0; static const float kResizeKnobSize = 18.0;
@@ -81,9 +63,9 @@ static const float kResizeKnobSize = 18.0;
// TODO: get rid of DesktopSettings here, and introduce private accessor // TODO: get rid of DesktopSettings here, and introduce private accessor
// methods to the Decorator base class // methods to the Decorator base class
TabDecorator::TabDecorator(DesktopSettings& settings, BRect rect) TabDecorator::TabDecorator(DesktopSettings& settings, BRect frame)
: :
Decorator(settings, rect), Decorator(settings, frame),
fOldMovingTab(0, 0, -1, -1), fOldMovingTab(0, 0, -1, -1),
// focus color constants // focus color constants
kFocusFrameColor(settings.UIColor(B_WINDOW_BORDER_COLOR)), kFocusFrameColor(settings.UIColor(B_WINDOW_BORDER_COLOR)),
@@ -104,12 +86,12 @@ TabDecorator::TabDecorator(DesktopSettings& settings, BRect rect)
(B_DARKEN_1_TINT + B_NO_TINT) / 2)), (B_DARKEN_1_TINT + B_NO_TINT) / 2)),
kNonFocusTextColor(settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR)) kNonFocusTextColor(settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR))
{ {
// TODO: If the decorator was created with a frame too small, it should
// resize itself!
STRACE(("TabDecorator:\n")); STRACE(("TabDecorator:\n"));
STRACE(("\tFrame (%.1f,%.1f,%.1f,%.1f)\n", STRACE(("\tFrame (%.1f,%.1f,%.1f,%.1f)\n",
rect.left, rect.top, rect.right, rect.bottom)); frame.left, frame.top, frame.right, frame.bottom));
// TODO: If the decorator was created with a frame too small, it should
// resize itself!
} }
@@ -119,60 +101,38 @@ TabDecorator::~TabDecorator()
} }
float // #pragma mark - Public methods
TabDecorator::TabLocation(int32 tab) const
{
TabDecorator::Tab* decoratorTab = _TabAt(tab);
if (decoratorTab == NULL)
return 0.0f;
return (float)decoratorTab->tabOffset;
}
bool /*! \brief Updates the decorator in the rectangular area \a updateRect.
TabDecorator::GetSettings(BMessage* settings) const
{
if (!fTitleBarRect.IsValid())
return false;
if (settings->AddRect("tab frame", fTitleBarRect) != B_OK)
return false;
if (settings->AddFloat("border width", fBorderWidth) != B_OK)
return false;
// TODO only add the location of the tab of the window who requested the
// settings
for (int32 i = 0; i < fTabList.CountItems(); i++) {
TabDecorator::Tab* tab = _TabAt(i);
if (settings->AddFloat("tab location", (float)tab->tabOffset) != B_OK)
return false;
}
return true;
}
// #pragma mark -
Updates all areas which intersect the frame and tab.
\param updateRect The rectangular area to update.
*/
void void
TabDecorator::GetSizeLimits(int32* minWidth, int32* minHeight, TabDecorator::Draw(BRect updateRect)
int32* maxWidth, int32* maxHeight) const
{ {
float minTabSize = 0; STRACE(("TabDecorator::Draw(BRect updateRect): "));
if (CountTabs() > 0) updateRect.PrintToStream();
minTabSize = _TabAt(0)->minTabSize;
if (fTitleBarRect.IsValid()) { fDrawingEngine->SetDrawState(&fDrawState);
*minWidth = (int32)roundf(max_c(*minWidth,
minTabSize - 2 * fBorderWidth)); _DrawFrame(updateRect & fBorderRect);
} _DrawTabs(updateRect & fTitleBarRect);
if (fResizeRect.IsValid()) { }
*minHeight = (int32)roundf(max_c(*minHeight,
fResizeRect.Height() - fBorderWidth));
} //! Forces a complete decorator update
void
TabDecorator::Draw()
{
STRACE(("TabDecorator: Draw()"));
fDrawingEngine->SetDrawState(&fDrawState);
_DrawFrame(fBorderRect);
_DrawTabs(fTitleBarRect);
} }
@@ -220,73 +180,12 @@ TabDecorator::RegionAt(BPoint where, int32& tab) const
} }
void
TabDecorator::ExtendDirtyRegion(Region region, BRegion& dirty)
{
switch (region) {
case REGION_TAB:
dirty.Include(fTitleBarRect);
break;
case REGION_CLOSE_BUTTON:
if ((fTopTab->flags & B_NOT_CLOSABLE) == 0)
for (int32 i = 0; i < fTabList.CountItems(); i++)
dirty.Include(fTabList.ItemAt(i)->closeRect);
break;
case REGION_ZOOM_BUTTON:
if ((fTopTab->flags & B_NOT_ZOOMABLE) == 0)
for (int32 i = 0; i < fTabList.CountItems(); i++)
dirty.Include(fTabList.ItemAt(i)->zoomRect);
break;
case REGION_LEFT_BORDER:
if (fLeftBorder.IsValid()) {
// fLeftBorder doesn't include the corners, so we have to add
// them manually.
BRect rect(fLeftBorder);
rect.top = fTopBorder.top;
rect.bottom = fBottomBorder.bottom;
dirty.Include(rect);
}
break;
case REGION_RIGHT_BORDER:
if (fRightBorder.IsValid()) {
// fRightBorder doesn't include the corners, so we have to add
// them manually.
BRect rect(fRightBorder);
rect.top = fTopBorder.top;
rect.bottom = fBottomBorder.bottom;
dirty.Include(rect);
}
break;
case REGION_TOP_BORDER:
dirty.Include(fTopBorder);
break;
case REGION_BOTTOM_BORDER:
dirty.Include(fBottomBorder);
break;
case REGION_RIGHT_BOTTOM_CORNER:
if ((fTopTab->flags & B_NOT_RESIZABLE) == 0)
dirty.Include(fResizeRect);
break;
default:
break;
}
}
bool bool
TabDecorator::SetRegionHighlight(Region region, uint8 highlight, TabDecorator::SetRegionHighlight(Region region, uint8 highlight,
BRegion* dirty, int32 tabIndex) BRegion* dirty, int32 tabIndex)
{ {
TabDecorator::Tab* tab Decorator::Tab* tab
= static_cast<TabDecorator::Tab*>(_TabAt(tabIndex)); = static_cast<Decorator::Tab*>(_TabAt(tabIndex));
if (tab != NULL) { if (tab != NULL) {
tab->isHighlighted = highlight != 0; tab->isHighlighted = highlight != 0;
// Invalidate the bitmap caches for the close/zoom button, when the // Invalidate the bitmap caches for the close/zoom button, when the
@@ -309,23 +208,6 @@ TabDecorator::SetRegionHighlight(Region region, uint8 highlight,
} }
float
TabDecorator::BorderWidth()
{
return fBorderWidth;
}
float
TabDecorator::TabHeight()
{
if (fTitleBarRect.IsValid())
return fTitleBarRect.Height();
return BorderWidth();
}
void void
TabDecorator::_DoLayout() TabDecorator::_DoLayout()
{ {
@@ -382,6 +264,8 @@ TabDecorator::_DoLayout()
fBottomBorder.Set(0.0, 0.0, -1.0, -1.0); fBottomBorder.Set(0.0, 0.0, -1.0, -1.0);
} }
fBorderRect = BRect(fTopBorder.LeftTop(), fBottomBorder.RightBottom());
// calculate resize rect // calculate resize rect
if (fBorderWidth > 1) { if (fBorderWidth > 1) {
fResizeRect.Set(fBottomBorder.right - kResizeKnobSize, fResizeRect.Set(fBottomBorder.right - kResizeKnobSize,
@@ -419,7 +303,7 @@ TabDecorator::_DoTabLayout()
float sumTabWidth = 0; float sumTabWidth = 0;
// calculate our tab rect // calculate our tab rect
for (int32 i = 0; i < fTabList.CountItems(); i++) { for (int32 i = 0; i < fTabList.CountItems(); i++) {
TabDecorator::Tab* tab = _TabAt(i); Decorator::Tab* tab = _TabAt(i);
BRect& tabRect = tab->tabRect; BRect& tabRect = tab->tabRect;
// distance from one item of the tab bar to another. // distance from one item of the tab bar to another.
@@ -568,33 +452,12 @@ TabDecorator::_DistributeTabSize(float delta)
prevTab->tabRect.right = floor(fFrame.right + fBorderWidth); prevTab->tabRect.right = floor(fFrame.right + fBorderWidth);
for (int32 i = 0; i < fTabList.CountItems(); i++) { for (int32 i = 0; i < fTabList.CountItems(); i++) {
TabDecorator::Tab* tab = _TabAt(i); Decorator::Tab* tab = _TabAt(i);
tab->tabOffset = uint32(tab->tabRect.left - fLeftBorder.left); tab->tabOffset = uint32(tab->tabRect.left - fLeftBorder.left);
} }
} }
Decorator::Tab*
TabDecorator::_AllocateNewTab()
{
Decorator::Tab* tab = new(std::nothrow) TabDecorator::Tab;
if (tab == NULL)
return NULL;
// Set appropriate colors based on the current focus value. In this case,
// each decorator defaults to not having the focus.
_SetFocus(tab);
return tab;
}
TabDecorator::Tab*
TabDecorator::_TabAt(int32 index) const
{
return static_cast<TabDecorator::Tab*>(fTabList.ItemAt(index));
}
void void
TabDecorator::_SetTitle(Decorator::Tab* tab, const char* string, TabDecorator::_SetTitle(Decorator::Tab* tab, const char* string,
BRegion* updateRegion) BRegion* updateRegion)
@@ -617,78 +480,6 @@ TabDecorator::_SetTitle(Decorator::Tab* tab, const char* string,
} }
void
TabDecorator::_FontsChanged(DesktopSettings& settings,
BRegion* updateRegion)
{
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
_InvalidateBitmaps();
_UpdateFont(settings);
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
}
void
TabDecorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings,
window_look look, BRegion* updateRegion)
{
// TODO: we could be much smarter about the update region
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
tab->look = look;
_UpdateFont(settings);
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
}
void
TabDecorator::_SetFlags(Decorator::Tab* tab, uint32 flags,
BRegion* updateRegion)
{
// TODO: we could be much smarter about the update region
// get previous extent
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
tab->flags = flags;
_DoLayout();
_InvalidateFootprint();
if (updateRegion != NULL)
updateRegion->Include(&GetFootprint());
}
void
TabDecorator::_SetFocus(Decorator::Tab* _tab)
{
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab);
tab->buttonFocus = IsFocus(tab)
|| ((tab->look == B_FLOATING_WINDOW_LOOK
|| tab->look == kLeftTitledWindowLook)
&& (tab->flags & B_AVOID_FOCUS) != 0);
if (CountTabs() > 1)
_LayoutTabItems(tab, tab->tabRect);
}
void void
TabDecorator::_MoveBy(BPoint offset) TabDecorator::_MoveBy(BPoint offset)
{ {
@@ -725,7 +516,7 @@ TabDecorator::_ResizeBy(BPoint offset, BRegion* dirty)
fFrame.bottom += offset.y; fFrame.bottom += offset.y;
// Handle invalidation of resize rect // Handle invalidation of resize rect
if (dirty && !(fTopTab->flags & B_NOT_RESIZABLE)) { if (dirty != NULL && !(fTopTab->flags & B_NOT_RESIZABLE)) {
BRect realResizeRect; BRect realResizeRect;
switch ((int)fTopTab->look) { switch ((int)fTopTab->look) {
case B_DOCUMENT_WINDOW_LOOK: case B_DOCUMENT_WINDOW_LOOK:
@@ -818,7 +609,7 @@ TabDecorator::_ResizeBy(BPoint offset, BRegion* dirty)
return; return;
} }
TabDecorator::Tab* tab = _TabAt(0); Decorator::Tab* tab = _TabAt(0);
BRect& tabRect = tab->tabRect; BRect& tabRect = tab->tabRect;
BRect oldTabRect(tabRect); BRect oldTabRect(tabRect);
@@ -870,6 +661,20 @@ TabDecorator::_ResizeBy(BPoint offset, BRegion* dirty)
} }
void
TabDecorator::_SetFocus(Decorator::Tab* tab)
{
Decorator::Tab* decoratorTab = static_cast<Decorator::Tab*>(tab);
decoratorTab->buttonFocus = IsFocus(tab)
|| ((decoratorTab->look == B_FLOATING_WINDOW_LOOK
|| decoratorTab->look == kLeftTitledWindowLook)
&& (decoratorTab->flags & B_AVOID_FOCUS) != 0);
if (CountTabs() > 1)
_LayoutTabItems(decoratorTab, decoratorTab->tabRect);
}
bool bool
TabDecorator::_SetTabLocation(Decorator::Tab* _tab, float location, TabDecorator::_SetTabLocation(Decorator::Tab* _tab, float location,
bool isShifting, BRegion* updateRegion) bool isShifting, BRegion* updateRegion)
@@ -890,7 +695,7 @@ TabDecorator::_SetTabLocation(Decorator::Tab* _tab, float location,
} }
} }
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
BRect& tabRect = tab->tabRect; BRect& tabRect = tab->tabRect;
if (tabRect.IsValid() == false) if (tabRect.IsValid() == false)
return false; return false;
@@ -980,7 +785,7 @@ bool
TabDecorator::_MoveTab(int32 from, int32 to, bool isMoving, TabDecorator::_MoveTab(int32 from, int32 to, bool isMoving,
BRegion* updateRegion) BRegion* updateRegion)
{ {
TabDecorator::Tab* toTab = _TabAt(to); Decorator::Tab* toTab = _TabAt(to);
if (toTab == NULL) if (toTab == NULL)
return false; return false;
@@ -1039,9 +844,9 @@ TabDecorator::_GetFootprint(BRegion *region)
void void
TabDecorator::DrawButtons(Decorator::Tab* tab, const BRect& invalid) TabDecorator::_DrawButtons(Decorator::Tab* tab, const BRect& invalid)
{ {
STRACE(("TabDecorator: DrawButtons\n")); STRACE(("TabDecorator: _DrawButtons\n"));
// Draw the buttons if we're supposed to // Draw the buttons if we're supposed to
if (!(tab->flags & B_NOT_CLOSABLE) && invalid.Intersects(tab->closeRect)) if (!(tab->flags & B_NOT_CLOSABLE) && invalid.Intersects(tab->closeRect))
@@ -1090,23 +895,10 @@ TabDecorator::_GetButtonSizeAndOffset(const BRect& tabRect, float* _offset,
} }
void
TabDecorator::_InvalidateBitmaps()
{
for (int32 i = 0; i < fTabList.CountItems(); i++) {
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_TabAt(i));
for (int32 index = 0; index < 4; index++) {
tab->closeBitmaps[index] = NULL;
tab->zoomBitmaps[index] = NULL;
}
}
}
void void
TabDecorator::_LayoutTabItems(Decorator::Tab* _tab, const BRect& tabRect) TabDecorator::_LayoutTabItems(Decorator::Tab* _tab, const BRect& tabRect)
{ {
TabDecorator::Tab* tab = static_cast<TabDecorator::Tab*>(_tab); Decorator::Tab* tab = static_cast<Decorator::Tab*>(_tab);
float offset; float offset;
float size; float size;
@@ -1200,7 +992,7 @@ TabDecorator::_SingleTabOffsetAndSize(float& tabSize)
} else { } else {
tabSize = fBottomBorder.bottom - fTopBorder.top; tabSize = fBottomBorder.bottom - fTopBorder.top;
} }
TabDecorator::Tab* tab = _TabAt(0); Decorator::Tab* tab = _TabAt(0);
maxLocation = tabSize - tab->maxTabSize; maxLocation = tabSize - tab->maxTabSize;
if (maxLocation < 0) if (maxLocation < 0)
maxLocation = 0; maxLocation = 0;
+6 -66
View File
@@ -21,33 +21,10 @@
class Desktop; class Desktop;
class ServerBitmap;
class TabDecorator: public Decorator { class TabDecorator: public Decorator {
public: public:
class Tab : public TabDecorator::Tab {
public:
Tab();
uint32 tabOffset;
float tabLocation;
float textOffset;
BString truncatedTitle;
int32 truncatedTitleLength;
bool buttonFocus : 1;
bool isHighlighted : 1;
float minTabSize;
float maxTabSize;
ServerBitmap* closeBitmaps[4];
ServerBitmap* zoomBitmaps[4];
};
TabDecorator(DesktopSettings& settings, TabDecorator(DesktopSettings& settings,
BRect frame); BRect frame);
virtual ~TabDecorator(); virtual ~TabDecorator();
@@ -85,39 +62,25 @@ protected:
typedef rgb_color ComponentColors[7]; typedef rgb_color ComponentColors[7];
public: public:
virtual float TabLocation(int32 tab) const; virtual void Draw(BRect updateRect);
virtual void Draw();
virtual bool GetSettings(BMessage* settings) const;
virtual void Draw(BRect updateRect) = 0;
virtual void Draw() = 0;
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
int32* maxWidth, int32* maxHeight) const;
virtual Region RegionAt(BPoint where, int32& tab) const; virtual Region RegionAt(BPoint where, int32& tab) const;
virtual void ExtendDirtyRegion(Region region,
BRegion& dirty);
virtual bool SetRegionHighlight(Region region, virtual bool SetRegionHighlight(Region region,
uint8 highlight, BRegion* dirty, uint8 highlight, BRegion* dirty,
int32 tab = -1); int32 tab = -1);
float BorderWidth();
float TabHeight();
protected: protected:
virtual void _DoLayout(); virtual void _DoLayout();
virtual void _DoTabLayout(); virtual void _DoTabLayout();
void _DistributeTabSize(float delta); void _DistributeTabSize(float delta);
virtual Decorator::Tab* _AllocateNewTab(); virtual void _DrawFrame(BRect rect) = 0;
TabDecorator::Tab* _TabAt(int32 index) const;
virtual void _DrawFrame(BRect r) = 0;
virtual void _DrawTab(Decorator::Tab* tab, BRect r) = 0; virtual void _DrawTab(Decorator::Tab* tab, BRect r) = 0;
virtual void _DrawButtons(Decorator::Tab* tab,
const BRect& invalid);
virtual void _DrawClose(Decorator::Tab* tab, bool direct, virtual void _DrawClose(Decorator::Tab* tab, bool direct,
BRect r) = 0; BRect r) = 0;
virtual void _DrawTitle(Decorator::Tab* tab, BRect r) = 0; virtual void _DrawTitle(Decorator::Tab* tab, BRect r) = 0;
@@ -127,19 +90,11 @@ protected:
virtual void _SetTitle(Decorator::Tab* tab, virtual void _SetTitle(Decorator::Tab* tab,
const char* string, const char* string,
BRegion* updateRegion = NULL); BRegion* updateRegion = NULL);
virtual void _SetFocus(Decorator::Tab* tab);
virtual void _FontsChanged(DesktopSettings& settings,
BRegion* updateRegion);
virtual void _SetLook(Decorator::Tab* tab,
DesktopSettings& settings, window_look look,
BRegion* updateRegion = NULL);
virtual void _SetFlags(Decorator::Tab* tab, uint32 flags,
BRegion* updateRegion = NULL);
virtual void _MoveBy(BPoint offset); virtual void _MoveBy(BPoint offset);
virtual void _ResizeBy(BPoint offset, BRegion* dirty); virtual void _ResizeBy(BPoint offset, BRegion* dirty);
virtual void _SetFocus(Decorator::Tab* tab);
virtual bool _SetTabLocation(Decorator::Tab* tab, virtual bool _SetTabLocation(Decorator::Tab* tab,
float location, bool isShifting, float location, bool isShifting,
BRegion* updateRegion = NULL); BRegion* updateRegion = NULL);
@@ -160,12 +115,6 @@ protected:
virtual void _GetButtonSizeAndOffset(const BRect& tabRect, virtual void _GetButtonSizeAndOffset(const BRect& tabRect,
float* offset, float* size, float* offset, float* size,
float* inset) const; float* inset) const;
virtual void _InvalidateBitmaps();
// TabDecorator customization points
virtual void DrawButtons(Decorator::Tab* tab,
const BRect& invalid);
virtual void _UpdateFont(DesktopSettings& settings); virtual void _UpdateFont(DesktopSettings& settings);
@@ -180,15 +129,6 @@ protected:
void _CalculateTabsRegion(); void _CalculateTabsRegion();
protected: protected:
// Individual rects for handling window frame
// rendering the proper way
BRect fRightBorder;
BRect fLeftBorder;
BRect fTopBorder;
BRect fBottomBorder;
int32 fBorderWidth;
BRegion fTabsRegion; BRegion fTabsRegion;
BRect fOldMovingTab; BRect fOldMovingTab;