* Added BSplitView drawing code to ControlLook.

* BSplitView uses ControlLook to draw itself.
* Small refactoring in SplitLayout to implement IsAboveSplitter(BPoint).
* BSplitView updates the view cursor when the mouse is above a splitter.
* Standard splitter size is now 6 pixels, which is a bit easer to hit.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31137 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-06-20 15:03:33 +00:00
parent 01206002ba
commit 1f9fd6d866
6 changed files with 244 additions and 53 deletions
+7
View File
@@ -208,6 +208,13 @@ public:
const rgb_color& base, uint32 flags = 0, const rgb_color& base, uint32 flags = 0,
uint32 borders = B_ALL_BORDERS); 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 // various borders
virtual void DrawBorder(BView* view, BRect& rect, virtual void DrawBorder(BView* view, BRect& rect,
+2
View File
@@ -55,10 +55,12 @@ public:
protected: protected:
virtual void DrawSplitter(BRect frame, virtual void DrawSplitter(BRect frame,
const BRect& updateRect,
enum orientation orientation, bool pressed); enum orientation orientation, bool pressed);
private: private:
static void _DrawDefaultSplitter(BView* view, BRect frame, static void _DrawDefaultSplitter(BView* view, BRect frame,
const BRect& updateRect,
enum orientation orientation, bool pressed); enum orientation orientation, bool pressed);
private: private:
+107
View File
@@ -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(&region);
}
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(&region);
}
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 - // #pragma mark -
+29 -9
View File
@@ -140,7 +140,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation,
fRightInset(0), fRightInset(0),
fTopInset(0), fTopInset(0),
fBottomInset(0), fBottomInset(0),
fSplitterSize(3), fSplitterSize(6),
fSpacing(spacing), fSpacing(spacing),
fSplitterItems(), fSplitterItems(),
@@ -551,6 +551,13 @@ BSplitLayout::SplitterItemFrame(int32 index) const
return BRect(); return BRect();
} }
// IsAboveSplitter
bool
BSplitLayout::IsAboveSplitter(const BPoint& point) const
{
return _SplitterItemAt(point) != NULL;
}
// StartDraggingSplitter // StartDraggingSplitter
bool bool
BSplitLayout::StartDraggingSplitter(BPoint point) BSplitLayout::StartDraggingSplitter(BPoint point)
@@ -568,19 +575,15 @@ BSplitLayout::StartDraggingSplitter(BPoint point)
return false; return false;
} }
int32 splitterCount = fSplitterItems.CountItems(); int32 index;
for (int32 i = 0; i < splitterCount; i++) { if (SplitterItem* splitItem = _SplitterItemAt(point, &index)) {
SplitterItem* splitItem = _SplitterItemAt(i);
BRect frame = splitItem->Frame();
if (frame.Contains(point)) {
fDraggingStartPoint = View()->ConvertToScreen(point); fDraggingStartPoint = View()->ConvertToScreen(point);
fDraggingStartValue = _SplitterValue(i); fDraggingStartValue = _SplitterValue(index);
fDraggingCurrentValue = fDraggingStartValue; fDraggingCurrentValue = fDraggingStartValue;
fDraggingSplitterIndex = i; fDraggingSplitterIndex = index;
return true; return true;
} }
}
return false; return false;
} }
@@ -690,6 +693,23 @@ BSplitLayout::_InvalidateCachedHeightForWidth()
fHeightForWidthVerticalLayouterWidth = -2; 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 // _SplitterItemAt
BSplitLayout::SplitterItem* BSplitLayout::SplitterItem*
BSplitLayout::_SplitterItemAt(int32 index) const BSplitLayout::_SplitterItemAt(int32 index) const
+3
View File
@@ -80,6 +80,7 @@ public:
// interface for BSplitView // interface for BSplitView
BRect SplitterItemFrame(int32 index) const; BRect SplitterItemFrame(int32 index) const;
bool IsAboveSplitter(const BPoint& point) const;
bool StartDraggingSplitter(BPoint point); bool StartDraggingSplitter(BPoint point);
bool DragSplitter(BPoint point); bool DragSplitter(BPoint point);
@@ -98,6 +99,8 @@ private:
void _InvalidateLayout(bool invalidateView); void _InvalidateLayout(bool invalidateView);
void _InvalidateCachedHeightForWidth(); void _InvalidateCachedHeightForWidth();
SplitterItem* _SplitterItemAt(const BPoint& point,
int32* index = NULL) const;
SplitterItem* _SplitterItemAt(int32 index) const; SplitterItem* _SplitterItemAt(int32 index) const;
void _GetSplitterValueRange(int32 index, void _GetSplitterValueRange(int32 index,
+63 -11
View File
@@ -5,12 +5,45 @@
#include <SplitView.h> #include <SplitView.h>
#include <stdio.h>
#include <ControlLook.h>
#include <Cursor.h>
#include "SplitLayout.h" #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 // constructor
BSplitView::BSplitView(enum orientation orientation, float spacing) BSplitView::BSplitView(enum orientation orientation, float spacing)
: BView(NULL, :
BView(NULL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT,
fSplitLayout = new BSplitLayout(orientation, spacing)) fSplitLayout = new BSplitLayout(orientation, spacing))
{ {
@@ -136,7 +169,8 @@ BSplitView::Draw(BRect updateRect)
int32 count = fSplitLayout->CountItems(); int32 count = fSplitLayout->CountItems();
for (int32 i = 0; i < count - 1; i++) { for (int32 i = 0; i < count - 1; i++) {
BRect frame = fSplitLayout->SplitterItemFrame(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 void
BSplitView::MouseDown(BPoint where) 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)) if (fSplitLayout->StartDraggingSplitter(where))
Invalidate(); Invalidate();
@@ -164,7 +199,17 @@ BSplitView::MouseUp(BPoint where)
void void
BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
{ {
BCursor cursor(B_CURSOR_SYSTEM_DEFAULT);
int32 splitterIndex = fSplitLayout->DraggedSplitter(); int32 splitterIndex = fSplitLayout->DraggedSplitter();
if (splitterIndex >= 0 || fSplitLayout->IsAboveSplitter(where)) {
if (Orientation() == B_VERTICAL)
cursor = BCursor(kVSplitterCursor);
else
cursor = BCursor(kHSplitterCursor);
}
if (splitterIndex >= 0) { if (splitterIndex >= 0) {
BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex); BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex);
if (fSplitLayout->DragSplitter(where)) { if (fSplitLayout->DragSplitter(where)) {
@@ -172,6 +217,8 @@ BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex)); Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex));
} }
} }
SetViewCursor(&cursor, true);
} }
// SetLayout // SetLayout
@@ -183,13 +230,18 @@ BSplitView::SetLayout(BLayout* layout)
// DrawSplitter // DrawSplitter
void void
BSplitView::DrawSplitter(BRect frame, enum orientation orientation, BSplitView::DrawSplitter(BRect frame, const BRect& updateRect,
bool pressed) enum orientation orientation, bool pressed)
{ {
rgb_color black = { 0, 0, 0, 255 }; _DrawDefaultSplitter(this, frame, updateRect, orientation, pressed);
rgb_color white = { 255, 255, 255, 255 }; }
SetHighColor(pressed ? white : black); // _DrawDefaultSplitter
void
FillRect(frame); 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);
} }