SectionEdit.cpp revision 420e9637
1fd7c0c2eSStephan Aßmus/*
2fd7c0c2eSStephan Aßmus * Copyright 2004-2007, Haiku, Inc. All Rights Reserved.
3fd7c0c2eSStephan Aßmus * Distributed under the terms of the MIT License.
4fd7c0c2eSStephan Aßmus *
5fd7c0c2eSStephan Aßmus * Authors:
600826781SKarsten Heimrich *		Mike Berg <mike@berg-net.us>
7fd7c0c2eSStephan Aßmus *		Julun <host.haiku@gmx.de>
8fd7c0c2eSStephan Aßmus *
9fd7c0c2eSStephan Aßmus */
1026c008b7SPhil Greenway
1126c008b7SPhil Greenway#include "SectionEdit.h"
1226c008b7SPhil Greenway
13fd7c0c2eSStephan Aßmus#include <Bitmap.h>
1402b73236SAxel Dörfler#include <ControlLook.h>
15fd7c0c2eSStephan Aßmus#include <List.h>
16fd7c0c2eSStephan Aßmus#include <Window.h>
1726c008b7SPhil Greenway
1802b73236SAxel Dörfler#include "TimeMessages.h"
1902b73236SAxel Dörfler
2026c008b7SPhil Greenway
216d6408d6SOliver TappeTSection::TSection(BRect frame)
226d6408d6SOliver Tappe	:
236d6408d6SOliver Tappe	fFrame(frame)
246d6408d6SOliver Tappe{
256d6408d6SOliver Tappe}
266d6408d6SOliver Tappe
276d6408d6SOliver Tappe
286d6408d6SOliver TappeBRect
296d6408d6SOliver TappeTSection::Bounds() const
306d6408d6SOliver Tappe{
316d6408d6SOliver Tappe	BRect frame(fFrame);
326d6408d6SOliver Tappe	return frame.OffsetByCopy(B_ORIGIN);
336d6408d6SOliver Tappe}
346d6408d6SOliver Tappe
356d6408d6SOliver Tappe
366d6408d6SOliver Tappevoid
376d6408d6SOliver TappeTSection::SetFrame(BRect frame)
386d6408d6SOliver Tappe{
396d6408d6SOliver Tappe	fFrame = frame;
406d6408d6SOliver Tappe}
416d6408d6SOliver Tappe
426d6408d6SOliver Tappe
436d6408d6SOliver TappeBRect
446d6408d6SOliver TappeTSection::Frame() const
456d6408d6SOliver Tappe{
466d6408d6SOliver Tappe	return fFrame;
476d6408d6SOliver Tappe}
486d6408d6SOliver Tappe
496d6408d6SOliver Tappe
50fd7c0c2eSStephan Aßmusconst uint32 kArrowAreaWidth = 16;
5126c008b7SPhil Greenway
5226c008b7SPhil Greenway
536d6408d6SOliver TappeTSectionEdit::TSectionEdit(BRect frame, const char* name, uint32 sections)
5402b73236SAxel Dörfler	:
5502b73236SAxel Dörfler	BControl(frame, name, NULL, NULL, B_FOLLOW_NONE, B_NAVIGABLE | B_WILL_DRAW),
5602b73236SAxel Dörfler	fSectionList(NULL),
5702b73236SAxel Dörfler	fFocus(-1),
58420e9637SOliver Tappe	fSectionCount(sections),
59420e9637SOliver Tappe	fHoldValue(0)
6026c008b7SPhil Greenway{
6126c008b7SPhil Greenway	InitView();
6226c008b7SPhil Greenway}
6326c008b7SPhil Greenway
6426c008b7SPhil Greenway
6526c008b7SPhil GreenwayTSectionEdit::~TSectionEdit()
6626c008b7SPhil Greenway{
67fd7c0c2eSStephan Aßmus	int32 count = fSectionList->CountItems();
68fd7c0c2eSStephan Aßmus	if (count > 0) {
69fd7c0c2eSStephan Aßmus		for (int32 index = 0; index < count; index++)
70fd7c0c2eSStephan Aßmus			delete (TSection*)fSectionList->ItemAt(index);
71fd7c0c2eSStephan Aßmus	}
72fd7c0c2eSStephan Aßmus	delete fSectionList;
7326c008b7SPhil Greenway}
7426c008b7SPhil Greenway
7526c008b7SPhil Greenway
7626c008b7SPhil Greenwayvoid
7726c008b7SPhil GreenwayTSectionEdit::AttachedToWindow()
7826c008b7SPhil Greenway{
7902b73236SAxel Dörfler	if (Parent())
8026c008b7SPhil Greenway		SetViewColor(Parent()->ViewColor());
8126c008b7SPhil Greenway}
8226c008b7SPhil Greenway
8326c008b7SPhil Greenway
8426c008b7SPhil Greenwayvoid
8500826781SKarsten HeimrichTSectionEdit::Draw(BRect updateRect)
8626c008b7SPhil Greenway{
8702b73236SAxel Dörfler	DrawBorder(updateRect);
8802b73236SAxel Dörfler
8900826781SKarsten Heimrich	for (uint32 idx = 0; idx < fSectionCount; idx++) {
90fd7c0c2eSStephan Aßmus		DrawSection(idx, ((uint32)fFocus == idx) && IsFocus());
9100826781SKarsten Heimrich		if (idx < fSectionCount -1)
9202b73236SAxel Dörfler			DrawSeparator(idx);
9326c008b7SPhil Greenway	}
9426c008b7SPhil Greenway}
9526c008b7SPhil Greenway
9626c008b7SPhil Greenway
9726c008b7SPhil Greenwayvoid
9826c008b7SPhil GreenwayTSectionEdit::MouseDown(BPoint where)
9926c008b7SPhil Greenway{
10026c008b7SPhil Greenway	MakeFocus(true);
10102b73236SAxel Dörfler
102fd7c0c2eSStephan Aßmus	if (fUpRect.Contains(where))
10326c008b7SPhil Greenway		DoUpPress();
104fd7c0c2eSStephan Aßmus	else if (fDownRect.Contains(where))
10526c008b7SPhil Greenway		DoDownPress();
106fd7c0c2eSStephan Aßmus	else if (fSectionList->CountItems()> 0) {
1076d6408d6SOliver Tappe		TSection* section;
108fd7c0c2eSStephan Aßmus		for (uint32 idx = 0; idx < fSectionCount; idx++) {
1096d6408d6SOliver Tappe			section = (TSection*)fSectionList->ItemAt(idx);
11026c008b7SPhil Greenway			if (section->Frame().Contains(where)) {
11126c008b7SPhil Greenway				SectionFocus(idx);
11226c008b7SPhil Greenway				return;
11326c008b7SPhil Greenway			}
11402b73236SAxel Dörfler		}
11526c008b7SPhil Greenway	}
11626c008b7SPhil Greenway}
11726c008b7SPhil Greenway
11826c008b7SPhil Greenway
11900826781SKarsten Heimrichvoid
12000826781SKarsten HeimrichTSectionEdit::MakeFocus(bool focused)
12100826781SKarsten Heimrich{
12200826781SKarsten Heimrich	if (focused == IsFocus())
12300826781SKarsten Heimrich		return;
12400826781SKarsten Heimrich
12500826781SKarsten Heimrich	BControl::MakeFocus(focused);
12602b73236SAxel Dörfler
12700826781SKarsten Heimrich	if (fFocus == -1)
12800826781SKarsten Heimrich		SectionFocus(0);
12900826781SKarsten Heimrich	else
13000826781SKarsten Heimrich		SectionFocus(fFocus);
13100826781SKarsten Heimrich}
13200826781SKarsten Heimrich
13300826781SKarsten Heimrich
13426c008b7SPhil Greenwayvoid
1356d6408d6SOliver TappeTSectionEdit::KeyDown(const char* bytes, int32 numbytes)
13626c008b7SPhil Greenway{
137fd7c0c2eSStephan Aßmus	if (fFocus == -1)
13826c008b7SPhil Greenway		SectionFocus(0);
13902b73236SAxel Dörfler
14026c008b7SPhil Greenway	switch (bytes[0]) {
14126c008b7SPhil Greenway		case B_LEFT_ARROW:
142fd7c0c2eSStephan Aßmus			fFocus -= 1;
143fd7c0c2eSStephan Aßmus			if (fFocus < 0)
144fd7c0c2eSStephan Aßmus				fFocus = fSectionCount -1;
145fd7c0c2eSStephan Aßmus			SectionFocus(fFocus);
14602b73236SAxel Dörfler			break;
14702b73236SAxel Dörfler
14826c008b7SPhil Greenway		case B_RIGHT_ARROW:
149fd7c0c2eSStephan Aßmus			fFocus += 1;
150fd7c0c2eSStephan Aßmus			if ((uint32)fFocus >= fSectionCount)
151fd7c0c2eSStephan Aßmus				fFocus = 0;
152fd7c0c2eSStephan Aßmus			SectionFocus(fFocus);
15302b73236SAxel Dörfler			break;
15402b73236SAxel Dörfler
15526c008b7SPhil Greenway		case B_UP_ARROW:
15626c008b7SPhil Greenway			DoUpPress();
15702b73236SAxel Dörfler			break;
15802b73236SAxel Dörfler
15926c008b7SPhil Greenway		case B_DOWN_ARROW:
16026c008b7SPhil Greenway			DoDownPress();
16102b73236SAxel Dörfler			break;
16202b73236SAxel Dörfler
16326c008b7SPhil Greenway		default:
16426c008b7SPhil Greenway			BControl::KeyDown(bytes, numbytes);
16502b73236SAxel Dörfler			break;
16626c008b7SPhil Greenway	}
16726c008b7SPhil Greenway	Draw(Bounds());
16826c008b7SPhil Greenway}
16926c008b7SPhil Greenway
17026c008b7SPhil Greenway
17126c008b7SPhil Greenwayvoid
17226c008b7SPhil GreenwayTSectionEdit::DispatchMessage()
17326c008b7SPhil Greenway{
17400826781SKarsten Heimrich	BMessage message(H_USER_CHANGE);
17500826781SKarsten Heimrich	BuildDispatch(&message);
17600826781SKarsten Heimrich	Window()->PostMessage(&message);
17726c008b7SPhil Greenway}
17826c008b7SPhil Greenway
17926c008b7SPhil Greenway
18026c008b7SPhil Greenwayuint32
18126c008b7SPhil GreenwayTSectionEdit::CountSections() const
18226c008b7SPhil Greenway{
183fd7c0c2eSStephan Aßmus	return fSectionList->CountItems();
18426c008b7SPhil Greenway}
18526c008b7SPhil Greenway
18626c008b7SPhil Greenway
18726c008b7SPhil Greenwayint32
18826c008b7SPhil GreenwayTSectionEdit::FocusIndex() const
18926c008b7SPhil Greenway{
190fd7c0c2eSStephan Aßmus	return fFocus;
19126c008b7SPhil Greenway}
19226c008b7SPhil Greenway
19326c008b7SPhil Greenway
19426c008b7SPhil Greenwayvoid
19526c008b7SPhil GreenwayTSectionEdit::InitView()
19626c008b7SPhil Greenway{
19726c008b7SPhil Greenway	// setup sections
198fd7c0c2eSStephan Aßmus	fSectionList = new BList(fSectionCount);
199fd7c0c2eSStephan Aßmus	fSectionArea = Bounds().InsetByCopy(2, 2);
20002b73236SAxel Dörfler	fSectionArea.right -= kArrowAreaWidth;
20126c008b7SPhil Greenway}
20226c008b7SPhil Greenway
20326c008b7SPhil Greenway
20426c008b7SPhil Greenwayvoid
20502b73236SAxel DörflerTSectionEdit::DrawBorder(const BRect& updateRect)
20626c008b7SPhil Greenway{
20702b73236SAxel Dörfler	BRect bounds(Bounds());
208420e9637SOliver Tappe	bool showFocus = (IsFocus() && Window() && Window()->IsActive());
209fd7c0c2eSStephan Aßmus
21002b73236SAxel Dörfler	be_control_look->DrawBorder(this, bounds, updateRect, ViewColor(),
211420e9637SOliver Tappe		B_FANCY_BORDER, showFocus ? BControlLook::B_FOCUSED : 0);
21226c008b7SPhil Greenway
21302b73236SAxel Dörfler	// draw up/down control
21426c008b7SPhil Greenway
21502b73236SAxel Dörfler	bounds.left = bounds.right - kArrowAreaWidth;
21602b73236SAxel Dörfler	bounds.right = Bounds().right - 2;
21702b73236SAxel Dörfler	fUpRect.Set(bounds.left + 3, bounds.top + 2, bounds.right,
21802b73236SAxel Dörfler		bounds.bottom / 2.0);
21902b73236SAxel Dörfler	fDownRect = fUpRect.OffsetByCopy(0, fUpRect.Height() + 2);
22002b73236SAxel Dörfler
22102b73236SAxel Dörfler	BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2), fUpRect.top + 1);
22202b73236SAxel Dörfler	BPoint left(fUpRect.left + 3, fUpRect.bottom - 1);
22302b73236SAxel Dörfler	BPoint right(left.x + 2 * (middle.x - left.x), fUpRect.bottom - 1);
22402b73236SAxel Dörfler
22502b73236SAxel Dörfler	SetPenSize(2);
22602b73236SAxel Dörfler
22702b73236SAxel Dörfler	if (updateRect.Intersects(fUpRect)) {
22802b73236SAxel Dörfler		FillRect(fUpRect, B_SOLID_LOW);
22902b73236SAxel Dörfler		BeginLineArray(2);
23002b73236SAxel Dörfler			AddLine(left, middle, HighColor());
23102b73236SAxel Dörfler			AddLine(middle, right, HighColor());
23202b73236SAxel Dörfler		EndLineArray();
23302b73236SAxel Dörfler	}
23402b73236SAxel Dörfler	if (updateRect.Intersects(fDownRect)) {
23502b73236SAxel Dörfler		middle.y = fDownRect.bottom - 1;
23602b73236SAxel Dörfler		left.y = right.y = fDownRect.top + 1;
23702b73236SAxel Dörfler
23802b73236SAxel Dörfler		FillRect(fDownRect, B_SOLID_LOW);
23902b73236SAxel Dörfler		BeginLineArray(2);
24002b73236SAxel Dörfler			AddLine(left, middle, HighColor());
24102b73236SAxel Dörfler			AddLine(middle, right, HighColor());
24202b73236SAxel Dörfler		EndLineArray();
24326c008b7SPhil Greenway	}
24426c008b7SPhil Greenway
24502b73236SAxel Dörfler	SetPenSize(1);
24626c008b7SPhil Greenway}
24726c008b7SPhil Greenway
24826c008b7SPhil Greenway
249fd7c0c2eSStephan Aßmusfloat
25002b73236SAxel DörflerTSectionEdit::SeparatorWidth() const
25126c008b7SPhil Greenway{
252fd7c0c2eSStephan Aßmus	return 0.0f;
25326c008b7SPhil Greenway}
25426c008b7SPhil Greenway
255