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 <Archivable.h> 11 #include <ControlLook.h> 12 #include <Cursor.h> 13 14 #include "SplitLayout.h" 15 16 17 BSplitView::BSplitView(enum orientation orientation, float spacing) 18 : 19 BView(NULL, 20 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INVALIDATE_AFTER_LAYOUT, 21 fSplitLayout = new BSplitLayout(orientation, spacing)) 22 { 23 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 24 } 25 26 27 BSplitView::BSplitView(BMessage* from) 28 : 29 BView(BUnarchiver::PrepareArchive(from)), 30 fSplitLayout(NULL) 31 { 32 BUnarchiver(from).Finish(); 33 } 34 35 36 BSplitView::~BSplitView() 37 { 38 } 39 40 41 void 42 BSplitView::SetInsets(float left, float top, float right, float bottom) 43 { 44 fSplitLayout->SetInsets(left, top, right, bottom); 45 } 46 47 48 void 49 BSplitView::GetInsets(float* left, float* top, float* right, 50 float* bottom) const 51 { 52 fSplitLayout->GetInsets(left, top, right, bottom); 53 } 54 55 56 float 57 BSplitView::Spacing() const 58 { 59 return fSplitLayout->Spacing(); 60 } 61 62 63 void 64 BSplitView::SetSpacing(float spacing) 65 { 66 fSplitLayout->SetSpacing(spacing); 67 } 68 69 70 orientation 71 BSplitView::Orientation() const 72 { 73 return fSplitLayout->Orientation(); 74 } 75 76 77 void 78 BSplitView::SetOrientation(enum orientation orientation) 79 { 80 fSplitLayout->SetOrientation(orientation); 81 } 82 83 84 float 85 BSplitView::SplitterSize() const 86 { 87 return fSplitLayout->SplitterSize(); 88 } 89 90 91 void 92 BSplitView::SetSplitterSize(float size) 93 { 94 fSplitLayout->SetSplitterSize(size); 95 } 96 97 98 void 99 BSplitView::SetCollapsible(bool collapsible) 100 { 101 fSplitLayout->SetCollapsible(collapsible); 102 } 103 104 105 void 106 BSplitView::SetCollapsible(int32 index, bool collapsible) 107 { 108 fSplitLayout->SetCollapsible(index, collapsible); 109 } 110 111 112 void 113 BSplitView::SetCollapsible(int32 first, int32 last, bool collapsible) 114 { 115 fSplitLayout->SetCollapsible(first, last, collapsible); 116 } 117 118 119 void 120 BSplitView::AddChild(BView* child, BView* sibling) 121 { 122 BView::AddChild(child, sibling); 123 } 124 125 126 bool 127 BSplitView::AddChild(BView* child, float weight) 128 { 129 return fSplitLayout->AddView(child, weight); 130 } 131 132 133 bool 134 BSplitView::AddChild(int32 index, BView* child, float weight) 135 { 136 return fSplitLayout->AddView(index, child, weight); 137 } 138 139 140 bool 141 BSplitView::AddChild(BLayoutItem* child) 142 { 143 return fSplitLayout->AddItem(child); 144 } 145 146 147 bool 148 BSplitView::AddChild(BLayoutItem* child, float weight) 149 { 150 return fSplitLayout->AddItem(child, weight); 151 } 152 153 154 bool 155 BSplitView::AddChild(int32 index, BLayoutItem* child, float weight) 156 { 157 return fSplitLayout->AddItem(index, child, weight); 158 } 159 160 161 void 162 BSplitView::Draw(BRect updateRect) 163 { 164 // draw the splitters 165 int32 draggedSplitterIndex = fSplitLayout->DraggedSplitter(); 166 int32 count = fSplitLayout->CountItems(); 167 for (int32 i = 0; i < count - 1; i++) { 168 BRect frame = fSplitLayout->SplitterItemFrame(i); 169 DrawSplitter(frame, updateRect, Orientation(), 170 draggedSplitterIndex == i); 171 } 172 } 173 174 175 void 176 BSplitView::MouseDown(BPoint where) 177 { 178 SetMouseEventMask(B_POINTER_EVENTS, 179 B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS); 180 181 if (fSplitLayout->StartDraggingSplitter(where)) 182 Invalidate(); 183 } 184 185 186 void 187 BSplitView::MouseUp(BPoint where) 188 { 189 if (fSplitLayout->StopDraggingSplitter()) { 190 Relayout(); 191 Invalidate(); 192 } 193 } 194 195 196 void 197 BSplitView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) 198 { 199 BCursor cursor(B_CURSOR_ID_SYSTEM_DEFAULT); 200 201 int32 splitterIndex = fSplitLayout->DraggedSplitter(); 202 203 if (splitterIndex >= 0 || fSplitLayout->IsAboveSplitter(where)) { 204 if (Orientation() == B_VERTICAL) 205 cursor = BCursor(B_CURSOR_ID_RESIZE_NORTH_SOUTH); 206 else 207 cursor = BCursor(B_CURSOR_ID_RESIZE_EAST_WEST); 208 } 209 210 if (splitterIndex >= 0) { 211 BRect oldFrame = fSplitLayout->SplitterItemFrame(splitterIndex); 212 if (fSplitLayout->DragSplitter(where)) { 213 Invalidate(oldFrame); 214 Invalidate(fSplitLayout->SplitterItemFrame(splitterIndex)); 215 } 216 } 217 218 SetViewCursor(&cursor, true); 219 } 220 221 222 void 223 BSplitView::SetLayout(BLayout* layout) 224 { 225 // not allowed 226 } 227 228 229 status_t 230 BSplitView::Archive(BMessage* into, bool deep) const 231 { 232 return BView::Archive(into, deep); 233 } 234 235 236 status_t 237 BSplitView::AllUnarchived(const BMessage* from) 238 { 239 status_t err = BView::AllUnarchived(from); 240 if (err == B_OK) { 241 fSplitLayout = dynamic_cast<BSplitLayout*>(GetLayout()); 242 if (!fSplitLayout && GetLayout()) 243 return B_BAD_TYPE; 244 else if (!fSplitLayout) 245 return B_ERROR; 246 } 247 return err; 248 } 249 250 251 BArchivable* 252 BSplitView::Instantiate(BMessage* from) 253 { 254 if (validate_instantiation(from, "BSplitView")) 255 return new BSplitView(from); 256 return NULL; 257 } 258 259 260 void 261 BSplitView::DrawSplitter(BRect frame, const BRect& updateRect, 262 enum orientation orientation, bool pressed) 263 { 264 _DrawDefaultSplitter(this, frame, updateRect, orientation, pressed); 265 } 266 267 268 void 269 BSplitView::_DrawDefaultSplitter(BView* view, BRect frame, 270 const BRect& updateRect, enum orientation orientation, bool pressed) 271 { 272 uint32 flags = pressed ? BControlLook::B_ACTIVATED : 0; 273 be_control_look->DrawSplitter(view, frame, updateRect, view->ViewColor(), 274 orientation, flags, 0); 275 } 276