1/* 2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * Copyright 2015, Haiku, Inc. 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7#include <SplitView.h> 8 9#include <stdio.h> 10 11#include <Archivable.h> 12#include <ControlLook.h> 13#include <Cursor.h> 14 15#include "SplitLayout.h" 16 17 18BSplitView::BSplitView(orientation orientation, float spacing) 19 : 20 BView(NULL, 21 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT, 22 fSplitLayout = new BSplitLayout(orientation, spacing)) 23{ 24} 25 26 27BSplitView::BSplitView(BMessage* from) 28 : 29 BView(BUnarchiver::PrepareArchive(from)), 30 fSplitLayout(NULL) 31{ 32 BUnarchiver(from).Finish(); 33} 34 35 36BSplitView::~BSplitView() 37{ 38} 39 40 41void 42BSplitView::SetInsets(float left, float top, float right, float bottom) 43{ 44 left = BControlLook::ComposeSpacing(left); 45 top = BControlLook::ComposeSpacing(top); 46 right = BControlLook::ComposeSpacing(right); 47 bottom = BControlLook::ComposeSpacing(bottom); 48 49 fSplitLayout->SetInsets(left, top, right, bottom); 50} 51 52 53void 54BSplitView::SetInsets(float horizontal, float vertical) 55{ 56 horizontal = BControlLook::ComposeSpacing(horizontal); 57 vertical = BControlLook::ComposeSpacing(vertical); 58 fSplitLayout->SetInsets(horizontal, vertical, horizontal, vertical); 59} 60 61 62void 63BSplitView::SetInsets(float insets) 64{ 65 insets = BControlLook::ComposeSpacing(insets); 66 fSplitLayout->SetInsets(insets, insets, insets, insets); 67} 68 69 70void 71BSplitView::GetInsets(float* left, float* top, float* right, 72 float* bottom) const 73{ 74 fSplitLayout->GetInsets(left, top, right, bottom); 75} 76 77 78float 79BSplitView::Spacing() const 80{ 81 return fSplitLayout->Spacing(); 82} 83 84 85void 86BSplitView::SetSpacing(float spacing) 87{ 88 fSplitLayout->SetSpacing(spacing); 89} 90 91 92orientation 93BSplitView::Orientation() const 94{ 95 return fSplitLayout->Orientation(); 96} 97 98 99void 100BSplitView::SetOrientation(orientation orientation) 101{ 102 fSplitLayout->SetOrientation(orientation); 103} 104 105 106float 107BSplitView::SplitterSize() const 108{ 109 return fSplitLayout->SplitterSize(); 110} 111 112 113void 114BSplitView::SetSplitterSize(float size) 115{ 116 fSplitLayout->SetSplitterSize(size); 117} 118 119 120int32 121BSplitView::CountItems() const 122{ 123 return fSplitLayout->CountItems(); 124} 125 126 127float 128BSplitView::ItemWeight(int32 index) const 129{ 130 return fSplitLayout->ItemWeight(index); 131} 132 133 134float 135BSplitView::ItemWeight(BLayoutItem* item) const 136{ 137 return fSplitLayout->ItemWeight(item); 138} 139 140 141void 142BSplitView::SetItemWeight(int32 index, float weight, bool invalidateLayout) 143{ 144 fSplitLayout->SetItemWeight(index, weight, invalidateLayout); 145} 146 147 148void 149BSplitView::SetItemWeight(BLayoutItem* item, float weight) 150{ 151 fSplitLayout->SetItemWeight(item, weight); 152} 153 154 155bool 156BSplitView::IsCollapsible(int32 index) const 157{ 158 return fSplitLayout->IsCollapsible(index); 159} 160 161 162void 163BSplitView::SetCollapsible(bool collapsible) 164{ 165 fSplitLayout->SetCollapsible(collapsible); 166} 167 168 169void 170BSplitView::SetCollapsible(int32 index, bool collapsible) 171{ 172 fSplitLayout->SetCollapsible(index, collapsible); 173} 174 175 176void 177BSplitView::SetCollapsible(int32 first, int32 last, bool collapsible) 178{ 179 fSplitLayout->SetCollapsible(first, last, collapsible); 180} 181 182 183bool 184BSplitView::IsItemCollapsed(int32 index) const 185{ 186 return fSplitLayout->IsItemCollapsed(index); 187} 188 189 190void 191BSplitView::SetItemCollapsed(int32 index, bool collapsed) 192{ 193 fSplitLayout->SetItemCollapsed(index, collapsed); 194} 195 196 197void 198BSplitView::AddChild(BView* child, BView* sibling) 199{ 200 BView::AddChild(child, sibling); 201} 202 203 204bool 205BSplitView::AddChild(BView* child, float weight) 206{ 207 return fSplitLayout->AddView(child, weight); 208} 209 210 211bool 212BSplitView::AddChild(int32 index, BView* child, float weight) 213{ 214 return fSplitLayout->AddView(index, child, weight); 215} 216 217 218bool 219BSplitView::AddChild(BLayoutItem* child) 220{ 221 return fSplitLayout->AddItem(child); 222} 223 224 225bool 226BSplitView::AddChild(BLayoutItem* child, float weight) 227{ 228 return fSplitLayout->AddItem(child, weight); 229} 230 231 232bool 233BSplitView::AddChild(int32 index, BLayoutItem* child, float weight) 234{ 235 return fSplitLayout->AddItem(index, child, weight); 236} 237 238 239void 240BSplitView::AttachedToWindow() 241{ 242 AdoptParentColors(); 243} 244 245 246void 247BSplitView::Draw(BRect updateRect) 248{ 249 // draw the splitters 250 int32 draggedSplitterIndex = fSplitLayout->DraggedSplitter(); 251 int32 count = fSplitLayout->CountItems(); 252 for (int32 i = 0; i < count - 1; i++) { 253 BRect frame = fSplitLayout->SplitterItemFrame(i); 254 DrawSplitter(frame, updateRect, Orientation(), 255 draggedSplitterIndex == i); 256 } 257} 258 259 260void 261BSplitView::DrawAfterChildren(BRect r) 262{ 263 return BView::DrawAfterChildren(r); 264} 265 266 267void 268BSplitView::MouseDown(BPoint where) 269{ 270 SetMouseEventMask(B_POINTER_EVENTS, 271 B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS); 272 273 if (fSplitLayout->StartDraggingSplitter(where)) 274 Invalidate(); 275} 276 277 278void 279BSplitView::MouseUp(BPoint where) 280{ 281 if (fSplitLayout->StopDraggingSplitter()) { 282 Relayout(); 283 Invalidate(); 284 } 285} 286 287 288void 289BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) 290{ 291 BCursor cursor(B_CURSOR_ID_SYSTEM_DEFAULT); 292 293 int32 splitterIndex = fSplitLayout->DraggedSplitter(); 294 295 if (splitterIndex >= 0 || fSplitLayout->IsAboveSplitter(where)) { 296 if (Orientation() == B_VERTICAL) 297 cursor = BCursor(B_CURSOR_ID_RESIZE_NORTH_SOUTH); 298 else 299 cursor = BCursor(B_CURSOR_ID_RESIZE_EAST_WEST); 300 } 301 302 if (splitterIndex >= 0) { 303 BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex); 304 if (fSplitLayout->DragSplitter(where)) { 305 Invalidate(oldFrame); 306 Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex)); 307 } 308 } 309 310 SetViewCursor(&cursor, true); 311} 312 313 314void 315BSplitView::MessageReceived(BMessage* message) 316{ 317 return BView::MessageReceived(message); 318} 319 320 321void 322BSplitView::SetLayout(BLayout* layout) 323{ 324 // not allowed 325} 326 327 328status_t 329BSplitView::Archive(BMessage* into, bool deep) const 330{ 331 return BView::Archive(into, deep); 332} 333 334 335status_t 336BSplitView::AllArchived(BMessage* archive) const 337{ 338 return BView::AllArchived(archive); 339} 340 341 342status_t 343BSplitView::AllUnarchived(const BMessage* from) 344{ 345 status_t err = BView::AllUnarchived(from); 346 if (err == B_OK) { 347 fSplitLayout = dynamic_cast<BSplitLayout*>(GetLayout()); 348 if (!fSplitLayout && GetLayout()) 349 return B_BAD_TYPE; 350 else if (!fSplitLayout) 351 return B_ERROR; 352 } 353 return err; 354} 355 356 357BArchivable* 358BSplitView::Instantiate(BMessage* from) 359{ 360 if (validate_instantiation(from, "BSplitView")) 361 return new BSplitView(from); 362 return NULL; 363} 364 365 366void 367BSplitView::DrawSplitter(BRect frame, const BRect& updateRect, 368 orientation orientation, bool pressed) 369{ 370 _DrawDefaultSplitter(this, frame, updateRect, orientation, pressed); 371} 372 373 374void 375BSplitView::_DrawDefaultSplitter(BView* view, BRect frame, 376 const BRect& updateRect, orientation orientation, bool pressed) 377{ 378 uint32 flags = pressed ? BControlLook::B_ACTIVATED : 0; 379 be_control_look->DrawSplitter(view, frame, updateRect, view->ViewColor(), 380 orientation, flags, 0); 381} 382 383 384status_t 385BSplitView::Perform(perform_code d, void* arg) 386{ 387 return BView::Perform(d, arg); 388} 389 390 391void BSplitView::_ReservedSplitView1() {} 392void BSplitView::_ReservedSplitView2() {} 393void BSplitView::_ReservedSplitView3() {} 394void BSplitView::_ReservedSplitView4() {} 395void BSplitView::_ReservedSplitView5() {} 396void BSplitView::_ReservedSplitView6() {} 397void BSplitView::_ReservedSplitView7() {} 398void BSplitView::_ReservedSplitView8() {} 399void BSplitView::_ReservedSplitView9() {} 400void BSplitView::_ReservedSplitView10() {} 401 402