diff --git a/src/add-ons/decorators/BeDecorator/BeDecorator.cpp b/src/add-ons/decorators/BeDecorator/BeDecorator.cpp index cf5cb3b5a8..1c2ee18426 100644 --- a/src/add-ons/decorators/BeDecorator/BeDecorator.cpp +++ b/src/add-ons/decorators/BeDecorator/BeDecorator.cpp @@ -34,7 +34,6 @@ #include "DrawState.h" #include "FontManager.h" #include "PatternHandler.h" -#include "RGBColor.h" #include "ServerBitmap.h" @@ -46,18 +45,6 @@ #endif -BeDecorator::Tab::Tab() - : - tabOffset(0), - tabLocation(0.0), - isHighlighted(false) -{ - 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 kResizeKnobSize = 18.0; @@ -76,10 +63,9 @@ blend_color_value(uint8 a, uint8 b, float position) } -/*! - \brief Function mostly for calculating gradient colors - \param col Start color - \param col2 End color +/*! \brief Function for calculating gradient colors + \param colorA Start color + \param colorB End color \param position A floating point number such that 0.0 <= position <= 1.0. 0.0 results in the start color and 1.0 results in the end color. \return The blended color. If an invalid position was given, {0,0,0,0} is returned. @@ -109,7 +95,6 @@ BeDecorAddOn::BeDecorAddOn(image_id id, const char* name) : DecorAddOn(id, name) { - } @@ -122,33 +107,17 @@ BeDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect) // TODO: get rid of DesktopSettings here, and introduce private accessor // methods to the Decorator base class - BeDecorator::BeDecorator(DesktopSettings& settings, BRect rect) : - Decorator(settings, rect), - fTabOffset(0), - fWasDoubleClick(false) + TabDecorator(settings, rect) { - fFrameColors = new RGBColor[6]; - fFrameColors[0].SetColor(152, 152, 152); - fFrameColors[1].SetColor(255, 255, 255); - fFrameColors[2].SetColor(ui_color(B_MENU_BACKGROUND_COLOR)); - fFrameColors[3].SetColor(136, 136, 136); - fFrameColors[4].SetColor(152, 152, 152); - fFrameColors[5].SetColor(96, 96, 96); - - fTabColor.SetColor(ui_color(B_WINDOW_TAB_COLOR)); - fTextColor.SetColor(ui_color(B_WINDOW_TEXT_COLOR)); - - fButtonHighColor.SetColor(tint_color(fTabColor.GetColor32(), - B_LIGHTEN_2_TINT)); - fButtonLowColor.SetColor(tint_color(fTabColor.GetColor32(), - B_DARKEN_2_TINT)); - - //_UpdateFont(settings); - - // TODO: If the decorator was created with a frame too small, it should - // resize itself! + //fFrameColors = new RGBColor[6]; + //fFrameColors[0].SetColor(152, 152, 152); + //fFrameColors[1].SetColor(255, 255, 255); + //fFrameColors[2].SetColor(216, 216, 216); + //fFrameColors[3].SetColor(136, 136, 136); + //fFrameColors[4].SetColor(152, 152, 152); + //fFrameColors[5].SetColor(96, 96, 96); STRACE(("BeDecorator:\n")); STRACE(("\tFrame (%.1f,%.1f,%.1f,%.1f)\n", @@ -159,46 +128,11 @@ BeDecorator::BeDecorator(DesktopSettings& settings, BRect rect) BeDecorator::~BeDecorator() { STRACE(("BeDecorator: ~BeDecorator()\n")); - delete [] fFrameColors; + //delete[] fFrameColors; } -float -BeDecorator::TabLocation(int32 tab) const -{ - BeDecorator::Tab* decoratorTab = _TabAt(tab); - if (decoratorTab == NULL) - return 0.0f; - - return (float)decoratorTab->tabOffset; -} - - -bool -BeDecorator::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++) { - BeDecorator::Tab* tab = _TabAt(i); - if (settings->AddFloat("tab location", (float)tab->tabOffset) != B_OK) - return false; - } - - return true; -} - - -// #pragma mark - +// #pragma mark - Public methods /*! \brief Updates the decorator in the rectangular area \a updateRect. @@ -234,340 +168,7 @@ BeDecorator::Draw() } -void -BeDecorator::GetSizeLimits(int32* minWidth, int32* minHeight, - int32* maxWidth, int32* maxHeight) const -{ - float minTabSize = 0; - if (CountTabs() > 0) - minTabSize = _TabAt(0)->minTabSize; - if (fTitleBarRect.IsValid()) { - *minWidth = (int32)roundf(max_c(*minWidth, - minTabSize - 2 * fBorderWidth)); - } - if (fResizeRect.IsValid()) { - *minHeight = (int32)roundf(max_c(*minHeight, - fResizeRect.Height() - fBorderWidth)); - } -} - - -Decorator::Region -BeDecorator::RegionAt(BPoint where, int32& tab) const -{ - // Let the base class version identify hits of the buttons and the tab. - Region region = Decorator::RegionAt(where, tab); - if (region != REGION_NONE) - return region; - - // check the resize corner - if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where)) - return REGION_RIGHT_BOTTOM_CORNER; - - // hit-test the borders - if (fLeftBorder.Contains(where)) - return REGION_LEFT_BORDER; - if (fTopBorder.Contains(where)) - return REGION_TOP_BORDER; - - // Part of the bottom and right borders may be a resize-region, so we have - // to check explicitly, if it has been it. - if (fRightBorder.Contains(where)) - region = REGION_RIGHT_BORDER; - else if (fBottomBorder.Contains(where)) - region = REGION_BOTTOM_BORDER; - else - return REGION_NONE; - - // check resize area - if ((fTopTab->flags & B_NOT_RESIZABLE) == 0 - && (fTopTab->look == B_TITLED_WINDOW_LOOK - || fTopTab->look == B_FLOATING_WINDOW_LOOK - || fTopTab->look == B_MODAL_WINDOW_LOOK - || fTopTab->look == kLeftTitledWindowLook)) { - BRect resizeRect(BPoint(fBottomBorder.right - kBorderResizeLength, - fBottomBorder.bottom - kBorderResizeLength), - fBottomBorder.RightBottom()); - if (resizeRect.Contains(where)) - return REGION_RIGHT_BOTTOM_CORNER; - } - - return region; -} - - -void -BeDecorator::_DoLayout() -{ - STRACE(("BeDecorator: Do Layout\n")); - // Here we determine the size of every rectangle that we use - // internally when we are given the size of the client rectangle. - - bool hasTab = false; - - switch ((int)fTopTab->look) { - case B_MODAL_WINDOW_LOOK: - fBorderWidth = 5; - break; - - case B_TITLED_WINDOW_LOOK: - case B_DOCUMENT_WINDOW_LOOK: - hasTab = true; - fBorderWidth = 5; - break; - case B_FLOATING_WINDOW_LOOK: - case kLeftTitledWindowLook: - hasTab = true; - fBorderWidth = 3; - break; - - case B_BORDERED_WINDOW_LOOK: - fBorderWidth = 1; - break; - - default: - fBorderWidth = 0; - } - - // calculate left/top/right/bottom borders - if (fBorderWidth > 0) { - // NOTE: no overlapping, the left and right border rects - // don't include the corners! - fLeftBorder.Set(fFrame.left - fBorderWidth, fFrame.top, - fFrame.left - 1, fFrame.bottom); - - fRightBorder.Set(fFrame.right + 1, fFrame.top , - fFrame.right + fBorderWidth, fFrame.bottom); - - fTopBorder.Set(fFrame.left - fBorderWidth, fFrame.top - fBorderWidth, - fFrame.right + fBorderWidth, fFrame.top - 1); - - fBottomBorder.Set(fFrame.left - fBorderWidth, fFrame.bottom + 1, - fFrame.right + fBorderWidth, fFrame.bottom + fBorderWidth); - } else { - // no border - fLeftBorder.Set(0.0, 0.0, -1.0, -1.0); - fRightBorder.Set(0.0, 0.0, -1.0, -1.0); - fTopBorder.Set(0.0, 0.0, -1.0, -1.0); - fBottomBorder.Set(0.0, 0.0, -1.0, -1.0); - } - - // calculate resize rect - if (fBorderWidth > 1) { - fResizeRect.Set(fBottomBorder.right - kResizeKnobSize, - fBottomBorder.bottom - kResizeKnobSize, fBottomBorder.right, - fBottomBorder.bottom); - } else { - // no border or one pixel border (menus and such) - fResizeRect.Set(0, 0, -1, -1); - } - - if (hasTab) { - _DoTabLayout(); - return; - } else { - // no tab - for (int32 i = 0; i < fTabList.CountItems(); i++) { - Decorator::Tab* tab = fTabList.ItemAt(i); - tab->tabRect.Set(0.0, 0.0, -1.0, -1.0); - } - fTabsRegion.MakeEmpty(); - fTitleBarRect.Set(0.0, 0.0, -1.0, -1.0); - } -} - - -void -BeDecorator::_DoTabLayout() -{ - float tabOffset = 0; - if (fTabList.CountItems() == 1) { - float tabSize; - tabOffset = _SingleTabOffsetAndSize(tabSize); - } - - float sumTabWidth = 0; - // calculate our tab rect - for (int32 i = 0; i < fTabList.CountItems(); i++) { - BeDecorator::Tab* tab = _TabAt(i); - - BRect& tabRect = tab->tabRect; - // distance from one item of the tab bar to another. - // In this case the text and close/zoom rects - tab->textOffset = _DefaultTextOffset(); - - font_height fontHeight; - fDrawState.Font().GetHeight(fontHeight); - - if (tab->look != kLeftTitledWindowLook) { - tabRect.Set(fFrame.left - fBorderWidth, - fFrame.top - fBorderWidth - - ceilf(fontHeight.ascent + fontHeight.descent + 7.0), - ((fFrame.right - fFrame.left) < 35.0 ? - fFrame.left + 35.0 : fFrame.right) + fBorderWidth, - fFrame.top - fBorderWidth); - } else { - tabRect.Set(fFrame.left - fBorderWidth - - ceilf(fontHeight.ascent + fontHeight.descent + 5.0), - fFrame.top - fBorderWidth, fFrame.left - fBorderWidth, - fFrame.bottom + fBorderWidth); - } - - // format tab rect for a floating window - make the rect smaller - if (tab->look == B_FLOATING_WINDOW_LOOK) { - tabRect.InsetBy(0, 2); - tabRect.OffsetBy(0, 2); - } - - float offset; - float size; - float inset; - _GetButtonSizeAndOffset(tabRect, &offset, &size, &inset); - - // tab->minTabSize contains just the room for the buttons - tab->minTabSize = inset * 2 + tab->textOffset; - if ((tab->flags & B_NOT_CLOSABLE) == 0) - tab->minTabSize += offset + size; - if ((tab->flags & B_NOT_ZOOMABLE) == 0) - tab->minTabSize += offset + size; - - // tab->maxTabSize contains tab->minTabSize + the width required for the - // title - tab->maxTabSize = fDrawingEngine - ? ceilf(fDrawingEngine->StringWidth(Title(tab), strlen(Title(tab)), - fDrawState.Font())) : 0.0; - if (tab->maxTabSize > 0.0) - tab->maxTabSize += tab->textOffset; - tab->maxTabSize += tab->minTabSize; - - float tabSize = (tab->look != kLeftTitledWindowLook - ? fFrame.Width() : fFrame.Height()) + fBorderWidth * 2; - if (tabSize < tab->minTabSize) - tabSize = tab->minTabSize; - if (tabSize > tab->maxTabSize) - tabSize = tab->maxTabSize; - - // layout buttons and truncate text - if (tab->look != kLeftTitledWindowLook) - tabRect.right = tabRect.left + tabSize; - else - tabRect.bottom = tabRect.top + tabSize; - - // make sure fTabOffset is within limits and apply it to - // the tabRect - tab->tabOffset = (uint32)tabOffset; - if (tab->tabLocation != 0.0 && fTabList.CountItems() == 1 - && tab->tabOffset > (fRightBorder.right - fLeftBorder.left - - tabRect.Width())) { - tab->tabOffset = uint32(fRightBorder.right - fLeftBorder.left - - tabRect.Width()); - } - tabRect.OffsetBy(tab->tabOffset, 0); - tabOffset += tabRect.Width(); - - sumTabWidth += tabRect.Width(); - } - - float windowWidth = fFrame.Width() + 2 * fBorderWidth; - if (CountTabs() > 1 && sumTabWidth > windowWidth) - _DistributeTabSize(sumTabWidth - windowWidth); - - // finally, layout the buttons and text within the tab rect - for (int32 i = 0; i < fTabList.CountItems(); i++) { - Decorator::Tab* tab = fTabList.ItemAt(i); - - if (i == 0) - fTitleBarRect = tab->tabRect; - else - fTitleBarRect = fTitleBarRect | tab->tabRect; - - _LayoutTabItems(tab, tab->tabRect); - } - fTabsRegion = fTitleBarRect; -} - - -static bool -int_equal(float x, float y) -{ - return abs(x - y) <= 1; -} - - -void -BeDecorator::_DistributeTabSize(float delta) -{ - ASSERT(CountTabs() > 1); - - float maxTabSize = 0; - float secMaxTabSize = 0; - int32 nTabsWithMaxSize = 0; - for (int32 i = 0; i < fTabList.CountItems(); i++) { - Decorator::Tab* tab = fTabList.ItemAt(i); - float tabWidth = tab->tabRect.Width(); - if (int_equal(maxTabSize, tabWidth)) { - nTabsWithMaxSize++; - continue; - } - if (maxTabSize < tabWidth) { - secMaxTabSize = maxTabSize; - maxTabSize = tabWidth; - nTabsWithMaxSize = 1; - } else if (secMaxTabSize <= tabWidth) - secMaxTabSize = tabWidth; - } - - float minus = ceil(std::min(maxTabSize - secMaxTabSize, delta)); - delta -= minus; - minus /= nTabsWithMaxSize; - - Decorator::Tab* prevTab = NULL; - for (int32 i = 0; i < fTabList.CountItems(); i++) { - Decorator::Tab* tab = fTabList.ItemAt(i); - if (int_equal(maxTabSize, tab->tabRect.Width())) - tab->tabRect.right -= minus; - - if (prevTab) { - tab->tabRect.OffsetBy(prevTab->tabRect.right - tab->tabRect.left, - 0); - } - - prevTab = tab; - } - - if (delta > 0) { - _DistributeTabSize(delta); - return; - } - - // done - prevTab->tabRect.right = floor(fFrame.right + fBorderWidth); - - for (int32 i = 0; i < fTabList.CountItems(); i++) { - BeDecorator::Tab* tab = _TabAt(i); - tab->tabOffset = uint32(tab->tabRect.left - fLeftBorder.left); - } -} - - -Decorator::Tab* -BeDecorator::_AllocateNewTab() -{ - Decorator::Tab* tab = new(std::nothrow) BeDecorator::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; -} - - -BeDecorator::Tab* -BeDecorator::_TabAt(int32 index) const -{ - return static_cast(fTabList.ItemAt(index)); -} +// #pragma mark - Protected methods void @@ -594,9 +195,12 @@ BeDecorator::_DrawFrame(BRect invalid) { // top if (invalid.Intersects(fTopBorder)) { + ComponentColors colors; + _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); + for (int8 i = 0; i < 5; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), fFrameColors[i]); + BPoint(r.right - i, r.top + i), colors[i]); } if (fTitleBarRect.IsValid()) { // grey along the bottom of the tab @@ -606,30 +210,39 @@ BeDecorator::_DrawFrame(BRect invalid) fTitleBarRect.bottom + 1), BPoint(fTitleBarRect.right - 2, fTitleBarRect.bottom + 1), - fFrameColors[2]); + colors[2]); } } // left - if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) { + if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -BorderWidth()))) { + ComponentColors colors; + _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); + for (int8 i = 0; i < 5; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), fFrameColors[i]); + BPoint(r.left + i, r.bottom - i), colors[i]); } } // bottom if (invalid.Intersects(fBottomBorder)) { + ComponentColors colors; + _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); + for (int8 i = 0; i < 5; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), BPoint(r.right - i, r.bottom - i), - fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + colors[(4 - i) == 4 ? 5 : (4 - i)]); } } // right - if (invalid.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) { + if (invalid.Intersects(fRightBorder.InsetByCopy(0, -BorderWidth()))) { + ComponentColors colors; + _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); + for (int8 i = 0; i < 5; i++) { fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), BPoint(r.right - i, r.bottom - i), - fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + colors[(4 - i) == 4 ? 5 : (4 - i)]); } } break; @@ -640,9 +253,12 @@ BeDecorator::_DrawFrame(BRect invalid) { // top if (invalid.Intersects(fTopBorder)) { + ComponentColors colors; + _GetComponentColors(COMPONENT_TOP_BORDER, colors, fTopTab); + for (int8 i = 0; i < 3; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), fFrameColors[i * 2]); + BPoint(r.right - i, r.top + i), colors[i * 2]); } if (fTitleBarRect.IsValid() && fTopTab->look != kLeftTitledWindowLook) { // grey along the bottom of the tab @@ -651,14 +267,17 @@ BeDecorator::_DrawFrame(BRect invalid) BPoint(fTitleBarRect.left + 2, fTitleBarRect.bottom + 1), BPoint(fTitleBarRect.right - 2, - fTitleBarRect.bottom + 1), fFrameColors[2]); + fTitleBarRect.bottom + 1), colors[2]); } } // left - if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -fBorderWidth))) { + if (invalid.Intersects(fLeftBorder.InsetByCopy(0, -BorderWidth()))) { + ComponentColors colors; + _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); + for (int8 i = 0; i < 3; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), fFrameColors[i * 2]); + BPoint(r.left + i, r.bottom - i), colors[i * 2]); } if (fTopTab->look == kLeftTitledWindowLook && fTitleBarRect.IsValid()) { @@ -668,23 +287,29 @@ BeDecorator::_DrawFrame(BRect invalid) BPoint(fTitleBarRect.right + 1, fTitleBarRect.top + 2), BPoint(fTitleBarRect.right + 1, - fTitleBarRect.bottom - 2), fFrameColors[2]); + fTitleBarRect.bottom - 2), colors[2]); } } // bottom if (invalid.Intersects(fBottomBorder)) { + ComponentColors colors; + _GetComponentColors(COMPONENT_BOTTOM_BORDER, colors, fTopTab); + for (int8 i = 0; i < 3; i++) { fDrawingEngine->StrokeLine(BPoint(r.left + i, r.bottom - i), BPoint(r.right - i, r.bottom - i), - fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + colors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } } // right - if (invalid.Intersects(fRightBorder.InsetByCopy(0, -fBorderWidth))) { + if (invalid.Intersects(fRightBorder.InsetByCopy(0, -BorderWidth()))) { + ComponentColors colors; + _GetComponentColors(COMPONENT_RIGHT_BORDER, colors, fTopTab); + for (int8 i = 0; i < 3; i++) { fDrawingEngine->StrokeLine(BPoint(r.right - i, r.top + i), BPoint(r.right - i, r.bottom - i), - fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + colors[(2 - i) == 2 ? 5 : (2 - i) * 2]); } } break; @@ -693,7 +318,10 @@ BeDecorator::_DrawFrame(BRect invalid) case B_BORDERED_WINDOW_LOOK: { // TODO: Draw the borders individually! - fDrawingEngine->StrokeRect(r, fFrameColors[5]); + ComponentColors colors; + _GetComponentColors(COMPONENT_LEFT_BORDER, colors, fTopTab); + + fDrawingEngine->StrokeRect(r, colors[5]); break; } @@ -706,6 +334,9 @@ BeDecorator::_DrawFrame(BRect invalid) if (!(fTopTab->flags & B_NOT_RESIZABLE)) { r = fResizeRect; + ComponentColors colors; + _GetComponentColors(COMPONENT_RESIZE_CORNER, colors, fTopTab); + switch ((int)fTopTab->look) { case B_DOCUMENT_WINDOW_LOOK: { @@ -715,27 +346,36 @@ BeDecorator::_DrawFrame(BRect invalid) float x = r.right - 3; float y = r.bottom - 3; - fDrawingEngine->FillRect(BRect(x - 13, y - 13, x, y), - fFrameColors[2]); + BRect bg(x - 13, y - 13, x, y); + + BGradientLinear gradient; + gradient.SetStart(bg.LeftTop()); + gradient.SetEnd(bg.RightBottom()); + gradient.AddColor(colors[1], 0); + gradient.AddColor(colors[2], 255); + + fDrawingEngine->FillRect(bg, gradient); fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), - BPoint(x - 15, y - 2), fFrameColors[0]); + BPoint(x - 15, y - 2), colors[0]); fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), - BPoint(x - 14, y - 1), fFrameColors[1]); + BPoint(x - 14, y - 1), colors[1]); fDrawingEngine->StrokeLine(BPoint(x - 15, y - 15), - BPoint(x - 2, y - 15), fFrameColors[0]); + BPoint(x - 2, y - 15), colors[0]); fDrawingEngine->StrokeLine(BPoint(x - 14, y - 14), - BPoint(x - 1, y - 14), fFrameColors[1]); + BPoint(x - 1, y - 14), colors[1]); - if (!IsFocus(fTopTab)) + if (fTopTab && !IsFocus(fTopTab)) break; + static const rgb_color kWhite + = (rgb_color){ 255, 255, 255, 255 }; for (int8 i = 1; i <= 4; i++) { for (int8 j = 1; j <= i; j++) { BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1); BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2); - fDrawingEngine->StrokePoint(pt1, fFrameColors[0]); - fDrawingEngine->StrokePoint(pt2, fFrameColors[1]); + fDrawingEngine->StrokePoint(pt1, colors[0]); + fDrawingEngine->StrokePoint(pt2, kWhite); } } break; @@ -754,11 +394,11 @@ BeDecorator::_DrawFrame(BRect invalid) fDrawingEngine->StrokeLine( BPoint(fRightBorder.left, fBottomBorder.bottom - kBorderResizeLength), BPoint(fRightBorder.right - 1, fBottomBorder.bottom - kBorderResizeLength), - fFrameColors[0]); + colors[0]); fDrawingEngine->StrokeLine( BPoint(fRightBorder.right - kBorderResizeLength, fBottomBorder.top), BPoint(fRightBorder.right - kBorderResizeLength, fBottomBorder.bottom - 1), - fFrameColors[0]); + colors[0]); break; } @@ -781,54 +421,54 @@ BeDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid) if (!tabRect.IsValid() || !invalid.Intersects(tabRect)) return; - if (fBorderWidth <= 0) - return; - - // TODO: cache these - RGBColor tabColorLight = RGBColor(tint_color(fTabColor.GetColor32(), - B_LIGHTEN_2_TINT)); - RGBColor tabColorShadow = RGBColor(tint_color(fTabColor.GetColor32(), - B_DARKEN_2_TINT)); + ComponentColors colors; + _GetComponentColors(COMPONENT_TAB, colors, tab); // outer frame fDrawingEngine->StrokeLine(tabRect.LeftTop(), tabRect.LeftBottom(), - fFrameColors[0]); + colors[COLOR_TAB_FRAME_LIGHT]); fDrawingEngine->StrokeLine(tabRect.LeftTop(), tabRect.RightTop(), - fFrameColors[0]); - if (fTopTab->look != kLeftTitledWindowLook) { + colors[COLOR_TAB_FRAME_LIGHT]); + if (tab->look != kLeftTitledWindowLook) { fDrawingEngine->StrokeLine(tabRect.RightTop(), tabRect.RightBottom(), - fFrameColors[5]); + colors[COLOR_TAB_FRAME_DARK]); } else { fDrawingEngine->StrokeLine(tabRect.LeftBottom(), - tabRect.RightBottom(), fFrameColors[5]); + tabRect.RightBottom(), colors[COLOR_TAB_FRAME_DARK]); } + float tabBotton = tabRect.bottom; + if (fTopTab != tab) + tabBotton -= 1; + // bevel fDrawingEngine->StrokeLine(BPoint(tabRect.left + 1, tabRect.top + 1), BPoint(tabRect.left + 1, - tabRect.bottom - (fTopTab->look == kLeftTitledWindowLook ? 1 : 0)), - tabColorLight); + tabBotton - (tab->look == kLeftTitledWindowLook ? 1 : 0)), + colors[COLOR_TAB_BEVEL]); fDrawingEngine->StrokeLine(BPoint(tabRect.left + 1, tabRect.top + 1), - BPoint(tabRect.right - (fTopTab->look == kLeftTitledWindowLook ? 0 : 1), + BPoint(tabRect.right - (tab->look == kLeftTitledWindowLook ? 0 : 1), tabRect.top + 1), - tabColorLight); + colors[COLOR_TAB_BEVEL]); - if (fTopTab->look != kLeftTitledWindowLook) { + if (tab->look != kLeftTitledWindowLook) { fDrawingEngine->StrokeLine(BPoint(tabRect.right - 1, tabRect.top + 2), - BPoint(tabRect.right - 1, tabRect.bottom), tabColorShadow); + BPoint(tabRect.right - 1, tabBotton), + colors[COLOR_TAB_SHADOW]); } else { fDrawingEngine->StrokeLine( BPoint(tabRect.left + 2, tabRect.bottom - 1), - BPoint(tabRect.right, tabRect.bottom - 1), tabColorShadow); + BPoint(tabRect.right, tabRect.bottom - 1), + colors[COLOR_TAB_SHADOW]); } // fill if (fTopTab->look != kLeftTitledWindowLook) { fDrawingEngine->FillRect(BRect(tabRect.left + 2, tabRect.top + 2, - tabRect.right - 2, tabRect.bottom), fTabColor); + tabRect.right - 2, tabRect.bottom), colors[COLOR_TAB]); } else { fDrawingEngine->FillRect(BRect(tabRect.left + 2, tabRect.top + 2, - tabRect.right, tabRect.bottom - 2), fTabColor); + tabRect.right, tabRect.bottom - 2), colors[COLOR_TAB]); } _DrawTitle(tab, tabRect); @@ -837,20 +477,33 @@ BeDecorator::_DrawTab(Decorator::Tab* tab, BRect invalid) } +void +BeDecorator::_DrawClose(Decorator::Tab* tab, bool direct, BRect rect) +{ + STRACE(("_DrawClose(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right, + rect.bottom)); + // Just like DrawZoom, but for a close button + _DrawBlendedRect(tab, rect, tab->closePressed); +} + + void BeDecorator::_DrawTitle(Decorator::Tab* _tab, BRect r) { STRACE(("_DrawTitle(%f, %f, %f, %f)\n", r.left, r.top, r.right, r.bottom)); - BeDecorator::Tab* tab = static_cast(_tab); + TabDecorator::Tab* tab = static_cast(_tab); const BRect& tabRect = tab->tabRect; const BRect& closeRect = tab->closeRect; const BRect& zoomRect = tab->zoomRect; + ComponentColors colors; + _GetComponentColors(COMPONENT_TAB, colors, tab); + fDrawingEngine->SetDrawingMode(B_OP_OVER); - fDrawingEngine->SetHighColor(fTextColor); - fDrawingEngine->SetLowColor(fTabColor); + fDrawingEngine->SetHighColor(ui_color(B_WINDOW_TEXT_COLOR)); + fDrawingEngine->SetLowColor(colors[COLOR_TAB]); fDrawingEngine->SetFont(fDrawState.Font()); // figure out position of text @@ -881,16 +534,6 @@ BeDecorator::_DrawTitle(Decorator::Tab* _tab, BRect r) } -void -BeDecorator::_DrawClose(Decorator::Tab* tab, bool direct, BRect rect) -{ - STRACE(("_DrawClose(%f,%f,%f,%f)\n", rect.left, rect.top, rect.right, - rect.bottom)); - // Just like DrawZoom, but for a close button - _DrawBlendedRect(rect, true); -} - - void BeDecorator::_DrawZoom(Decorator::Tab* tab, bool direct, BRect rect) { @@ -899,489 +542,29 @@ BeDecorator::_DrawZoom(Decorator::Tab* tab, bool direct, BRect rect) // If this has been implemented, then the decorator has a Zoom button // which should be drawn based on the state of the member zoomstate - BRect zr(rect); - zr.left += 3.0; - zr.top += 3.0; - _DrawBlendedRect(zr, true); - - zr = rect; - zr.right -= 5.0; - zr.bottom -= 5.0; - _DrawBlendedRect(zr, true); -} - - -void -BeDecorator::_SetTitle(Decorator::Tab* tab, const char* string, - BRegion* updateRegion) -{ - // TODO: we could be much smarter about the update region - - BRect rect = TabRect(tab); - - _DoLayout(); - - if (updateRegion == NULL) - return; - - rect = rect | TabRect(tab); - - rect.bottom++; - // the border will look differently when the title is adjacent - - updateRegion->Include(rect); -} - - -void -BeDecorator::_FontsChanged(DesktopSettings& settings, - BRegion* updateRegion) -{ - // get previous extent - if (updateRegion != NULL) - updateRegion->Include(&GetFootprint()); - - _UpdateFont(settings); - _DoLayout(); - - _InvalidateFootprint(); - if (updateRegion != NULL) - updateRegion->Include(&GetFootprint()); -} - - -void -BeDecorator::_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); - _InvalidateBitmaps(); - _DoLayout(); - - _InvalidateFootprint(); - if (updateRegion != NULL) - updateRegion->Include(&GetFootprint()); -} - - -void -BeDecorator::_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 -BeDecorator::_SetFocus(Decorator::Tab* _tab) -{ - BeDecorator::Tab* tab = static_cast(_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 -BeDecorator::_MoveBy(BPoint offset) -{ - STRACE(("BeDecorator: Move By (%.1f, %.1f)\n", offset.x, offset.y)); - // Move all internal rectangles the appropriate amount - for (int32 i = 0; i < fTabList.CountItems(); i++) { - Decorator::Tab* tab = fTabList.ItemAt(i); - - tab->zoomRect.OffsetBy(offset); - tab->closeRect.OffsetBy(offset); - tab->tabRect.OffsetBy(offset); - } - fFrame.OffsetBy(offset); - fTitleBarRect.OffsetBy(offset); - fTabsRegion.OffsetBy(offset); - fResizeRect.OffsetBy(offset); - fBorderRect.OffsetBy(offset); - - fLeftBorder.OffsetBy(offset); - fRightBorder.OffsetBy(offset); - fTopBorder.OffsetBy(offset); - fBottomBorder.OffsetBy(offset); -} - - -void -BeDecorator::_ResizeBy(BPoint offset, BRegion* dirty) -{ - STRACE(("BeDecorator: Resize By (%.1f, %.1f)\n", offset.x, offset.y)); - // Move all internal rectangles the appropriate amount - fFrame.right += offset.x; - fFrame.bottom += offset.y; - - // Handle invalidation of resize rect - if (dirty && !(fTopTab->flags & B_NOT_RESIZABLE)) { - BRect realResizeRect; - switch ((int)fTopTab->look) { - case B_DOCUMENT_WINDOW_LOOK: - realResizeRect = fResizeRect; - // Resize rect at old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // Resize rect at new location - dirty->Include(realResizeRect); - break; - case B_TITLED_WINDOW_LOOK: - case B_FLOATING_WINDOW_LOOK: - case B_MODAL_WINDOW_LOOK: - case kLeftTitledWindowLook: - // The bottom border resize line - realResizeRect.Set(fRightBorder.right - kBorderResizeLength, - fBottomBorder.top, fRightBorder.right - kBorderResizeLength, - fBottomBorder.bottom - 1); - // Old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // New location - dirty->Include(realResizeRect); - - // The right border resize line - realResizeRect.Set(fRightBorder.left, - fBottomBorder.bottom - kBorderResizeLength, fRightBorder.right - 1, - fBottomBorder.bottom - kBorderResizeLength); - // Old location - dirty->Include(realResizeRect); - realResizeRect.OffsetBy(offset); - // New location - dirty->Include(realResizeRect); - break; - default: - break; - } - } - - fResizeRect.OffsetBy(offset); - - fBorderRect.right += offset.x; - fBorderRect.bottom += offset.y; - - fLeftBorder.bottom += offset.y; - fTopBorder.right += offset.x; - - fRightBorder.OffsetBy(offset.x, 0.0); - fRightBorder.bottom += offset.y; - - fBottomBorder.OffsetBy(0.0, offset.y); - fBottomBorder.right += offset.x; - - if (dirty) { - if (offset.x > 0.0) { - BRect t(fRightBorder.left - offset.x, fTopBorder.top, - fRightBorder.right, fTopBorder.bottom); - dirty->Include(t); - t.Set(fRightBorder.left - offset.x, fBottomBorder.top, - fRightBorder.right, fBottomBorder.bottom); - dirty->Include(t); - dirty->Include(fRightBorder); - } else if (offset.x < 0.0) { - dirty->Include(BRect(fRightBorder.left, fTopBorder.top, - fRightBorder.right, fBottomBorder.bottom)); - } - if (offset.y > 0.0) { - BRect t(fLeftBorder.left, fLeftBorder.bottom - offset.y, - fLeftBorder.right, fLeftBorder.bottom); - dirty->Include(t); - t.Set(fRightBorder.left, fRightBorder.bottom - offset.y, - fRightBorder.right, fRightBorder.bottom); - dirty->Include(t); - dirty->Include(fBottomBorder); - } else if (offset.y < 0.0) { - dirty->Include(fBottomBorder); - } - } - - // resize tab and layout tab items - if (fTitleBarRect.IsValid()) { - if (fTabList.CountItems() > 1) { - _DoTabLayout(); - if (dirty != NULL) - dirty->Include(fTitleBarRect); - return; - } - - BeDecorator::Tab* tab = _TabAt(0); - BRect& tabRect = tab->tabRect; - BRect oldTabRect(tabRect); - - float tabSize; - float tabOffset = _SingleTabOffsetAndSize(tabSize); - - float delta = tabOffset - tab->tabOffset; - tab->tabOffset = (uint32)tabOffset; - if (fTopTab->look != kLeftTitledWindowLook) - tabRect.OffsetBy(delta, 0.0); - else - tabRect.OffsetBy(0.0, delta); - - if (tabSize < tab->minTabSize) - tabSize = tab->minTabSize; - if (tabSize > tab->maxTabSize) - tabSize = tab->maxTabSize; - - if (fTopTab->look != kLeftTitledWindowLook - && tabSize != tabRect.Width()) { - tabRect.right = tabRect.left + tabSize; - } else if (fTopTab->look == kLeftTitledWindowLook - && tabSize != tabRect.Height()) { - tabRect.bottom = tabRect.top + tabSize; - } - - if (oldTabRect != tabRect) { - _LayoutTabItems(tab, tabRect); - - if (dirty) { - // NOTE: the tab rect becoming smaller only would - // handled be the Desktop anyways, so it is sufficient - // to include it into the dirty region in it's - // final state - BRect redraw(tabRect); - if (delta != 0.0) { - redraw = redraw | oldTabRect; - if (fTopTab->look != kLeftTitledWindowLook) - redraw.bottom++; - else - redraw.right++; - } - dirty->Include(redraw); - } - } - fTitleBarRect = tabRect; - fTabsRegion = fTitleBarRect; - } -} - - -bool -BeDecorator::_SetTabLocation(Decorator::Tab* _tab, float location, - bool isShifting, BRegion* updateRegion) -{ - STRACE(("BeDecorator: Set Tab Location(%.1f)\n", location)); - if (CountTabs() > 1) { - if (isShifting == false) { - _DoTabLayout(); - if (updateRegion != NULL) - updateRegion->Include(fTitleBarRect); - fOldMovingTab = BRect(0, 0, -1, -1); - return true; - } else { - if (fOldMovingTab.IsValid() == false) - fOldMovingTab = _tab->tabRect; - } - } - - BeDecorator::Tab* tab = static_cast(_tab); - BRect& tabRect = tab->tabRect; - if (tabRect.IsValid() == false) - return false; - - if (location < 0) - location = 0; - - float maxLocation - = fRightBorder.right - fLeftBorder.left - tabRect.Width(); - if (CountTabs() > 1) - maxLocation = fTitleBarRect.right - fLeftBorder.left - tabRect.Width(); - - if (location > maxLocation) - location = maxLocation; - - float delta = floor(location - tab->tabOffset); - if (delta == 0.0) - return false; - - // redraw old rect (1 pixel on the border must also be updated) - BRect rect(tabRect); - rect.bottom++; - if (updateRegion != NULL) - updateRegion->Include(rect); - - tabRect.OffsetBy(delta, 0); - tab->tabOffset = (int32)location; - _LayoutTabItems(_tab, tabRect); - tab->tabLocation = maxLocation > 0.0 ? tab->tabOffset / maxLocation : 0.0; - - if (fTabList.CountItems() == 1) - fTitleBarRect = tabRect; - - _CalculateTabsRegion(); - - // redraw new rect as well - rect = tabRect; - rect.bottom++; - if (updateRegion != NULL) - updateRegion->Include(rect); - - return true; -} - - -bool -BeDecorator::_SetSettings(const BMessage& settings, BRegion* updateRegion) -{ - float tabLocation; - bool modified = false; - for (int32 i = 0; i < fTabList.CountItems(); i++) { - if (settings.FindFloat("tab location", i, &tabLocation) != B_OK) - return false; - modified |= SetTabLocation(i, tabLocation, updateRegion); - } - return modified; -} - - -bool -BeDecorator::_AddTab(DesktopSettings& settings, int32 index, - BRegion* updateRegion) -{ - _UpdateFont(settings); - - _DoLayout(); - if (updateRegion != NULL) - updateRegion->Include(fTitleBarRect); - return true; -} - - -bool -BeDecorator::_RemoveTab(int32 index, BRegion* updateRegion) -{ - BRect oldTitle = fTitleBarRect; - _DoLayout(); - if (updateRegion != NULL) { - updateRegion->Include(oldTitle); - updateRegion->Include(fTitleBarRect); - } - return true; -} - - -bool -BeDecorator::_MoveTab(int32 from, int32 to, bool isMoving, - BRegion* updateRegion) -{ - BeDecorator::Tab* toTab = _TabAt(to); - if (toTab == NULL) - return false; - - if (from < to) { - fOldMovingTab.OffsetBy(toTab->tabRect.Width(), 0); - toTab->tabRect.OffsetBy(-fOldMovingTab.Width(), 0); - } else { - fOldMovingTab.OffsetBy(-toTab->tabRect.Width(), 0); - toTab->tabRect.OffsetBy(fOldMovingTab.Width(), 0); - } - - toTab->tabOffset = uint32(toTab->tabRect.left - fLeftBorder.left); - _LayoutTabItems(toTab, toTab->tabRect); - - _CalculateTabsRegion(); - - if (updateRegion != NULL) - updateRegion->Include(fTitleBarRect); - return true; -} - - -void -BeDecorator::_GetFootprint(BRegion *region) -{ - STRACE(("BeDecorator: Get Footprint\n")); - // This function calculates the decorator's footprint in coordinates - // relative to the view. This is most often used to set a Window - // object's visible region. - if (region == NULL) - return; - - region->MakeEmpty(); - - if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK) - return; - - region->Include(fTopBorder); - region->Include(fLeftBorder); - region->Include(fRightBorder); - region->Include(fBottomBorder); - - if (fTopTab->look == B_BORDERED_WINDOW_LOOK) - return; - - region->Include(&fTabsRegion); - - if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK) { - // include the rectangular resize knob on the bottom right - float knobSize = kResizeKnobSize - fBorderWidth; - region->Include(BRect(fFrame.right - knobSize, fFrame.bottom - knobSize, - fFrame.right, fFrame.bottom)); - } -} - - -void -BeDecorator::DrawButtons(Decorator::Tab* tab, const BRect& invalid) -{ - // Draw the buttons if we're supposed to - if (!(tab->flags & B_NOT_CLOSABLE) && invalid.Intersects(tab->closeRect)) - _DrawClose(tab, false, tab->closeRect); - if (!(tab->flags & B_NOT_ZOOMABLE) && invalid.Intersects(tab->zoomRect)) - _DrawZoom(tab, false, tab->zoomRect); -} - - -void -BeDecorator::_UpdateFont(DesktopSettings& settings) -{ - ServerFont font; - if (fTopTab->look == B_FLOATING_WINDOW_LOOK - || fTopTab->look == kLeftTitledWindowLook) { - settings.GetDefaultPlainFont(font); - if (fTopTab->look == kLeftTitledWindowLook) - font.SetRotation(90.0f); - } else - settings.GetDefaultBoldFont(font); - - font.SetFlags(B_FORCE_ANTIALIASING); - font.SetSpacing(B_STRING_SPACING); - fDrawState.SetFont(font); + BRect zoomRect(rect); + zoomRect.left += 3.0; + zoomRect.top += 3.0; + _DrawBlendedRect(tab, zoomRect, tab->zoomPressed); + + zoomRect = rect; + zoomRect.right -= 5.0; + zoomRect.bottom -= 5.0; + _DrawBlendedRect(tab, zoomRect, tab->zoomPressed); } /*! \brief Draws a framed rectangle with a gradient. - \param down The rectangle should be drawn recessed or not + \param tab The tab to draw on. + \param rect The rectangular area to draw in. + \param down Whether or not the button is drawn in down state. */ void -BeDecorator::_DrawBlendedRect(BRect r, bool down) +BeDecorator::_DrawBlendedRect(Decorator::Tab* tab, BRect rect, bool down) { - BRect r1 = r; - BRect r2 = r; + BRect r1 = rect; + BRect r2 = rect; r1.left += 1.0; r1.top += 1.0; @@ -1389,204 +572,117 @@ BeDecorator::_DrawBlendedRect(BRect r, bool down) r2.bottom -= 1.0; r2.right -= 1.0; - // TODO: replace these with cached versions? does R5 use different colours? - RGBColor tabColorLight = RGBColor(tint_color(fTabColor.GetColor32(), - B_LIGHTEN_2_TINT)); - RGBColor tabColorShadow = RGBColor(tint_color(fTabColor.GetColor32(), - B_DARKEN_2_TINT)); + ComponentColors colors; + _GetComponentColors(COMPONENT_TAB, colors, tab); - int32 w = r.IntegerWidth(); - int32 h = r.IntegerHeight(); + const rgb_color tabColor(colors[COLOR_TAB]); - RGBColor temprgbcol; - rgb_color halfColor, startColor, endColor; - float rstep, gstep, bstep; + rgb_color tabColorLight(tabColor); + tabColorLight.red = std::min(255, tabColor.red + 64), + tabColorLight.green = std::min(255, tabColor.green + 64), + tabColorLight.blue = std::min(255, tabColor.blue + 64); - int steps = w < h ? w : h; + rgb_color tabColorShadow(tabColor); + tabColorShadow.red = std::max(0, tabColor.red - 72), + tabColorShadow.green = std::max(0, tabColor.green - 72), + tabColorShadow.blue = std::max(0, tabColor.blue - 72); + + int32 w = rect.IntegerWidth(); + int32 h = rect.IntegerHeight(); + int32 steps = w < h ? w : h; + + rgb_color startColor; + rgb_color endColor; if (down) { - startColor = fButtonLowColor.GetColor32(); - endColor = fButtonHighColor.GetColor32(); + startColor = tabColorShadow; + endColor = tabColorLight; } else { - startColor = fButtonHighColor.GetColor32(); - endColor = fButtonLowColor.GetColor32(); + startColor = tabColorLight; + endColor = tabColorShadow; } - halfColor = make_blend_color(startColor, endColor, 0.5); + rgb_color halfColor(make_blend_color(startColor, endColor, 0.5)); - rstep = float(startColor.red - halfColor.red) / steps; - gstep = float(startColor.green - halfColor.green) / steps; - bstep = float(startColor.blue - halfColor.blue) / steps; + float rstep = float(startColor.red - halfColor.red) / steps; + float gstep = float(startColor.green - halfColor.green) / steps; + float bstep = float(startColor.blue - halfColor.blue) / steps; - for (int32 i = 0; i <= steps; i++) { - temprgbcol.SetColor(uint8(startColor.red - (i * rstep)), + for (int32 i = 0; i < steps; i += steps / 3) { + RGBColor tempRGBCol; + + tempRGBCol.SetColor(uint8(startColor.red - (i * rstep)), uint8(startColor.green - (i * gstep)), uint8(startColor.blue - (i * bstep))); - fDrawingEngine->StrokeLine(BPoint(r.left, r.top + i), - BPoint(r.left + i, r.top), temprgbcol); + for (int32 j = i; j < steps && j < i + steps / 3; j++) { + fDrawingEngine->StrokeLine(BPoint(rect.left, rect.top + j), + BPoint(rect.left + j, rect.top), tempRGBCol); + } - temprgbcol.SetColor(uint8(halfColor.red - (i * rstep)), + tempRGBCol.SetColor(uint8(halfColor.red - (i * rstep)), uint8(halfColor.green - (i * gstep)), uint8(halfColor.blue - (i * bstep))); - fDrawingEngine->StrokeLine(BPoint(r.left + steps, r.top + i), - BPoint(r.left + i, r.top + steps), temprgbcol); - } - - // draw bevelling effect on box - fDrawingEngine->StrokeRect(r2, tabColorShadow); // inner dark box - fDrawingEngine->StrokeRect(r, tabColorShadow); // outer dark box - fDrawingEngine->StrokeRect(r1, tabColorLight); // light box -} - - -void -BeDecorator::_GetButtonSizeAndOffset(const BRect& tabRect, float* _offset, - float* _size, float* _inset) const -{ - float tabSize = fTopTab->look == kLeftTitledWindowLook ? - tabRect.Width() : tabRect.Height(); - - bool smallTab = fTopTab->look == B_FLOATING_WINDOW_LOOK - || fTopTab->look == kLeftTitledWindowLook; - - *_offset = smallTab ? floorf(fDrawState.Font().Size() / 2.6) - : floorf(fDrawState.Font().Size() / 2.3); - *_inset = smallTab ? floorf(fDrawState.Font().Size() / 5.0) - : floorf(fDrawState.Font().Size() / 6.0); - - // "+ 2" so that the rects are centered within the solid area - // (without the 2 pixels for the top border) - *_size = tabSize - 2 * *_offset + *_inset; -} - - -void -BeDecorator::_LayoutTabItems(Decorator::Tab* _tab, const BRect& tabRect) -{ - BeDecorator::Tab* tab = static_cast(_tab); - - float offset; - float size; - float inset; - _GetButtonSizeAndOffset(tabRect, &offset, &size, &inset); - - // default textOffset - tab->textOffset = _DefaultTextOffset(); - - BRect& closeRect = tab->closeRect; - BRect& zoomRect = tab->zoomRect; - - // calulate close rect based on the tab rectangle - if (tab->look != kLeftTitledWindowLook) { - closeRect.Set(tabRect.left + offset, tabRect.top + offset, - tabRect.left + offset + size, tabRect.top + offset + size); - - zoomRect.Set(tabRect.right - offset - size, tabRect.top + offset, - tabRect.right - offset, tabRect.top + offset + size); - - // hidden buttons have no width - if ((tab->flags & B_NOT_CLOSABLE) != 0) - closeRect.right = closeRect.left - offset; - if ((tab->flags & B_NOT_ZOOMABLE) != 0) - zoomRect.left = zoomRect.right + offset; - } else { - closeRect.Set(tabRect.left + offset, tabRect.top + offset, - tabRect.left + offset + size, tabRect.top + offset + size); - - zoomRect.Set(tabRect.left + offset, tabRect.bottom - offset - size, - tabRect.left + size + offset, tabRect.bottom - offset); - - // hidden buttons have no height - if ((tab->flags & B_NOT_CLOSABLE) != 0) - closeRect.bottom = closeRect.top - offset; - if ((tab->flags & B_NOT_ZOOMABLE) != 0) - zoomRect.top = zoomRect.bottom + offset; - } - - // calculate room for title - // TODO: the +2 is there because the title often appeared - // truncated for no apparent reason - OTOH the title does - // also not appear perfectly in the middle - if (tab->look != kLeftTitledWindowLook) - size = (zoomRect.left - closeRect.right) - tab->textOffset * 2 + inset; - else - size = (zoomRect.top - closeRect.bottom) - tab->textOffset * 2 + inset; - - bool stackMode = fTabList.CountItems() > 1; - if (stackMode && IsFocus(tab) == false) { - zoomRect.Set(0, 0, 0, 0); - size = (tab->tabRect.right - closeRect.right) - tab->textOffset * 2 - + inset; - } - uint8 truncateMode = B_TRUNCATE_MIDDLE; - if (stackMode) { - if (tab->tabRect.Width() < 100) - truncateMode = B_TRUNCATE_END; - float titleWidth = fDrawState.Font().StringWidth(Title(tab), - BString(Title(tab)).Length()); - if (size < titleWidth) { - float oldTextOffset = tab->textOffset; - tab->textOffset -= (titleWidth - size) / 2; - const float kMinTextOffset = 5.; - if (tab->textOffset < kMinTextOffset) - tab->textOffset = kMinTextOffset; - size += oldTextOffset * 2; - size -= tab->textOffset * 2; + for (int32 j = i; j < steps && j < i + steps / 3; j++) { + fDrawingEngine->StrokeLine(BPoint(rect.left + steps, rect.top + j), + BPoint(rect.left + j, rect.top + steps), tempRGBCol); } } - tab->truncatedTitle = Title(tab); - fDrawState.Font().TruncateString(&tab->truncatedTitle, truncateMode, size); - tab->truncatedTitleLength = tab->truncatedTitle.Length(); -} - -void -BeDecorator::_InvalidateBitmaps() -{ - for (int32 i = 0; i < fTabList.CountItems(); i++) { - BeDecorator::Tab* tab = _TabAt(i); - for (int32 index = 0; index < 4; index++) { - tab->closeBitmaps[index] = NULL; - tab->zoomBitmaps[index] = NULL; - } - } -} - - -float -BeDecorator::_DefaultTextOffset() const -{ - return (fTopTab->look == B_FLOATING_WINDOW_LOOK - || fTopTab->look == kLeftTitledWindowLook) ? 10 : 18; -} - - -float -BeDecorator::_SingleTabOffsetAndSize(float& tabSize) -{ - float maxLocation; - if (fTopTab->look != kLeftTitledWindowLook) { - tabSize = fRightBorder.right - fLeftBorder.left; + // draw bevel effect on box + if (down) { + fDrawingEngine->StrokeRect(r2, RGBColor(tabColorLight)); + // inner light box + fDrawingEngine->StrokeRect(rect, RGBColor(tabColorLight)); + // outer light box + fDrawingEngine->StrokeRect(r1, RGBColor(tabColorShadow)); + // dark box } else { - tabSize = fBottomBorder.bottom - fTopBorder.top; + fDrawingEngine->StrokeRect(r2, RGBColor(tabColorShadow)); + // inner dark box + fDrawingEngine->StrokeRect(rect, RGBColor(tabColorShadow)); + // outer dark box + fDrawingEngine->StrokeRect(r1, RGBColor(tabColorLight)); + // light box } - BeDecorator::Tab* tab = _TabAt(0); - maxLocation = tabSize - tab->maxTabSize; - if (maxLocation < 0) - maxLocation = 0; - - return floorf(tab->tabLocation * maxLocation); } void -BeDecorator::_CalculateTabsRegion() +BeDecorator::_GetComponentColors(Component component, + ComponentColors _colors, Decorator::Tab* tab) { - fTabsRegion.MakeEmpty(); - for (int32 i = 0; i < fTabList.CountItems(); i++) - fTabsRegion.Include(fTabList.ItemAt(i)->tabRect); + // get the highlight for our component + Region region = REGION_NONE; + switch (component) { + case COMPONENT_TAB: + region = REGION_TAB; + break; + case COMPONENT_CLOSE_BUTTON: + region = REGION_CLOSE_BUTTON; + break; + case COMPONENT_ZOOM_BUTTON: + region = REGION_ZOOM_BUTTON; + break; + case COMPONENT_LEFT_BORDER: + region = REGION_LEFT_BORDER; + break; + case COMPONENT_RIGHT_BORDER: + region = REGION_RIGHT_BORDER; + break; + case COMPONENT_TOP_BORDER: + region = REGION_TOP_BORDER; + break; + case COMPONENT_BOTTOM_BORDER: + region = REGION_BOTTOM_BORDER; + break; + case COMPONENT_RESIZE_CORNER: + region = REGION_RIGHT_BOTTOM_CORNER; + break; + } + + return GetComponentColors(component, RegionHighlight(region), _colors, tab); } diff --git a/src/add-ons/decorators/BeDecorator/BeDecorator.h b/src/add-ons/decorators/BeDecorator/BeDecorator.h index 98b1531105..c5bb90ddda 100644 --- a/src/add-ons/decorators/BeDecorator/BeDecorator.h +++ b/src/add-ons/decorators/BeDecorator/BeDecorator.h @@ -16,10 +16,11 @@ #include "DecorManager.h" #include "RGBColor.h" +#include "TabDecorator.h" class Desktop; -class ServerBitmap; + class BeDecorAddOn : public DecorAddOn { public: @@ -30,171 +31,37 @@ protected: BRect rect); }; -class BeDecorator: public Decorator { + +class BeDecorator: public TabDecorator { 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; - }; - BeDecorator(DesktopSettings& settings, BRect frame); virtual ~BeDecorator(); - virtual float TabLocation(int32 tab) const; - - virtual bool GetSettings(BMessage* settings) const; - virtual void Draw(BRect updateRect); virtual void Draw(); - virtual void GetSizeLimits(int32* minWidth, int32* minHeight, - int32* maxWidth, int32* maxHeight) const; - - virtual Region RegionAt(BPoint where, int32& tab) const; - protected: - enum Component { - COMPONENT_TAB, - - COMPONENT_CLOSE_BUTTON, - COMPONENT_ZOOM_BUTTON, - - COMPONENT_LEFT_BORDER, - COMPONENT_RIGHT_BORDER, - COMPONENT_TOP_BORDER, - COMPONENT_BOTTOM_BORDER, - - COMPONENT_RESIZE_CORNER - }; - - enum { - COLOR_TAB_FRAME_LIGHT = 0, - COLOR_TAB_FRAME_DARK = 1, - COLOR_TAB = 2, - COLOR_TAB_LIGHT = 3, - COLOR_TAB_BEVEL = 4, - COLOR_TAB_SHADOW = 5, - COLOR_TAB_TEXT = 6 - }; - - enum { - COLOR_BUTTON = 0, - COLOR_BUTTON_LIGHT = 1 - }; - - typedef rgb_color ComponentColors[7]; - -protected: - virtual void _DoLayout(); - virtual void _DoTabLayout(); - void _DistributeTabSize(float delta); - - virtual Decorator::Tab* _AllocateNewTab(); - BeDecorator::Tab* _TabAt(int32 index) const; - virtual void _DrawFrame(BRect rect); virtual void _DrawTab(Decorator::Tab* tab, BRect rect); - virtual void _DrawTitle(Decorator::Tab* tab, BRect rect); virtual void _DrawClose(Decorator::Tab* tab, bool direct, BRect rect); + virtual void _DrawTitle(Decorator::Tab* tab, BRect rect); virtual void _DrawZoom(Decorator::Tab* tab, bool direct, BRect rect); - virtual void _SetTitle(Decorator::Tab* tab, const char* string, - BRegion* updateRegion = NULL); - - 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 _SetFocus(Decorator::Tab* tab); - - virtual void _MoveBy(BPoint offset); - virtual void _ResizeBy(BPoint offset, BRegion* dirty); - - virtual bool _AddTab(DesktopSettings& settings, - 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 bool _SetTabLocation(Decorator::Tab* tab, float location, - bool isShifting, BRegion* updateRegion = NULL); - - virtual bool _SetSettings(const BMessage& settings, - BRegion* updateRegion = NULL); - - virtual void _GetFootprint(BRegion* region); - - void _GetButtonSizeAndOffset(const BRect& tabRect, - float* offset, float* size, - float* inset) const; - - virtual void DrawButtons(Decorator::Tab* tab, - const BRect& invalid); - private: - void _UpdateFont(DesktopSettings& settings); - void _DrawBlendedRect(BRect r, bool down); - void _LayoutTabItems(Decorator::Tab* _tab, const BRect& tabRect); - void _InvalidateBitmaps(); + void _DrawBlendedRect(Decorator::Tab* tab, + BRect rect, bool down); + + void _GetComponentColors(Component component, + ComponentColors _colors, + Decorator::Tab* tab = NULL); inline float _DefaultTextOffset() const; inline float _SingleTabOffsetAndSize(float& tabSize); void _CalculateTabsRegion(); - -private: - RGBColor fButtonHighColor; - RGBColor fButtonLowColor; - RGBColor fTextColor; - RGBColor fTabColor; - - RGBColor* fFrameColors; - - // Individual rects for handling window frame - // rendering the proper way - BRect fRightBorder; - BRect fLeftBorder; - BRect fTopBorder; - BRect fBottomBorder; - - int32 fBorderWidth; - - BRegion fTabsRegion; - BRect fOldMovingTab; - - uint32 fTabOffset; - float fTabLocation; - - float fMinTabSize; - float fMaxTabSize; - - bool fWasDoubleClick; }; diff --git a/src/servers/app/decorator/DefaultDecorator.cpp b/src/servers/app/decorator/DefaultDecorator.cpp index 2aa4968eb6..63ba863905 100644 --- a/src/servers/app/decorator/DefaultDecorator.cpp +++ b/src/servers/app/decorator/DefaultDecorator.cpp @@ -525,39 +525,6 @@ DefaultDecorator::_DrawZoom(Decorator::Tab* _tab, bool direct, BRect rect) } -void -DefaultDecorator::_FontsChanged(DesktopSettings& settings, - BRegion* updateRegion) -{ - TabDecorator::_FontsChanged(settings, updateRegion); -} - - -void -DefaultDecorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings, - window_look look, BRegion* updateRegion) -{ - _InvalidateBitmaps(); - - TabDecorator::_SetLook(tab, settings, look, updateRegion); -} - - -void -DefaultDecorator::_SetFlags(Decorator::Tab* tab, uint32 flags, - BRegion* updateRegion) -{ - TabDecorator::_SetFlags(tab, flags, updateRegion); -} - - -void -DefaultDecorator::_SetFocus(Decorator::Tab* tab) -{ - TabDecorator::_SetFocus(tab); -} - - // #pragma mark - Private methods @@ -612,14 +579,6 @@ DefaultDecorator::_DrawBlendedRect(DrawingEngine* engine, BRect rect, } -void -DefaultDecorator::_GetButtonSizeAndOffset(const BRect& tabRect, float* _offset, - float* _size, float* _inset) const -{ - TabDecorator::_GetButtonSizeAndOffset(tabRect, _offset, _size, _inset); -} - - void DefaultDecorator::_InvalidateBitmaps() { @@ -773,38 +732,3 @@ DefaultDecorator::_GetComponentColors(Component component, return GetComponentColors(component, RegionHighlight(region), _colors, tab); } - - -float -DefaultDecorator::_DefaultTextOffset() const -{ - return (fTopTab->look == B_FLOATING_WINDOW_LOOK - || fTopTab->look == kLeftTitledWindowLook) ? 10 : 18; -} - - -float -DefaultDecorator::_SingleTabOffsetAndSize(float& tabSize) -{ - float maxLocation; - if (fTopTab->look != kLeftTitledWindowLook) { - tabSize = fRightBorder.right - fLeftBorder.left; - } else { - tabSize = fBottomBorder.bottom - fTopBorder.top; - } - TabDecorator::Tab* tab = static_cast(_TabAt(0)); - maxLocation = tabSize - tab->maxTabSize; - if (maxLocation < 0) - maxLocation = 0; - - return floorf(tab->tabLocation * maxLocation); -} - - -void -DefaultDecorator::_CalculateTabsRegion() -{ - fTabsRegion.MakeEmpty(); - for (int32 i = 0; i < fTabList.CountItems(); i++) - fTabsRegion.Include(fTabList.ItemAt(i)->tabRect); -} diff --git a/src/servers/app/decorator/DefaultDecorator.h b/src/servers/app/decorator/DefaultDecorator.h index fbc2228010..73d9e4ef0a 100644 --- a/src/servers/app/decorator/DefaultDecorator.h +++ b/src/servers/app/decorator/DefaultDecorator.h @@ -21,7 +21,7 @@ class Desktop; -class ServerBitmap; + class DefaultDecorator: public TabDecorator { public: @@ -42,21 +42,6 @@ protected: virtual void _DrawZoom(Decorator::Tab* tab, bool direct, BRect r); - 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 _GetButtonSizeAndOffset(const BRect& tabRect, - float* offset, float* size, - float* inset) const; - private: void _DrawButtonBitmap(ServerBitmap* bitmap, bool direct, BRect rect); @@ -71,11 +56,6 @@ private: void _GetComponentColors(Component component, ComponentColors _colors, Decorator::Tab* tab = NULL); - - inline float _DefaultTextOffset() const; - inline float _SingleTabOffsetAndSize(float& tabSize); - - void _CalculateTabsRegion(); }; diff --git a/src/servers/app/decorator/TabDecorator.cpp b/src/servers/app/decorator/TabDecorator.cpp index cef2d8b43b..7684355bcf 100644 --- a/src/servers/app/decorator/TabDecorator.cpp +++ b/src/servers/app/decorator/TabDecorator.cpp @@ -37,7 +37,6 @@ #include "DrawState.h" #include "FontManager.h" #include "PatternHandler.h" -#include "ServerBitmap.h" //#define DEBUG_DECORATOR @@ -58,8 +57,14 @@ int_equal(float x, float y) TabDecorator::Tab::Tab() : tabOffset(0), - tabLocation(0.0), - isHighlighted(false) + 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] @@ -79,6 +84,7 @@ static const float kResizeKnobSize = 18.0; TabDecorator::TabDecorator(DesktopSettings& settings, BRect rect) : Decorator(settings, rect), + fOldMovingTab(0, 0, -1, -1), // focus color constants kFocusFrameColor(settings.UIColor(B_WINDOW_BORDER_COLOR)), kFocusTabColor(settings.UIColor(B_WINDOW_TAB_COLOR)), @@ -96,9 +102,7 @@ TabDecorator::TabDecorator(DesktopSettings& settings, BRect rect) kNonFocusTabColorBevel(tint_color(kNonFocusTabColor, B_LIGHTEN_2_TINT)), kNonFocusTabColorShadow(tint_color(kNonFocusTabColor, (B_DARKEN_1_TINT + B_NO_TINT) / 2)), - kNonFocusTextColor(settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR)), - - fOldMovingTab(0, 0, -1, -1) + kNonFocusTextColor(settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR)) { // TODO: If the decorator was created with a frame too small, it should // resize itself! @@ -216,33 +220,6 @@ TabDecorator::RegionAt(BPoint where, int32& tab) const } -bool -TabDecorator::SetRegionHighlight(Region region, uint8 highlight, - BRegion* dirty, int32 tabIndex) -{ - TabDecorator::Tab* tab = _TabAt(tabIndex); - if (tab != NULL) { - tab->isHighlighted = highlight != 0; - // Invalidate the bitmap caches for the close/zoom button, when the - // highlight changes. - switch (region) { - case REGION_CLOSE_BUTTON: - if (highlight != RegionHighlight(region)) - memset(&tab->closeBitmaps, 0, sizeof(tab->closeBitmaps)); - break; - case REGION_ZOOM_BUTTON: - if (highlight != RegionHighlight(region)) - memset(&tab->zoomBitmaps, 0, sizeof(tab->zoomBitmaps)); - break; - default: - break; - } - } - - return Decorator::SetRegionHighlight(region, highlight, dirty, tabIndex); -} - - void TabDecorator::ExtendDirtyRegion(Region region, BRegion& dirty) { @@ -304,6 +281,121 @@ TabDecorator::ExtendDirtyRegion(Region region, BRegion& dirty) } +/*! Returns the frame colors for the specified decorator component. + + The meaning of the color array elements depends on the specified component. + For some components some array elements are unused. + + \param component The component for which to return the frame colors. + \param highlight The highlight set for the component. + \param colors An array of colors to be initialized by the function. +*/ +void +TabDecorator::GetComponentColors(Component component, uint8 highlight, + ComponentColors _colors, Decorator::Tab* _tab) +{ + TabDecorator::Tab* tab = static_cast(_tab); + switch (component) { + case COMPONENT_TAB: + if (tab && tab->buttonFocus) { + _colors[COLOR_TAB_FRAME_LIGHT] + = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); + _colors[COLOR_TAB_FRAME_DARK] + = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); + _colors[COLOR_TAB] = kFocusTabColor; + _colors[COLOR_TAB_LIGHT] = kFocusTabColorLight; + _colors[COLOR_TAB_BEVEL] = kFocusTabColorBevel; + _colors[COLOR_TAB_SHADOW] = kFocusTabColorShadow; + _colors[COLOR_TAB_TEXT] = kFocusTextColor; + } else { + _colors[COLOR_TAB_FRAME_LIGHT] + = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[COLOR_TAB_FRAME_DARK] + = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); + _colors[COLOR_TAB] = kNonFocusTabColor; + _colors[COLOR_TAB_LIGHT] = kNonFocusTabColorLight; + _colors[COLOR_TAB_BEVEL] = kNonFocusTabColorBevel; + _colors[COLOR_TAB_SHADOW] = kNonFocusTabColorShadow; + _colors[COLOR_TAB_TEXT] = kNonFocusTextColor; + } + break; + + case COMPONENT_CLOSE_BUTTON: + case COMPONENT_ZOOM_BUTTON: + if (tab && tab->buttonFocus) { + _colors[COLOR_BUTTON] = kFocusTabColor; + _colors[COLOR_BUTTON_LIGHT] = kFocusTabColorLight; + } else { + _colors[COLOR_BUTTON] = kNonFocusTabColor; + _colors[COLOR_BUTTON_LIGHT] = kNonFocusTabColorLight; + } + break; + + case COMPONENT_LEFT_BORDER: + case COMPONENT_RIGHT_BORDER: + case COMPONENT_TOP_BORDER: + case COMPONENT_BOTTOM_BORDER: + case COMPONENT_RESIZE_CORNER: + default: + if (tab && tab->buttonFocus) { + _colors[0] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); + _colors[1] = tint_color(kFocusFrameColor, B_LIGHTEN_2_TINT); + _colors[2] = kFocusFrameColor; + _colors[3] = tint_color(kFocusFrameColor, + (B_DARKEN_1_TINT + B_NO_TINT) / 2); + _colors[4] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); + _colors[5] = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); + } else { + _colors[0] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[1] = tint_color(kNonFocusFrameColor, B_LIGHTEN_2_TINT); + _colors[2] = kNonFocusFrameColor; + _colors[3] = tint_color(kNonFocusFrameColor, + (B_DARKEN_1_TINT + B_NO_TINT) / 2); + _colors[4] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[5] = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); + } + + // for the resize-border highlight dye everything bluish. + if (highlight == HIGHLIGHT_RESIZE_BORDER) { + for (int32 i = 0; i < 6; i++) { + _colors[i].red = std::max((int)_colors[i].red - 80, 0); + _colors[i].green = std::max((int)_colors[i].green - 80, 0); + _colors[i].blue = 255; + } + } + break; + } +} + + +bool +TabDecorator::SetRegionHighlight(Region region, uint8 highlight, + BRegion* dirty, int32 tabIndex) +{ + TabDecorator::Tab* tab + = static_cast(_TabAt(tabIndex)); + if (tab != NULL) { + tab->isHighlighted = highlight != 0; + // Invalidate the bitmap caches for the close/zoom button, when the + // highlight changes. + switch (region) { + case REGION_CLOSE_BUTTON: + if (highlight != RegionHighlight(region)) + memset(&tab->closeBitmaps, 0, sizeof(tab->closeBitmaps)); + break; + case REGION_ZOOM_BUTTON: + if (highlight != RegionHighlight(region)) + memset(&tab->zoomBitmaps, 0, sizeof(tab->zoomBitmaps)); + break; + default: + break; + } + } + + return Decorator::SetRegionHighlight(region, highlight, dirty, tabIndex); +} + + float TabDecorator::BorderWidth() { @@ -1044,93 +1136,6 @@ TabDecorator::DrawButtons(Decorator::Tab* tab, const BRect& invalid) } -/*! Returns the frame colors for the specified decorator component. - - The meaning of the color array elements depends on the specified component. - For some components some array elements are unused. - - \param component The component for which to return the frame colors. - \param highlight The highlight set for the component. - \param colors An array of colors to be initialized by the function. -*/ -void -TabDecorator::GetComponentColors(Component component, uint8 highlight, - ComponentColors _colors, Decorator::Tab* _tab) -{ - TabDecorator::Tab* tab = static_cast(_tab); - switch (component) { - case COMPONENT_TAB: - if (tab && tab->buttonFocus) { - _colors[COLOR_TAB_FRAME_LIGHT] - = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[COLOR_TAB_FRAME_DARK] - = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); - _colors[COLOR_TAB] = kFocusTabColor; - _colors[COLOR_TAB_LIGHT] = kFocusTabColorLight; - _colors[COLOR_TAB_BEVEL] = kFocusTabColorBevel; - _colors[COLOR_TAB_SHADOW] = kFocusTabColorShadow; - _colors[COLOR_TAB_TEXT] = kFocusTextColor; - } else { - _colors[COLOR_TAB_FRAME_LIGHT] - = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); - _colors[COLOR_TAB_FRAME_DARK] - = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); - _colors[COLOR_TAB] = kNonFocusTabColor; - _colors[COLOR_TAB_LIGHT] = kNonFocusTabColorLight; - _colors[COLOR_TAB_BEVEL] = kNonFocusTabColorBevel; - _colors[COLOR_TAB_SHADOW] = kNonFocusTabColorShadow; - _colors[COLOR_TAB_TEXT] = kNonFocusTextColor; - } - break; - - case COMPONENT_CLOSE_BUTTON: - case COMPONENT_ZOOM_BUTTON: - if (tab && tab->buttonFocus) { - _colors[COLOR_BUTTON] = kFocusTabColor; - _colors[COLOR_BUTTON_LIGHT] = kFocusTabColorLight; - } else { - _colors[COLOR_BUTTON] = kNonFocusTabColor; - _colors[COLOR_BUTTON_LIGHT] = kNonFocusTabColorLight; - } - break; - - case COMPONENT_LEFT_BORDER: - case COMPONENT_RIGHT_BORDER: - case COMPONENT_TOP_BORDER: - case COMPONENT_BOTTOM_BORDER: - case COMPONENT_RESIZE_CORNER: - default: - if (tab && tab->buttonFocus) { - _colors[0] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[1] = tint_color(kFocusFrameColor, B_LIGHTEN_2_TINT); - _colors[2] = kFocusFrameColor; - _colors[3] = tint_color(kFocusFrameColor, - (B_DARKEN_1_TINT + B_NO_TINT) / 2); - _colors[4] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[5] = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); - } else { - _colors[0] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); - _colors[1] = tint_color(kNonFocusFrameColor, B_LIGHTEN_2_TINT); - _colors[2] = kNonFocusFrameColor; - _colors[3] = tint_color(kNonFocusFrameColor, - (B_DARKEN_1_TINT + B_NO_TINT) / 2); - _colors[4] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); - _colors[5] = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); - } - - // for the resize-border highlight dye everything bluish. - if (highlight == HIGHLIGHT_RESIZE_BORDER) { - for (int32 i = 0; i < 6; i++) { - _colors[i].red = std::max((int)_colors[i].red - 80, 0); - _colors[i].green = std::max((int)_colors[i].green - 80, 0); - _colors[i].blue = 255; - } - } - break; - } -} - - void TabDecorator::_UpdateFont(DesktopSettings& settings) { diff --git a/src/servers/app/decorator/TabDecorator.h b/src/servers/app/decorator/TabDecorator.h index 7575316ed0..cae67e2d88 100644 --- a/src/servers/app/decorator/TabDecorator.h +++ b/src/servers/app/decorator/TabDecorator.h @@ -40,39 +40,18 @@ public: bool buttonFocus : 1; bool isHighlighted : 1; - ServerBitmap* closeBitmaps[4]; - ServerBitmap* zoomBitmaps[4]; float minTabSize; float maxTabSize; + + ServerBitmap* closeBitmaps[4]; + ServerBitmap* zoomBitmaps[4]; }; TabDecorator(DesktopSettings& settings, BRect frame); virtual ~TabDecorator(); - virtual float TabLocation(int32 tab) const; - - 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 bool SetRegionHighlight(Region region, - uint8 highlight, BRegion* dirty, - int32 tab = -1); - - virtual void ExtendDirtyRegion(Region region, - BRegion& dirty); - - float BorderWidth(); - float TabHeight(); - protected: enum { COLOR_TAB_FRAME_LIGHT = 0, @@ -105,6 +84,33 @@ protected: typedef rgb_color ComponentColors[7]; +public: + virtual float TabLocation(int32 tab) const; + + 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 void ExtendDirtyRegion(Region region, + BRegion& dirty); + + virtual void GetComponentColors(Component component, + uint8 highlight, ComponentColors _colors, + Decorator::Tab* tab = NULL); + + virtual bool SetRegionHighlight(Region region, + uint8 highlight, BRegion* dirty, + int32 tab = -1); + + float BorderWidth(); + float TabHeight(); + protected: virtual void _DoLayout(); virtual void _DoTabLayout(); @@ -162,9 +168,6 @@ protected: // TabDecorator customization points virtual void DrawButtons(Decorator::Tab* tab, const BRect& invalid); - virtual void GetComponentColors(Component component, - uint8 highlight, ComponentColors _colors, - Decorator::Tab* tab = NULL); virtual void _UpdateFont(DesktopSettings& settings); @@ -172,11 +175,25 @@ private: void _LayoutTabItems(Decorator::Tab* tab, const BRect& tabRect); +protected: inline float _DefaultTextOffset() const; inline float _SingleTabOffsetAndSize(float& tabSize); void _CalculateTabsRegion(); + protected: + // Individual rects for handling window frame + // rendering the proper way + BRect fRightBorder; + BRect fLeftBorder; + BRect fTopBorder; + BRect fBottomBorder; + + int32 fBorderWidth; + + BRegion fTabsRegion; + BRect fOldMovingTab; + const rgb_color kFocusFrameColor; const rgb_color kFocusTabColor; @@ -192,18 +209,6 @@ protected: const rgb_color kNonFocusTabColorBevel; const rgb_color kNonFocusTabColorShadow; const rgb_color kNonFocusTextColor; - - // Individual rects for handling window frame - // rendering the proper way - BRect fRightBorder; - BRect fLeftBorder; - BRect fTopBorder; - BRect fBottomBorder; - - int32 fBorderWidth; - - BRegion fTabsRegion; - BRect fOldMovingTab; };