xref: /haiku/src/apps/launchbox/PadView.cpp (revision ac966d59413e7f0f7395d42d499725f8d6414c3a)
125648ff0SStephan Aßmus /*
29368e58bSStephan Aßmus  * Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>.
39368e58bSStephan Aßmus  * All rights reserved. Distributed under the terms of the MIT License.
425648ff0SStephan Aßmus  */
525648ff0SStephan Aßmus 
625648ff0SStephan Aßmus #include "PadView.h"
725648ff0SStephan Aßmus 
825648ff0SStephan Aßmus #include <stdio.h>
925648ff0SStephan Aßmus 
1025648ff0SStephan Aßmus #include <Application.h>
110e07d4c0SAdrien Destugues #include <Catalog.h>
1225648ff0SStephan Aßmus #include <GroupLayout.h>
1325648ff0SStephan Aßmus #include <MenuItem.h>
1425648ff0SStephan Aßmus #include <Message.h>
1525648ff0SStephan Aßmus #include <PopUpMenu.h>
1625648ff0SStephan Aßmus #include <Region.h>
1725648ff0SStephan Aßmus #include <Screen.h>
1825648ff0SStephan Aßmus #include <SpaceLayoutItem.h>
1925648ff0SStephan Aßmus 
2025648ff0SStephan Aßmus #include "LaunchButton.h"
2125648ff0SStephan Aßmus #include "MainWindow.h"
2225648ff0SStephan Aßmus 
238d186370SStephan Aßmus 
24546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
25546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "LaunchBox"
260e07d4c0SAdrien Destugues 
270e07d4c0SAdrien Destugues 
28a6099ca9SStephan Aßmus static bigtime_t sActivationDelay = 40000;
29a6099ca9SStephan Aßmus static const uint32 kIconSizes[] = { 16, 20, 24, 32, 40, 48, 64 };
3025648ff0SStephan Aßmus 
318d186370SStephan Aßmus 
32f32e3a29SStephan Aßmus enum {
33a6099ca9SStephan Aßmus 	MSG_TOGGLE_LAYOUT			= 'tgll',
348d186370SStephan Aßmus 	MSG_SET_ICON_SIZE			= 'stis',
358d186370SStephan Aßmus 	MSG_SET_IGNORE_DOUBLECLICK	= 'strd'
36f32e3a29SStephan Aßmus };
37f32e3a29SStephan Aßmus 
388d186370SStephan Aßmus 
3925648ff0SStephan Aßmus PadView::PadView(const char* name)
40f32e3a29SStephan Aßmus 	: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE, NULL),
4125648ff0SStephan Aßmus 	  fDragging(false),
42f32e3a29SStephan Aßmus 	  fClickTime(0),
43a6099ca9SStephan Aßmus 	  fButtonLayout(new BGroupLayout(B_VERTICAL, 4)),
44a6099ca9SStephan Aßmus 	  fIconSize(DEFAULT_ICON_SIZE)
4525648ff0SStephan Aßmus {
4625648ff0SStephan Aßmus 	SetViewColor(B_TRANSPARENT_32_BIT);
4725648ff0SStephan Aßmus 	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
48a6099ca9SStephan Aßmus 	get_click_speed(&sActivationDelay);
4925648ff0SStephan Aßmus 
50f32e3a29SStephan Aßmus 	fButtonLayout->SetInsets(2, 7, 2, 2);
51f32e3a29SStephan Aßmus 	SetLayout(fButtonLayout);
5225648ff0SStephan Aßmus }
5325648ff0SStephan Aßmus 
548d186370SStephan Aßmus 
5525648ff0SStephan Aßmus PadView::~PadView()
5625648ff0SStephan Aßmus {
5725648ff0SStephan Aßmus }
5825648ff0SStephan Aßmus 
598d186370SStephan Aßmus 
6025648ff0SStephan Aßmus void
6125648ff0SStephan Aßmus PadView::Draw(BRect updateRect)
6225648ff0SStephan Aßmus {
6325648ff0SStephan Aßmus 	rgb_color background = LowColor();
6425648ff0SStephan Aßmus 	rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
6525648ff0SStephan Aßmus 	rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
6625648ff0SStephan Aßmus 	BRect r(Bounds());
6725648ff0SStephan Aßmus 	BeginLineArray(4);
6825648ff0SStephan Aßmus 		AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), light);
6925648ff0SStephan Aßmus 		AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), light);
7025648ff0SStephan Aßmus 		AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), shadow);
7125648ff0SStephan Aßmus 		AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), shadow);
7225648ff0SStephan Aßmus 	EndLineArray();
7325648ff0SStephan Aßmus 	r.InsetBy(1.0, 1.0);
7425648ff0SStephan Aßmus 	StrokeRect(r, B_SOLID_LOW);
7525648ff0SStephan Aßmus 	r.InsetBy(1.0, 1.0);
7625648ff0SStephan Aßmus 	// dots along top
7725648ff0SStephan Aßmus 	BPoint dot = r.LeftTop();
78f32e3a29SStephan Aßmus 	int32 current;
79f32e3a29SStephan Aßmus 	int32 stop;
80f32e3a29SStephan Aßmus 	BPoint offset;
81f32e3a29SStephan Aßmus 	BPoint next;
82f32e3a29SStephan Aßmus 	if (Orientation() == B_VERTICAL) {
83f32e3a29SStephan Aßmus 		current = (int32)dot.x;
84f32e3a29SStephan Aßmus 		stop = (int32)r.right;
85f32e3a29SStephan Aßmus 		offset = BPoint(0, 1);
86f32e3a29SStephan Aßmus 		next = BPoint(1, -4);
87f32e3a29SStephan Aßmus 		r.top += 5.0;
88f32e3a29SStephan Aßmus 	} else {
89f32e3a29SStephan Aßmus 		current = (int32)dot.y;
90f32e3a29SStephan Aßmus 		stop = (int32)r.bottom;
91f32e3a29SStephan Aßmus 		offset = BPoint(1, 0);
92f32e3a29SStephan Aßmus 		next = BPoint(-4, 1);
93f32e3a29SStephan Aßmus 		r.left += 5.0;
94f32e3a29SStephan Aßmus 	}
9525648ff0SStephan Aßmus 	int32 num = 1;
96f32e3a29SStephan Aßmus 	while (current <= stop) {
9725648ff0SStephan Aßmus 		rgb_color col1;
9825648ff0SStephan Aßmus 		rgb_color col2;
9998dc6a20SOliver Tappe 		if (num == 1) {
10025648ff0SStephan Aßmus 			col1 = shadow;
10125648ff0SStephan Aßmus 			col2 = background;
10298dc6a20SOliver Tappe 		} else if (num == 2) {
10325648ff0SStephan Aßmus 			col1 = background;
10425648ff0SStephan Aßmus 			col2 = light;
10598dc6a20SOliver Tappe 		} else {
10625648ff0SStephan Aßmus 			col1 = background;
10725648ff0SStephan Aßmus 			col2 = background;
10825648ff0SStephan Aßmus 			num = 0;
10925648ff0SStephan Aßmus 		}
11025648ff0SStephan Aßmus 		SetHighColor(col1);
11125648ff0SStephan Aßmus 		StrokeLine(dot, dot, B_SOLID_HIGH);
11225648ff0SStephan Aßmus 		SetHighColor(col2);
113f32e3a29SStephan Aßmus 		dot += offset;
11425648ff0SStephan Aßmus 		StrokeLine(dot, dot, B_SOLID_HIGH);
115f32e3a29SStephan Aßmus 		dot += offset;
11625648ff0SStephan Aßmus 		StrokeLine(dot, dot, B_SOLID_LOW);
117f32e3a29SStephan Aßmus 		dot += offset;
11825648ff0SStephan Aßmus 		SetHighColor(col1);
11925648ff0SStephan Aßmus 		StrokeLine(dot, dot, B_SOLID_HIGH);
120f32e3a29SStephan Aßmus 		dot += offset;
12125648ff0SStephan Aßmus 		SetHighColor(col2);
12225648ff0SStephan Aßmus 		StrokeLine(dot, dot, B_SOLID_HIGH);
12325648ff0SStephan Aßmus 		// next pixel
12425648ff0SStephan Aßmus 		num++;
125f32e3a29SStephan Aßmus 		dot += next;
126f32e3a29SStephan Aßmus 		current++;
12725648ff0SStephan Aßmus 	}
12825648ff0SStephan Aßmus 	FillRect(r, B_SOLID_LOW);
12925648ff0SStephan Aßmus }
13025648ff0SStephan Aßmus 
1318d186370SStephan Aßmus 
13225648ff0SStephan Aßmus void
13325648ff0SStephan Aßmus PadView::MessageReceived(BMessage* message)
13425648ff0SStephan Aßmus {
13525648ff0SStephan Aßmus 	switch (message->what) {
136f32e3a29SStephan Aßmus 		case MSG_TOGGLE_LAYOUT:
137f32e3a29SStephan Aßmus 			if (fButtonLayout->Orientation() == B_HORIZONTAL) {
138f32e3a29SStephan Aßmus 				fButtonLayout->SetInsets(2, 7, 2, 2);
139f32e3a29SStephan Aßmus 				fButtonLayout->SetOrientation(B_VERTICAL);
140f32e3a29SStephan Aßmus 			} else {
141f32e3a29SStephan Aßmus 				fButtonLayout->SetInsets(7, 2, 2, 2);
142f32e3a29SStephan Aßmus 				fButtonLayout->SetOrientation(B_HORIZONTAL);
143f32e3a29SStephan Aßmus 			}
144f32e3a29SStephan Aßmus 			break;
1458d186370SStephan Aßmus 
146a6099ca9SStephan Aßmus 		case MSG_SET_ICON_SIZE:
147a6099ca9SStephan Aßmus 			uint32 size;
148a6099ca9SStephan Aßmus 			if (message->FindInt32("size", (int32*)&size) == B_OK)
149a6099ca9SStephan Aßmus 				SetIconSize(size);
150a6099ca9SStephan Aßmus 			break;
1518d186370SStephan Aßmus 
1528d186370SStephan Aßmus 		case MSG_SET_IGNORE_DOUBLECLICK:
1538d186370SStephan Aßmus 			SetIgnoreDoubleClick(!IgnoreDoubleClick());
1548d186370SStephan Aßmus 			break;
1558d186370SStephan Aßmus 
15625648ff0SStephan Aßmus 		default:
15725648ff0SStephan Aßmus 			BView::MessageReceived(message);
15825648ff0SStephan Aßmus 			break;
15925648ff0SStephan Aßmus 	}
16025648ff0SStephan Aßmus }
16125648ff0SStephan Aßmus 
1628d186370SStephan Aßmus 
16325648ff0SStephan Aßmus void
16425648ff0SStephan Aßmus PadView::MouseDown(BPoint where)
16525648ff0SStephan Aßmus {
16680e19252SStephan Aßmus 	BWindow* window = Window();
16780e19252SStephan Aßmus 	if (window == NULL)
16880e19252SStephan Aßmus 		return;
16980e19252SStephan Aßmus 
17025648ff0SStephan Aßmus 	BRegion region;
17125648ff0SStephan Aßmus 	GetClippingRegion(&region);
17280e19252SStephan Aßmus 	if (!region.Contains(where))
17380e19252SStephan Aßmus 		return;
17480e19252SStephan Aßmus 
17525648ff0SStephan Aßmus 	bool handle = true;
17625648ff0SStephan Aßmus 	for (int32 i = 0; BView* child = ChildAt(i); i++) {
17725648ff0SStephan Aßmus 		if (child->Frame().Contains(where)) {
17825648ff0SStephan Aßmus 			handle = false;
17925648ff0SStephan Aßmus 			break;
18025648ff0SStephan Aßmus 		}
18125648ff0SStephan Aßmus 	}
18280e19252SStephan Aßmus 	if (!handle)
18380e19252SStephan Aßmus 		return;
18480e19252SStephan Aßmus 
18580e19252SStephan Aßmus 	BMessage* message = window->CurrentMessage();
18680e19252SStephan Aßmus 	if (message == NULL)
18780e19252SStephan Aßmus 		return;
18880e19252SStephan Aßmus 
18925648ff0SStephan Aßmus 	uint32 buttons;
19025648ff0SStephan Aßmus 	message->FindInt32("buttons", (int32*)&buttons);
19125648ff0SStephan Aßmus 	if (buttons & B_SECONDARY_MOUSE_BUTTON) {
19225648ff0SStephan Aßmus 		BRect r = Bounds();
19325648ff0SStephan Aßmus 		r.InsetBy(2.0, 2.0);
19425648ff0SStephan Aßmus 		r.top += 6.0;
19525648ff0SStephan Aßmus 		if (r.Contains(where)) {
19625648ff0SStephan Aßmus 			DisplayMenu(where);
19725648ff0SStephan Aßmus 		} else {
19825648ff0SStephan Aßmus 			// sends the window to the back
19925648ff0SStephan Aßmus 			window->Activate(false);
20025648ff0SStephan Aßmus 		}
20125648ff0SStephan Aßmus 	} else {
202a6099ca9SStephan Aßmus 		if (system_time() - fClickTime < sActivationDelay) {
20325648ff0SStephan Aßmus 			window->Minimize(true);
20425648ff0SStephan Aßmus 			fClickTime = 0;
20525648ff0SStephan Aßmus 		} else {
20625648ff0SStephan Aßmus 			window->Activate();
20725648ff0SStephan Aßmus 			fDragOffset = ConvertToScreen(where) - window->Frame().LeftTop();
20825648ff0SStephan Aßmus 			fDragging = true;
20925648ff0SStephan Aßmus 			SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
21025648ff0SStephan Aßmus 			fClickTime = system_time();
21125648ff0SStephan Aßmus 		}
21225648ff0SStephan Aßmus 	}
21325648ff0SStephan Aßmus }
21425648ff0SStephan Aßmus 
2158d186370SStephan Aßmus 
21625648ff0SStephan Aßmus void
21725648ff0SStephan Aßmus PadView::MouseUp(BPoint where)
21825648ff0SStephan Aßmus {
21925648ff0SStephan Aßmus 	if (BWindow* window = Window()) {
22025648ff0SStephan Aßmus 		uint32 buttons;
22125648ff0SStephan Aßmus 		window->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
22225648ff0SStephan Aßmus 		if (buttons & B_PRIMARY_MOUSE_BUTTON
223a6099ca9SStephan Aßmus 			&& system_time() - fClickTime < sActivationDelay
22425648ff0SStephan Aßmus 			&& window->IsActive())
22525648ff0SStephan Aßmus 			window->Activate();
22625648ff0SStephan Aßmus 	}
22725648ff0SStephan Aßmus 	fDragging = false;
22825648ff0SStephan Aßmus }
22925648ff0SStephan Aßmus 
2308d186370SStephan Aßmus 
23125648ff0SStephan Aßmus void
23225648ff0SStephan Aßmus PadView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
23325648ff0SStephan Aßmus {
2348eeb005fSStephan Aßmus 	MainWindow* window = dynamic_cast<MainWindow*>(Window());
2358eeb005fSStephan Aßmus 	if (window == NULL)
2368eeb005fSStephan Aßmus 		return;
2378eeb005fSStephan Aßmus 
23825648ff0SStephan Aßmus 	if (fDragging) {
23925648ff0SStephan Aßmus 		window->MoveTo(ConvertToScreen(where) - fDragOffset);
24025648ff0SStephan Aßmus 	} else if (window->AutoRaise()) {
24125648ff0SStephan Aßmus 		where = ConvertToScreen(where);
24225648ff0SStephan Aßmus 		BScreen screen(window);
24325648ff0SStephan Aßmus 		BRect frame = screen.Frame();
24425648ff0SStephan Aßmus 		BRect windowFrame = window->Frame();
24525648ff0SStephan Aßmus 		if (where.x == frame.left || where.x == frame.right
24625648ff0SStephan Aßmus 			|| where.y == frame.top || where.y == frame.bottom) {
24725648ff0SStephan Aßmus 			BPoint position = window->ScreenPosition();
24825648ff0SStephan Aßmus 			bool raise = false;
24925648ff0SStephan Aßmus 			if (fabs(0.5 - position.x) > fabs(0.5 - position.y)) {
25025648ff0SStephan Aßmus 				// left or right border
2518d186370SStephan Aßmus 				if (where.y >= windowFrame.top
2528d186370SStephan Aßmus 					&& where.y <= windowFrame.bottom) {
25325648ff0SStephan Aßmus 					if (position.x < 0.5 && where.x == frame.left)
25425648ff0SStephan Aßmus 						raise = true;
25525648ff0SStephan Aßmus 					else if (position.x > 0.5 && where.x == frame.right)
25625648ff0SStephan Aßmus 						raise = true;
25725648ff0SStephan Aßmus 				}
25825648ff0SStephan Aßmus 			} else {
25925648ff0SStephan Aßmus 				// top or bottom border
26025648ff0SStephan Aßmus 				if (where.x >= windowFrame.left && where.x <= windowFrame.right) {
26125648ff0SStephan Aßmus 					if (position.y < 0.5 && where.y == frame.top)
26225648ff0SStephan Aßmus 						raise = true;
263a6099ca9SStephan Aßmus 					else if (position.y > 0.5 && where.y == frame.bottom)
26425648ff0SStephan Aßmus 						raise = true;
26525648ff0SStephan Aßmus 				}
26625648ff0SStephan Aßmus 			}
26725648ff0SStephan Aßmus 			if (raise)
26825648ff0SStephan Aßmus 				window->Activate();
26925648ff0SStephan Aßmus 		}
27025648ff0SStephan Aßmus 	}
27125648ff0SStephan Aßmus }
27225648ff0SStephan Aßmus 
2738d186370SStephan Aßmus 
27425648ff0SStephan Aßmus void
27525648ff0SStephan Aßmus PadView::AddButton(LaunchButton* button, LaunchButton* beforeButton)
27625648ff0SStephan Aßmus {
277a6099ca9SStephan Aßmus 	button->SetIconSize(fIconSize);
278a6099ca9SStephan Aßmus 
27925648ff0SStephan Aßmus 	if (beforeButton)
280f32e3a29SStephan Aßmus 		fButtonLayout->AddView(fButtonLayout->IndexOfView(beforeButton), button);
28125648ff0SStephan Aßmus 	else
282f32e3a29SStephan Aßmus 		fButtonLayout->AddView(button);
2839368e58bSStephan Aßmus 
2849368e58bSStephan Aßmus 	_NotifySettingsChanged();
28525648ff0SStephan Aßmus }
28625648ff0SStephan Aßmus 
2878d186370SStephan Aßmus 
28825648ff0SStephan Aßmus bool
28925648ff0SStephan Aßmus PadView::RemoveButton(LaunchButton* button)
29025648ff0SStephan Aßmus {
2919368e58bSStephan Aßmus 	bool result = fButtonLayout->RemoveView(button);
2929368e58bSStephan Aßmus 	if (result)
2939368e58bSStephan Aßmus 		_NotifySettingsChanged();
2949368e58bSStephan Aßmus 	return result;
29525648ff0SStephan Aßmus }
29625648ff0SStephan Aßmus 
2978d186370SStephan Aßmus 
29825648ff0SStephan Aßmus LaunchButton*
29925648ff0SStephan Aßmus PadView::ButtonAt(int32 index) const
30025648ff0SStephan Aßmus {
30170e39d09SStephan Aßmus 	BLayoutItem* item = fButtonLayout->ItemAt(index);
30270e39d09SStephan Aßmus 	if (item == NULL)
30370e39d09SStephan Aßmus 		return NULL;
30470e39d09SStephan Aßmus 	return dynamic_cast<LaunchButton*>(item->View());
30525648ff0SStephan Aßmus }
30625648ff0SStephan Aßmus 
3078d186370SStephan Aßmus 
30825648ff0SStephan Aßmus void
30925648ff0SStephan Aßmus PadView::DisplayMenu(BPoint where, LaunchButton* button) const
31025648ff0SStephan Aßmus {
3118eeb005fSStephan Aßmus 	MainWindow* window = dynamic_cast<MainWindow*>(Window());
3128eeb005fSStephan Aßmus 	if (window == NULL)
3138eeb005fSStephan Aßmus 		return;
3148eeb005fSStephan Aßmus 
31525648ff0SStephan Aßmus 	LaunchButton* nearestButton = button;
31625648ff0SStephan Aßmus 	if (!nearestButton) {
31725648ff0SStephan Aßmus 		// find the nearest button
31825648ff0SStephan Aßmus 		for (int32 i = 0; (nearestButton = ButtonAt(i)); i++) {
31925648ff0SStephan Aßmus 			if (nearestButton->Frame().top > where.y)
32025648ff0SStephan Aßmus 				break;
32125648ff0SStephan Aßmus 		}
32225648ff0SStephan Aßmus 	}
3230e07d4c0SAdrien Destugues 	BPopUpMenu* menu = new BPopUpMenu(B_TRANSLATE("launch popup"), false, false);
32425648ff0SStephan Aßmus 	// add button
32525648ff0SStephan Aßmus 	BMessage* message = new BMessage(MSG_ADD_SLOT);
32625648ff0SStephan Aßmus 	message->AddPointer("be:source", (void*)nearestButton);
3270e07d4c0SAdrien Destugues 	BMenuItem* item = new BMenuItem(B_TRANSLATE("Add button here"), message);
32825648ff0SStephan Aßmus 	item->SetTarget(window);
32925648ff0SStephan Aßmus 	menu->AddItem(item);
33025648ff0SStephan Aßmus 	// button options
33125648ff0SStephan Aßmus 	if (button) {
3329368e58bSStephan Aßmus 		// clear button
33325648ff0SStephan Aßmus 		message = new BMessage(MSG_CLEAR_SLOT);
33425648ff0SStephan Aßmus 		message->AddPointer("be:source", (void*)button);
3350e07d4c0SAdrien Destugues 		item = new BMenuItem(B_TRANSLATE("Clear button"), message);
33625648ff0SStephan Aßmus 		item->SetTarget(window);
33725648ff0SStephan Aßmus 		menu->AddItem(item);
33825648ff0SStephan Aßmus 		// remove button
33925648ff0SStephan Aßmus 		message = new BMessage(MSG_REMOVE_SLOT);
34025648ff0SStephan Aßmus 		message->AddPointer("be:source", (void*)button);
3410e07d4c0SAdrien Destugues 		item = new BMenuItem(B_TRANSLATE("Remove button"), message);
34225648ff0SStephan Aßmus 		item->SetTarget(window);
34325648ff0SStephan Aßmus 		menu->AddItem(item);
344*ac966d59SMatt Madia 		// Open containing folder button
345*ac966d59SMatt Madia 		if (button->Ref() != NULL) {
346*ac966d59SMatt Madia 			message = new BMessage(MSG_OPEN_CONTAINING_FOLDER);
347*ac966d59SMatt Madia 			message->AddPointer("be:source", (void*)button);
348*ac966d59SMatt Madia 			item = new BMenuItem(B_TRANSLATE("Open containing folder"), message);
349*ac966d59SMatt Madia 			item->SetTarget(window);
350*ac966d59SMatt Madia 			menu->AddItem(item);
351*ac966d59SMatt Madia 		}
3529368e58bSStephan Aßmus 		// set button description
3539368e58bSStephan Aßmus 		if (button->Ref()) {
3549368e58bSStephan Aßmus 			message = new BMessage(MSG_SET_DESCRIPTION);
3559368e58bSStephan Aßmus 			message->AddPointer("be:source", (void*)button);
3560e07d4c0SAdrien Destugues 			item = new BMenuItem(B_TRANSLATE("Set description"B_UTF8_ELLIPSIS),
3570e07d4c0SAdrien Destugues 				message);
3589368e58bSStephan Aßmus 			item->SetTarget(window);
3599368e58bSStephan Aßmus 			menu->AddItem(item);
3609368e58bSStephan Aßmus 		}
36125648ff0SStephan Aßmus 	}
36225648ff0SStephan Aßmus 	menu->AddSeparatorItem();
36325648ff0SStephan Aßmus 	// window settings
364c16bcdfcSJoachim Seemer 	BMenu* settingsM = new BMenu(B_TRANSLATE("Settings"));
36525648ff0SStephan Aßmus 	settingsM->SetFont(be_plain_font);
36625648ff0SStephan Aßmus 
367f32e3a29SStephan Aßmus 	const char* toggleLayoutLabel;
368f32e3a29SStephan Aßmus 	if (fButtonLayout->Orientation() == B_HORIZONTAL)
3690e07d4c0SAdrien Destugues 		toggleLayoutLabel = B_TRANSLATE("Vertical layout");
370f32e3a29SStephan Aßmus 	else
3710e07d4c0SAdrien Destugues 		toggleLayoutLabel = B_TRANSLATE("Horizontal layout");
372f32e3a29SStephan Aßmus 	item = new BMenuItem(toggleLayoutLabel, new BMessage(MSG_TOGGLE_LAYOUT));
373f32e3a29SStephan Aßmus 	item->SetTarget(this);
374f32e3a29SStephan Aßmus 	settingsM->AddItem(item);
375f32e3a29SStephan Aßmus 
3760e07d4c0SAdrien Destugues 	BMenu* iconSizeM = new BMenu(B_TRANSLATE("Icon size"));
377a6099ca9SStephan Aßmus 	for (uint32 i = 0; i < sizeof(kIconSizes) / sizeof(uint32); i++) {
378a6099ca9SStephan Aßmus 		uint32 iconSize = kIconSizes[i];
379a6099ca9SStephan Aßmus 		message = new BMessage(MSG_SET_ICON_SIZE);
380a6099ca9SStephan Aßmus 		message->AddInt32("size", iconSize);
381a6099ca9SStephan Aßmus 		BString label;
382a6099ca9SStephan Aßmus 		label << iconSize << " x " << iconSize;
383a6099ca9SStephan Aßmus 		item = new BMenuItem(label.String(), message);
384a6099ca9SStephan Aßmus 		item->SetTarget(this);
385a6099ca9SStephan Aßmus 		item->SetMarked(IconSize() == iconSize);
386a6099ca9SStephan Aßmus 		iconSizeM->AddItem(item);
387a6099ca9SStephan Aßmus 	}
388a6099ca9SStephan Aßmus 	settingsM->AddItem(iconSizeM);
389a6099ca9SStephan Aßmus 
3900e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Ignore double-click"),
3918d186370SStephan Aßmus 		new BMessage(MSG_SET_IGNORE_DOUBLECLICK));
3928d186370SStephan Aßmus 	item->SetTarget(this);
3938d186370SStephan Aßmus 	item->SetMarked(IgnoreDoubleClick());
3948d186370SStephan Aßmus 	settingsM->AddItem(item);
3958d186370SStephan Aßmus 
39625648ff0SStephan Aßmus 	uint32 what = window->Look() == B_BORDERED_WINDOW_LOOK ? MSG_SHOW_BORDER : MSG_HIDE_BORDER;
3970e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Show window border"), new BMessage(what));
39825648ff0SStephan Aßmus 	item->SetTarget(window);
39925648ff0SStephan Aßmus 	item->SetMarked(what == MSG_HIDE_BORDER);
40025648ff0SStephan Aßmus 	settingsM->AddItem(item);
40125648ff0SStephan Aßmus 
4020e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Auto-raise"), new BMessage(MSG_TOGGLE_AUTORAISE));
40325648ff0SStephan Aßmus 	item->SetTarget(window);
40425648ff0SStephan Aßmus 	item->SetMarked(window->AutoRaise());
40525648ff0SStephan Aßmus 	settingsM->AddItem(item);
40625648ff0SStephan Aßmus 
4070e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Show on all workspaces"), new BMessage(MSG_SHOW_ON_ALL_WORKSPACES));
40825648ff0SStephan Aßmus 	item->SetTarget(window);
40925648ff0SStephan Aßmus 	item->SetMarked(window->ShowOnAllWorkspaces());
41025648ff0SStephan Aßmus 	settingsM->AddItem(item);
41125648ff0SStephan Aßmus 
41225648ff0SStephan Aßmus 	menu->AddItem(settingsM);
41325648ff0SStephan Aßmus 
41425648ff0SStephan Aßmus 	menu->AddSeparatorItem();
41525648ff0SStephan Aßmus 
41625648ff0SStephan Aßmus 	// pad commands
4170e07d4c0SAdrien Destugues 	BMenu* padM = new BMenu(B_TRANSLATE("Pad"));
41825648ff0SStephan Aßmus 	padM->SetFont(be_plain_font);
41925648ff0SStephan Aßmus 	// new pad
4200e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("New"), new BMessage(MSG_ADD_WINDOW));
42125648ff0SStephan Aßmus 	item->SetTarget(be_app);
42225648ff0SStephan Aßmus 	padM->AddItem(item);
42325648ff0SStephan Aßmus 	// new pad
4240e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Clone"), new BMessage(MSG_ADD_WINDOW));
42525648ff0SStephan Aßmus 	item->SetTarget(window);
42625648ff0SStephan Aßmus 	padM->AddItem(item);
42725648ff0SStephan Aßmus 	padM->AddSeparatorItem();
42825648ff0SStephan Aßmus 	// close
4290e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Close"), new BMessage(B_QUIT_REQUESTED));
43025648ff0SStephan Aßmus 	item->SetTarget(window);
43125648ff0SStephan Aßmus 	padM->AddItem(item);
43225648ff0SStephan Aßmus 	menu->AddItem(padM);
43325648ff0SStephan Aßmus 	// app commands
434560ff447SJonas Sundström 	BMenu* appM = new BMenu(B_TRANSLATE_SYSTEM_NAME("LaunchBox"));
43525648ff0SStephan Aßmus 	appM->SetFont(be_plain_font);
43625648ff0SStephan Aßmus 	// quit
4370e07d4c0SAdrien Destugues 	item = new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED));
43825648ff0SStephan Aßmus 	item->SetTarget(be_app);
43925648ff0SStephan Aßmus 	appM->AddItem(item);
44025648ff0SStephan Aßmus 	menu->AddItem(appM);
44125648ff0SStephan Aßmus 	// finish popup
44225648ff0SStephan Aßmus 	menu->SetAsyncAutoDestruct(true);
44325648ff0SStephan Aßmus 	menu->SetFont(be_plain_font);
44425648ff0SStephan Aßmus 	where = ConvertToScreen(where);
44525648ff0SStephan Aßmus 	BRect mouseRect(where, where);
44625648ff0SStephan Aßmus 	mouseRect.InsetBy(-4.0, -4.0);
44725648ff0SStephan Aßmus 	menu->Go(where, true, false, mouseRect, true);
44825648ff0SStephan Aßmus }
44925648ff0SStephan Aßmus 
4508d186370SStephan Aßmus 
451f32e3a29SStephan Aßmus void
452f32e3a29SStephan Aßmus PadView::SetOrientation(enum orientation orientation)
453f32e3a29SStephan Aßmus {
454f32e3a29SStephan Aßmus 	if (orientation == B_VERTICAL) {
455f32e3a29SStephan Aßmus 		fButtonLayout->SetInsets(2, 7, 2, 2);
456f32e3a29SStephan Aßmus 		fButtonLayout->SetOrientation(B_VERTICAL);
457f32e3a29SStephan Aßmus 	} else {
458f32e3a29SStephan Aßmus 		fButtonLayout->SetInsets(7, 2, 2, 2);
459f32e3a29SStephan Aßmus 		fButtonLayout->SetOrientation(B_HORIZONTAL);
460f32e3a29SStephan Aßmus 	}
4619368e58bSStephan Aßmus 	_NotifySettingsChanged();
462f32e3a29SStephan Aßmus }
463f32e3a29SStephan Aßmus 
4648d186370SStephan Aßmus 
465f32e3a29SStephan Aßmus enum orientation
466f32e3a29SStephan Aßmus PadView::Orientation() const
467f32e3a29SStephan Aßmus {
468f32e3a29SStephan Aßmus 	return fButtonLayout->Orientation();
469f32e3a29SStephan Aßmus }
470f32e3a29SStephan Aßmus 
4718d186370SStephan Aßmus 
472a6099ca9SStephan Aßmus void
473a6099ca9SStephan Aßmus PadView::SetIconSize(uint32 size)
474a6099ca9SStephan Aßmus {
475a6099ca9SStephan Aßmus 	if (size == fIconSize)
476a6099ca9SStephan Aßmus 		return;
477a6099ca9SStephan Aßmus 
478a6099ca9SStephan Aßmus 	fIconSize = size;
479a6099ca9SStephan Aßmus 
480a6099ca9SStephan Aßmus 	for (int32 i = 0; LaunchButton* button = ButtonAt(i); i++)
481a6099ca9SStephan Aßmus 		button->SetIconSize(fIconSize);
4829368e58bSStephan Aßmus 
4839368e58bSStephan Aßmus 	_NotifySettingsChanged();
484a6099ca9SStephan Aßmus }
485a6099ca9SStephan Aßmus 
4868d186370SStephan Aßmus 
487a6099ca9SStephan Aßmus uint32
488a6099ca9SStephan Aßmus PadView::IconSize() const
489a6099ca9SStephan Aßmus {
490a6099ca9SStephan Aßmus 	return fIconSize;
491a6099ca9SStephan Aßmus }
492a6099ca9SStephan Aßmus 
493f32e3a29SStephan Aßmus 
4948d186370SStephan Aßmus void
4958d186370SStephan Aßmus PadView::SetIgnoreDoubleClick(bool refuse)
4968d186370SStephan Aßmus {
4978d186370SStephan Aßmus 	LaunchButton::SetIgnoreDoubleClick(refuse);
4989368e58bSStephan Aßmus 
4999368e58bSStephan Aßmus 	_NotifySettingsChanged();
5008d186370SStephan Aßmus }
5018d186370SStephan Aßmus 
5028d186370SStephan Aßmus 
5038d186370SStephan Aßmus bool
5048d186370SStephan Aßmus PadView::IgnoreDoubleClick() const
5058d186370SStephan Aßmus {
5068d186370SStephan Aßmus 	return LaunchButton::IgnoreDoubleClick();
5078d186370SStephan Aßmus }
5088d186370SStephan Aßmus 
5098d186370SStephan Aßmus 
5109368e58bSStephan Aßmus void
5119368e58bSStephan Aßmus PadView::_NotifySettingsChanged()
5129368e58bSStephan Aßmus {
5139368e58bSStephan Aßmus 	be_app->PostMessage(MSG_SETTINGS_CHANGED);
5149368e58bSStephan Aßmus }
5159368e58bSStephan Aßmus 
516