1 /* 2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include <SplitView.h> 7 8 #include <stdio.h> 9 10 #include <ControlLook.h> 11 #include <Cursor.h> 12 13 #include "SplitLayout.h" 14 15 16 static const unsigned char kHSplitterCursor[] = { 17 16, 1, 8, 8, 18 0x03, 0xc0, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 19 0x1a, 0x58, 0x2a, 0x54, 0x4a, 0x52, 0x8a, 0x51, 20 0x8a, 0x51, 0x4a, 0x52, 0x2a, 0x54, 0x1a, 0x58, 21 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x03, 0xc0, 22 23 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 24 0x1b, 0xd8, 0x3b, 0xdc, 0x7b, 0xde, 0xfb, 0xdf, 25 0xfb, 0xdf, 0x7b, 0xde, 0x3b, 0xdc, 0x1b, 0xd8, 26 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0 27 }; 28 29 static const unsigned char kVSplitterCursor[] = { 30 16, 1, 8, 8, 31 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, 0x10, 32 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x01, 33 0x80, 0x01, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 34 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, 35 36 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 37 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 38 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 39 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80 40 }; 41 42 43 // constructor 44 BSplitView::BSplitView(enum orientation orientation, float spacing) 45 : 46 BView(NULL, 47 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT, 48 fSplitLayout = new BSplitLayout(orientation, spacing)) 49 { 50 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 51 } 52 53 // destructor 54 BSplitView::~BSplitView() 55 { 56 } 57 58 // SetInsets 59 void 60 BSplitView::SetInsets(float left, float top, float right, float bottom) 61 { 62 fSplitLayout->SetInsets(left, top, right, bottom); 63 } 64 65 // GetInsets 66 void 67 BSplitView::GetInsets(float* left, float* top, float* right, 68 float* bottom) const 69 { 70 fSplitLayout->GetInsets(left, top, right, bottom); 71 } 72 73 // Spacing 74 float 75 BSplitView::Spacing() const 76 { 77 return fSplitLayout->Spacing(); 78 } 79 80 // SetSpacing 81 void 82 BSplitView::SetSpacing(float spacing) 83 { 84 fSplitLayout->SetSpacing(spacing); 85 } 86 87 // Orientation 88 orientation 89 BSplitView::Orientation() const 90 { 91 return fSplitLayout->Orientation(); 92 } 93 94 // SetOrientation 95 void 96 BSplitView::SetOrientation(enum orientation orientation) 97 { 98 fSplitLayout->SetOrientation(orientation); 99 } 100 101 // SplitterSize 102 float 103 BSplitView::SplitterSize() const 104 { 105 return fSplitLayout->SplitterSize(); 106 } 107 108 // SetSplitterSize 109 void 110 BSplitView::SetSplitterSize(float size) 111 { 112 fSplitLayout->SetSplitterSize(size); 113 } 114 115 // SetCollapsible 116 void 117 BSplitView::SetCollapsible(bool collapsible) 118 { 119 fSplitLayout->SetCollapsible(collapsible); 120 } 121 122 // SetCollapsible 123 void 124 BSplitView::SetCollapsible(int32 index, bool collapsible) 125 { 126 fSplitLayout->SetCollapsible(index, collapsible); 127 } 128 129 // SetCollapsible 130 void 131 BSplitView::SetCollapsible(int32 first, int32 last, bool collapsible) 132 { 133 fSplitLayout->SetCollapsible(first, last, collapsible); 134 } 135 136 // AddChild 137 void 138 BSplitView::AddChild(BView* child, BView* sibling) 139 { 140 BView::AddChild(child, sibling); 141 } 142 143 // AddChild 144 bool 145 BSplitView::AddChild(BView* child, float weight) 146 { 147 return fSplitLayout->AddView(child, weight); 148 } 149 150 // AddChild 151 bool 152 BSplitView::AddChild(int32 index, BView* child, float weight) 153 { 154 return fSplitLayout->AddView(index, child, weight); 155 } 156 157 // AddChild 158 bool 159 BSplitView::AddChild(BLayoutItem* child) 160 { 161 return fSplitLayout->AddItem(child); 162 } 163 164 // AddChild 165 bool 166 BSplitView::AddChild(BLayoutItem* child, float weight) 167 { 168 return fSplitLayout->AddItem(child, weight); 169 } 170 171 // AddChild 172 bool 173 BSplitView::AddChild(int32 index, BLayoutItem* child, float weight) 174 { 175 return fSplitLayout->AddItem(index, child, weight); 176 } 177 178 // Draw 179 void 180 BSplitView::Draw(BRect updateRect) 181 { 182 // draw the splitters 183 int32 draggedSplitterIndex = fSplitLayout->DraggedSplitter(); 184 int32 count = fSplitLayout->CountItems(); 185 for (int32 i = 0; i < count - 1; i++) { 186 BRect frame = fSplitLayout->SplitterItemFrame(i); 187 DrawSplitter(frame, updateRect, Orientation(), 188 draggedSplitterIndex == i); 189 } 190 } 191 192 // MouseDown 193 void 194 BSplitView::MouseDown(BPoint where) 195 { 196 SetMouseEventMask(B_POINTER_EVENTS, 197 B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS); 198 199 if (fSplitLayout->StartDraggingSplitter(where)) 200 Invalidate(); 201 } 202 203 // MouseUp 204 void 205 BSplitView::MouseUp(BPoint where) 206 { 207 if (fSplitLayout->StopDraggingSplitter()) { 208 Relayout(); 209 Invalidate(); 210 } 211 } 212 213 // MouseMoved 214 void 215 BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) 216 { 217 BCursor cursor(B_CURSOR_SYSTEM_DEFAULT); 218 219 int32 splitterIndex = fSplitLayout->DraggedSplitter(); 220 221 if (splitterIndex >= 0 || fSplitLayout->IsAboveSplitter(where)) { 222 if (Orientation() == B_VERTICAL) 223 cursor = BCursor(kVSplitterCursor); 224 else 225 cursor = BCursor(kHSplitterCursor); 226 } 227 228 if (splitterIndex >= 0) { 229 BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex); 230 if (fSplitLayout->DragSplitter(where)) { 231 Invalidate(oldFrame); 232 Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex)); 233 } 234 } 235 236 SetViewCursor(&cursor, true); 237 } 238 239 // SetLayout 240 void 241 BSplitView::SetLayout(BLayout* layout) 242 { 243 // not allowed 244 } 245 246 // DrawSplitter 247 void 248 BSplitView::DrawSplitter(BRect frame, const BRect& updateRect, 249 enum orientation orientation, bool pressed) 250 { 251 _DrawDefaultSplitter(this, frame, updateRect, orientation, pressed); 252 } 253 254 // _DrawDefaultSplitter 255 void 256 BSplitView::_DrawDefaultSplitter(BView* view, BRect frame, 257 const BRect& updateRect, enum orientation orientation, bool pressed) 258 { 259 uint32 flags = pressed ? BControlLook::B_ACTIVATED : 0; 260 be_control_look->DrawSplitter(view, frame, updateRect, view->ViewColor(), 261 orientation, flags, 0); 262 } 263