xref: /haiku/src/kits/interface/SplitView.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 
18 BSplitView::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 
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 	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 
53 void
54 BSplitView::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 
62 void
63 BSplitView::SetInsets(float insets)
64 {
65 	insets = BControlLook::ComposeSpacing(insets);
66 	fSplitLayout->SetInsets(insets, insets, insets, insets);
67 }
68 
69 
70 void
71 BSplitView::GetInsets(float* left, float* top, float* right,
72 	float* bottom) const
73 {
74 	fSplitLayout->GetInsets(left, top, right, bottom);
75 }
76 
77 
78 float
79 BSplitView::Spacing() const
80 {
81 	return fSplitLayout->Spacing();
82 }
83 
84 
85 void
86 BSplitView::SetSpacing(float spacing)
87 {
88 	fSplitLayout->SetSpacing(spacing);
89 }
90 
91 
92 orientation
93 BSplitView::Orientation() const
94 {
95 	return fSplitLayout->Orientation();
96 }
97 
98 
99 void
100 BSplitView::SetOrientation(orientation orientation)
101 {
102 	fSplitLayout->SetOrientation(orientation);
103 }
104 
105 
106 float
107 BSplitView::SplitterSize() const
108 {
109 	return fSplitLayout->SplitterSize();
110 }
111 
112 
113 void
114 BSplitView::SetSplitterSize(float size)
115 {
116 	fSplitLayout->SetSplitterSize(size);
117 }
118 
119 
120 int32
121 BSplitView::CountItems() const
122 {
123 	return fSplitLayout->CountItems();
124 }
125 
126 
127 float
128 BSplitView::ItemWeight(int32 index) const
129 {
130 	return fSplitLayout->ItemWeight(index);
131 }
132 
133 
134 float
135 BSplitView::ItemWeight(BLayoutItem* item) const
136 {
137 	return fSplitLayout->ItemWeight(item);
138 }
139 
140 
141 void
142 BSplitView::SetItemWeight(int32 index, float weight, bool invalidateLayout)
143 {
144 	fSplitLayout->SetItemWeight(index, weight, invalidateLayout);
145 }
146 
147 
148 void
149 BSplitView::SetItemWeight(BLayoutItem* item, float weight)
150 {
151 	fSplitLayout->SetItemWeight(item, weight);
152 }
153 
154 
155 bool
156 BSplitView::IsCollapsible(int32 index) const
157 {
158 	return fSplitLayout->IsCollapsible(index);
159 }
160 
161 
162 void
163 BSplitView::SetCollapsible(bool collapsible)
164 {
165 	fSplitLayout->SetCollapsible(collapsible);
166 }
167 
168 
169 void
170 BSplitView::SetCollapsible(int32 index, bool collapsible)
171 {
172 	fSplitLayout->SetCollapsible(index, collapsible);
173 }
174 
175 
176 void
177 BSplitView::SetCollapsible(int32 first, int32 last, bool collapsible)
178 {
179 	fSplitLayout->SetCollapsible(first, last, collapsible);
180 }
181 
182 
183 bool
184 BSplitView::IsItemCollapsed(int32 index) const
185 {
186 	return fSplitLayout->IsItemCollapsed(index);
187 }
188 
189 
190 void
191 BSplitView::SetItemCollapsed(int32 index, bool collapsed)
192 {
193 	fSplitLayout->SetItemCollapsed(index, collapsed);
194 }
195 
196 
197 void
198 BSplitView::AddChild(BView* child, BView* sibling)
199 {
200 	BView::AddChild(child, sibling);
201 }
202 
203 
204 bool
205 BSplitView::AddChild(BView* child, float weight)
206 {
207 	return fSplitLayout->AddView(child, weight);
208 }
209 
210 
211 bool
212 BSplitView::AddChild(int32 index, BView* child, float weight)
213 {
214 	return fSplitLayout->AddView(index, child, weight);
215 }
216 
217 
218 bool
219 BSplitView::AddChild(BLayoutItem* child)
220 {
221 	return fSplitLayout->AddItem(child);
222 }
223 
224 
225 bool
226 BSplitView::AddChild(BLayoutItem* child, float weight)
227 {
228 	return fSplitLayout->AddItem(child, weight);
229 }
230 
231 
232 bool
233 BSplitView::AddChild(int32 index, BLayoutItem* child, float weight)
234 {
235 	return fSplitLayout->AddItem(index, child, weight);
236 }
237 
238 
239 void
240 BSplitView::AttachedToWindow()
241 {
242 	AdoptParentColors();
243 }
244 
245 
246 void
247 BSplitView::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 
260 void
261 BSplitView::DrawAfterChildren(BRect r)
262 {
263 	return BView::DrawAfterChildren(r);
264 }
265 
266 
267 void
268 BSplitView::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 
278 void
279 BSplitView::MouseUp(BPoint where)
280 {
281 	if (fSplitLayout->StopDraggingSplitter()) {
282 		Relayout();
283 		Invalidate();
284 	}
285 }
286 
287 
288 void
289 BSplitView::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 
314 void
315 BSplitView::MessageReceived(BMessage* message)
316 {
317 	return BView::MessageReceived(message);
318 }
319 
320 
321 void
322 BSplitView::SetLayout(BLayout* layout)
323 {
324 	// not allowed
325 }
326 
327 
328 status_t
329 BSplitView::Archive(BMessage* into, bool deep) const
330 {
331 	return BView::Archive(into, deep);
332 }
333 
334 
335 status_t
336 BSplitView::AllArchived(BMessage* archive) const
337 {
338 	return BView::AllArchived(archive);
339 }
340 
341 
342 status_t
343 BSplitView::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 
357 BArchivable*
358 BSplitView::Instantiate(BMessage* from)
359 {
360 	if (validate_instantiation(from, "BSplitView"))
361 		return new BSplitView(from);
362 	return NULL;
363 }
364 
365 
366 void
367 BSplitView::DrawSplitter(BRect frame, const BRect& updateRect,
368 	orientation orientation, bool pressed)
369 {
370 	_DrawDefaultSplitter(this, frame, updateRect, orientation, pressed);
371 }
372 
373 
374 void
375 BSplitView::_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 
384 status_t
385 BSplitView::Perform(perform_code d, void* arg)
386 {
387 	return BView::Perform(d, arg);
388 }
389 
390 
391 void BSplitView::_ReservedSplitView1() {}
392 void BSplitView::_ReservedSplitView2() {}
393 void BSplitView::_ReservedSplitView3() {}
394 void BSplitView::_ReservedSplitView4() {}
395 void BSplitView::_ReservedSplitView5() {}
396 void BSplitView::_ReservedSplitView6() {}
397 void BSplitView::_ReservedSplitView7() {}
398 void BSplitView::_ReservedSplitView8() {}
399 void BSplitView::_ReservedSplitView9() {}
400 void BSplitView::_ReservedSplitView10() {}
401 
402