diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index b48ab2ee85..1529a6a8f2 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -208,6 +208,13 @@ public: const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS); + /*virtual*/ void DrawSplitter(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + enum orientation orientation, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + // various borders virtual void DrawBorder(BView* view, BRect& rect, diff --git a/headers/os/interface/SplitView.h b/headers/os/interface/SplitView.h index 5d29ffb83b..92c7e73bd5 100644 --- a/headers/os/interface/SplitView.h +++ b/headers/os/interface/SplitView.h @@ -55,10 +55,12 @@ public: protected: virtual void DrawSplitter(BRect frame, + const BRect& updateRect, enum orientation orientation, bool pressed); private: static void _DrawDefaultSplitter(BView* view, BRect frame, + const BRect& updateRect, enum orientation orientation, bool pressed); private: diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index 7990cb71b0..a13dbe13f7 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -239,7 +239,7 @@ BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, if (popupIndicator) { BRect leftRect(rect); leftRect.right -= 10; - + BRect rightRect(rect); rightRect.left = rightRect.right - 9; @@ -272,7 +272,7 @@ BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, view->SetHighColor(markColor); view->FillTriangle(triangle[0], triangle[1], triangle[2]); - + view->SetFlags(viewFlags); rect = leftRect; @@ -424,7 +424,7 @@ BControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, _DrawOuterResessedFrame(view, rect, base, 0.6); - // colors + // colors rgb_color dark1BorderColor = tint_color(base, 1.3); rgb_color dark2BorderColor = tint_color(base, 1.2); rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20); @@ -869,7 +869,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, rightBarSide.top = sliderPosition; } - // fill the background for the corners, exclude the middle bar for now + // fill the background for the corners, exclude the middle bar for now BRegion region(rect); region.Exclude(rightBarSide); view->ConstrainClippingRegion(®ion); @@ -879,7 +879,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, orientation); - view->PopState(); + view->PopState(); region.Set(rect); region.Exclude(leftBarSide); @@ -890,7 +890,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, orientation); - view->PopState(); + view->PopState(); view->ConstrainClippingRegion(NULL); } @@ -921,7 +921,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, barRect.bottom -= ceilf(barRect.Width() / 2); } - // fill the background for the corners, exclude the middle bar for now + // fill the background for the corners, exclude the middle bar for now BRegion region(rect); region.Exclude(barRect); view->ConstrainClippingRegion(®ion); @@ -968,7 +968,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); - + _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); @@ -976,7 +976,7 @@ BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); - + _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); @@ -1031,7 +1031,7 @@ BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, // figure out the tints to be used float frameLightTint; float frameShadowTint; - + if (flags & B_DISABLED) { frameLightTint = 1.30; frameShadowTint = 1.35; @@ -1040,7 +1040,7 @@ BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, frameLightTint = 1.6; frameShadowTint = 1.65; } - + frameLightColor = tint_color(base, frameLightTint); frameShadowColor = tint_color(base, frameShadowTint); } @@ -1143,7 +1143,7 @@ BControlLook::DrawSliderTriangle(BView* view, BRect& rect, // figure out the tints to be used float frameLightTint; float frameShadowTint; - + if (flags & B_DISABLED) { frameLightTint = 1.30; frameShadowTint = 1.35; @@ -1152,7 +1152,7 @@ BControlLook::DrawSliderTriangle(BView* view, BRect& rect, frameLightTint = 1.6; frameShadowTint = 1.65; } - + frameLightColor = tint_color(base, frameLightTint); frameShadowColor = tint_color(base, frameShadowTint); } @@ -1440,6 +1440,113 @@ BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, } +void +BControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, enum orientation orientation, uint32 flags, + uint32 borders) +{ + rgb_color background; + if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) + background = tint_color(base, B_DARKEN_1_TINT); + else + background = base; + + rgb_color light = tint_color(background, 0.6); + rgb_color shadow = tint_color(background, 1.21); + + // frame + if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) + DrawRaisedBorder(view, rect, updateRect, background, flags, borders); + + // dots and rest of background + if (orientation == B_HORIZONTAL) { + if (rect.Width() > 2) { + // background on left/right + BRegion region(rect); + rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); + rect.right = rect.left + 1; + region.Exclude(rect); + view->SetHighColor(background); + view->FillRegion(®ion); + } + + BPoint dot = rect.LeftTop(); + BPoint stop = rect.LeftBottom(); + int32 num = 1; + while (dot.y <= stop.y) { + rgb_color col1; + rgb_color col2; + switch (num) { + case 1: + col1 = background; + col2 = background; + break; + case 2: + col1 = shadow; + col2 = background; + break; + case 3: + col1 = background; + col2 = light; + num = 0; + break; + } + view->SetHighColor(col1); + view->StrokeLine(dot, dot, B_SOLID_HIGH); + view->SetHighColor(col2); + dot.x++; + view->StrokeLine(dot, dot, B_SOLID_HIGH); + dot.x -= 1.0; + // next pixel + num++; + dot.y++; + } + } else { + if (rect.Height() > 2) { + // background on left/right + BRegion region(rect); + rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); + rect.bottom = rect.top + 1; + region.Exclude(rect); + view->SetHighColor(background); + view->FillRegion(®ion); + } + + BPoint dot = rect.LeftTop(); + BPoint stop = rect.RightTop(); + int32 num = 1; + while (dot.x <= stop.x) { + rgb_color col1; + rgb_color col2; + switch (num) { + case 1: + col1 = background; + col2 = background; + break; + case 2: + col1 = shadow; + col2 = background; + break; + case 3: + col1 = background; + col2 = light; + num = 0; + break; + } + view->SetHighColor(col1); + view->StrokeLine(dot, dot, B_SOLID_HIGH); + view->SetHighColor(col2); + dot.y++; + view->StrokeLine(dot, dot, B_SOLID_HIGH); + dot.y -= 1.0; + // next pixel + num++; + dot.x++; + } + } +} + + // #pragma mark - @@ -1601,7 +1708,7 @@ BControlLook::DrawLabel(BView* view, const char* label, BRect rect, // truncate the label if necessary and get the width and height BString truncatedLabel(label); - + BFont font; view->GetFont(&font); @@ -1765,7 +1872,7 @@ BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, // colors float tintLight = kEdgeBevelLightTint; float tintShadow = kEdgeBevelShadowTint; - + if (contrast == 0.0) { tintLight = B_NO_TINT; tintShadow = B_NO_TINT; @@ -1773,10 +1880,10 @@ BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; } - + rgb_color borderBevelShadow = tint_color(base, tintShadow); rgb_color borderBevelLight = tint_color(base, tintLight); - + if (brightness < 1.0) { borderBevelShadow.red = uint8(borderBevelShadow.red * brightness); borderBevelShadow.green = uint8(borderBevelShadow.green * brightness); @@ -1785,7 +1892,7 @@ BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, borderBevelLight.green = uint8(borderBevelLight.green * brightness); borderBevelLight.blue = uint8(borderBevelLight.blue * brightness); } - + _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, borderBevelLight, borderBevelLight, borders); } diff --git a/src/kits/interface/SplitLayout.cpp b/src/kits/interface/SplitLayout.cpp index a10b8306e2..9ba800263b 100644 --- a/src/kits/interface/SplitLayout.cpp +++ b/src/kits/interface/SplitLayout.cpp @@ -140,7 +140,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation, fRightInset(0), fTopInset(0), fBottomInset(0), - fSplitterSize(3), + fSplitterSize(6), fSpacing(spacing), fSplitterItems(), @@ -153,7 +153,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation, fVerticalLayouter(NULL), fHorizontalLayoutInfo(NULL), fVerticalLayoutInfo(NULL), - + fHeightForWidthItems(), fHeightForWidthVerticalLayouter(NULL), fHeightForWidthHorizontalLayoutInfo(NULL), @@ -165,7 +165,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation, fCachedMinHeightForWidth(-1), fCachedMaxHeightForWidth(-1), fCachedPreferredHeightForWidth(-1), - + fDraggingStartPoint(), fDraggingStartValue(0), fDraggingCurrentValue(0), @@ -482,7 +482,7 @@ BSplitLayout::LayoutView() verticalLayouter = fHeightForWidthVerticalLayouter; } else verticalLayouter = fVerticalLayouter; - + verticalLayouter->Layout(fVerticalLayoutInfo, size.height); float xOffset = fLeftInset; @@ -551,6 +551,13 @@ BSplitLayout::SplitterItemFrame(int32 index) const return BRect(); } +// IsAboveSplitter +bool +BSplitLayout::IsAboveSplitter(const BPoint& point) const +{ + return _SplitterItemAt(point) != NULL; +} + // StartDraggingSplitter bool BSplitLayout::StartDraggingSplitter(BPoint point) @@ -568,18 +575,14 @@ BSplitLayout::StartDraggingSplitter(BPoint point) return false; } - int32 splitterCount = fSplitterItems.CountItems(); - for (int32 i = 0; i < splitterCount; i++) { - SplitterItem* splitItem = _SplitterItemAt(i); - BRect frame = splitItem->Frame(); - if (frame.Contains(point)) { - fDraggingStartPoint = View()->ConvertToScreen(point); - fDraggingStartValue = _SplitterValue(i); - fDraggingCurrentValue = fDraggingStartValue; - fDraggingSplitterIndex = i; + int32 index; + if (SplitterItem* splitItem = _SplitterItemAt(point, &index)) { + fDraggingStartPoint = View()->ConvertToScreen(point); + fDraggingStartValue = _SplitterValue(index); + fDraggingCurrentValue = fDraggingStartValue; + fDraggingSplitterIndex = index; - return true; - } + return true; } return false; @@ -690,6 +693,23 @@ BSplitLayout::_InvalidateCachedHeightForWidth() fHeightForWidthVerticalLayouterWidth = -2; } +// _SplitterItemAt +BSplitLayout::SplitterItem* +BSplitLayout::_SplitterItemAt(const BPoint& point, int32* index) const +{ + int32 splitterCount = fSplitterItems.CountItems(); + for (int32 i = 0; i < splitterCount; i++) { + SplitterItem* splitItem = _SplitterItemAt(i); + BRect frame = splitItem->Frame(); + if (frame.Contains(point)) { + if (index != NULL) + *index = i; + return splitItem; + } + } + return NULL; +} + // _SplitterItemAt BSplitLayout::SplitterItem* BSplitLayout::_SplitterItemAt(int32 index) const @@ -778,7 +798,7 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info) bool visibilityChanged = (info->isVisible != isVisible); if (visibilityChanged) item->SetVisible(info->isVisible); - + // nothing more to do, if the item is not visible if (!info->isVisible) return; @@ -1070,7 +1090,7 @@ BSplitLayout::_ValidateMinMax() fHeightForWidthItems.MakeEmpty(); _InvalidateCachedHeightForWidth(); - + // filter the visible items int32 itemCount = CountItems(); for (int32 i = 0; i < itemCount; i++) { @@ -1084,7 +1104,7 @@ BSplitLayout::_ValidateMinMax() if (item->HasHeightForWidth()) fHeightForWidthItems.AddItem(item); } - itemCount = fVisibleItems.CountItems(); + itemCount = fVisibleItems.CountItems(); // create the layouters Layouter* itemLayouter = new SimpleLayouter(itemCount, 0); @@ -1161,7 +1181,7 @@ BSplitLayout::_InternalGetHeightForWidth(float width, bool realLayout, } horizontalLayoutInfo = fHeightForWidthHorizontalLayoutInfo; } - + // do the horizontal layout (already done when doing this for the real // layout) if (!realLayout) @@ -1223,7 +1243,7 @@ BSplitLayout::_AddInsets(BSize size) float spacing = _SplitterSpace(); if (fOrientation == B_HORIZONTAL) size.width = BLayoutUtils::AddDistances(size.width, spacing - 1); - else + else size.height = BLayoutUtils::AddDistances(size.height, spacing - 1); return size; @@ -1257,7 +1277,7 @@ BSplitLayout::_SubtractInsets(BSize size) float spacing = _SplitterSpace(); if (fOrientation == B_HORIZONTAL) size.width = BLayoutUtils::SubtractDistances(size.width, spacing - 1); - else + else size.height = BLayoutUtils::SubtractDistances(size.height, spacing - 1); return size; diff --git a/src/kits/interface/SplitLayout.h b/src/kits/interface/SplitLayout.h index 4cea388f17..7bb0320519 100644 --- a/src/kits/interface/SplitLayout.h +++ b/src/kits/interface/SplitLayout.h @@ -80,13 +80,14 @@ public: // interface for BSplitView BRect SplitterItemFrame(int32 index) const; + bool IsAboveSplitter(const BPoint& point) const; bool StartDraggingSplitter(BPoint point); bool DragSplitter(BPoint point); bool StopDraggingSplitter(); int32 DraggedSplitter() const; -protected: +protected: virtual void ItemAdded(BLayoutItem* item); virtual void ItemRemoved(BLayoutItem* item); @@ -98,6 +99,8 @@ private: void _InvalidateLayout(bool invalidateView); void _InvalidateCachedHeightForWidth(); + SplitterItem* _SplitterItemAt(const BPoint& point, + int32* index = NULL) const; SplitterItem* _SplitterItemAt(int32 index) const; void _GetSplitterValueRange(int32 index, @@ -150,7 +153,7 @@ private: LayoutInfo* fHorizontalLayoutInfo; LayoutInfo* fVerticalLayoutInfo; - + BList fHeightForWidthItems; // Incorporates the children's height for width constraints for a // concrete width. Cloned lazily from fVerticalLayout when needed. @@ -165,7 +168,7 @@ private: float fCachedMinHeightForWidth; float fCachedMaxHeightForWidth; float fCachedPreferredHeightForWidth; - + BPoint fDraggingStartPoint; int32 fDraggingStartValue; int32 fDraggingCurrentValue; diff --git a/src/kits/interface/SplitView.cpp b/src/kits/interface/SplitView.cpp index e0950cd9bd..bdc2940667 100644 --- a/src/kits/interface/SplitView.cpp +++ b/src/kits/interface/SplitView.cpp @@ -5,12 +5,45 @@ #include +#include + +#include +#include + #include "SplitLayout.h" +static const unsigned char kHSplitterCursor[] = { + 16, 1, 8, 8, + 0x03, 0xc0, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x1a, 0x58, 0x2a, 0x54, 0x4a, 0x52, 0x8a, 0x51, + 0x8a, 0x51, 0x4a, 0x52, 0x2a, 0x54, 0x1a, 0x58, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x03, 0xc0, + + 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, + 0x1b, 0xd8, 0x3b, 0xdc, 0x7b, 0xde, 0xfb, 0xdf, + 0xfb, 0xdf, 0x7b, 0xde, 0x3b, 0xdc, 0x1b, 0xd8, + 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0 +}; + +static const unsigned char kVSplitterCursor[] = { + 16, 1, 8, 8, + 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, 0x10, + 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x01, + 0x80, 0x01, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, + 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, + + 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, + 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, + 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80 +}; + + // constructor BSplitView::BSplitView(enum orientation orientation, float spacing) - : BView(NULL, + : + BView(NULL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT, fSplitLayout = new BSplitLayout(orientation, spacing)) { @@ -136,7 +169,8 @@ BSplitView::Draw(BRect updateRect) int32 count = fSplitLayout->CountItems(); for (int32 i = 0; i < count - 1; i++) { BRect frame = fSplitLayout->SplitterItemFrame(i); - DrawSplitter(frame, Orientation(), draggedSplitterIndex == i); + DrawSplitter(frame, updateRect, Orientation(), + draggedSplitterIndex == i); } } @@ -144,7 +178,8 @@ BSplitView::Draw(BRect updateRect) void BSplitView::MouseDown(BPoint where) { - SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + SetMouseEventMask(B_POINTER_EVENTS, + B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS); if (fSplitLayout->StartDraggingSplitter(where)) Invalidate(); @@ -164,7 +199,17 @@ BSplitView::MouseUp(BPoint where) void BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) { + BCursor cursor(B_CURSOR_SYSTEM_DEFAULT); + int32 splitterIndex = fSplitLayout->DraggedSplitter(); + + if (splitterIndex >= 0 || fSplitLayout->IsAboveSplitter(where)) { + if (Orientation() == B_VERTICAL) + cursor = BCursor(kVSplitterCursor); + else + cursor = BCursor(kHSplitterCursor); + } + if (splitterIndex >= 0) { BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex); if (fSplitLayout->DragSplitter(where)) { @@ -172,6 +217,8 @@ BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex)); } } + + SetViewCursor(&cursor, true); } // SetLayout @@ -183,13 +230,18 @@ BSplitView::SetLayout(BLayout* layout) // DrawSplitter void -BSplitView::DrawSplitter(BRect frame, enum orientation orientation, - bool pressed) +BSplitView::DrawSplitter(BRect frame, const BRect& updateRect, + enum orientation orientation, bool pressed) { - rgb_color black = { 0, 0, 0, 255 }; - rgb_color white = { 255, 255, 255, 255 }; - - SetHighColor(pressed ? white : black); - - FillRect(frame); + _DrawDefaultSplitter(this, frame, updateRect, orientation, pressed); +} + +// _DrawDefaultSplitter +void +BSplitView::_DrawDefaultSplitter(BView* view, BRect frame, + const BRect& updateRect, enum orientation orientation, bool pressed) +{ + uint32 flags = pressed ? BControlLook::B_ACTIVATED : 0; + be_control_look->DrawSplitter(view, frame, updateRect, view->ViewColor(), + orientation, flags, 0); }