xref: /haiku/src/bin/desklink/DeskButton.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
1 /*
2  * Copyright 2003-2007, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval
7  *		Jonas Sundström
8  */
9 
10 
11 #include "DeskButton.h"
12 
13 #include <Alert.h>
14 #include <Bitmap.h>
15 #include <Catalog.h>
16 #include <ControlLook.h>
17 #include <Dragger.h>
18 #include <MenuItem.h>
19 #include <Message.h>
20 #include <NodeInfo.h>
21 #include <PopUpMenu.h>
22 #include <Roster.h>
23 #include <String.h>
24 
25 #include <stdlib.h>
26 
27 #define OPEN_REF	'opre'
28 #define DO_ACTION	'doac'
29 
30 
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "DeskButton"
33 
34 
35 extern const char *kAppSignature;
36 	// from desklink.cpp
37 
38 
39 DeskButton::DeskButton(BRect frame, entry_ref* ref, const char* name,
40 		BList& titles, BList& actions, uint32 resizeMask, uint32 flags)
41 	: BView(frame, name, resizeMask, flags),
42 	fRef(*ref),
43 	fActionList(actions),
44 	fTitleList(titles)
45 {
46 	fSegments = new BBitmap(frame, B_RGBA32);
47 	BNodeInfo::GetTrackerIcon(&fRef, fSegments, (icon_size)-1);
48 }
49 
50 
51 DeskButton::DeskButton(BMessage *message)
52 	: BView(message)
53 {
54 	message->FindRef("ref", &fRef);
55 
56 	BString title, action;
57 	int32 index = 0;
58 	while(message->FindString("title", index, &title)==B_OK
59 		&& message->FindString("action", index, &action)==B_OK) {
60 		fTitleList.AddItem(new BString(title));
61 		fActionList.AddItem(new BString(action));
62 		index++;
63 	}
64 
65 	fSegments = new BBitmap(BRect(BPoint(0, 0), be_control_look->ComposeIconSize(B_MINI_ICON)),
66 		B_RGBA32);
67 	BNodeInfo::GetTrackerIcon(&fRef, fSegments,
68 		(icon_size)(fSegments->Bounds().IntegerWidth() + 1));
69 }
70 
71 
72 DeskButton::~DeskButton()
73 {
74 	delete fSegments;
75 }
76 
77 
78 // archiving overrides
79 DeskButton *
80 DeskButton::Instantiate(BMessage *data)
81 {
82 	if (!validate_instantiation(data, "DeskButton"))
83 		return NULL;
84 
85 	return new DeskButton(data);
86 }
87 
88 
89 status_t
90 DeskButton::Archive(BMessage *data, bool deep) const
91 {
92 	BView::Archive(data, deep);
93 
94 	data->AddRef("ref", &fRef);
95 
96 	for (int32 i = 0; i < fTitleList.CountItems()
97 			&& i < fActionList.CountItems(); i++) {
98 		data->AddString("title", *(BString*)fTitleList.ItemAt(i));
99 		data->AddString("action", *(BString*)fActionList.ItemAt(i));
100 	}
101 
102 	data->AddString("add_on", kAppSignature);
103 	return B_NO_ERROR;
104 }
105 
106 
107 void
108 DeskButton::MessageReceived(BMessage *message)
109 {
110 	switch (message->what) {
111 		case OPEN_REF:
112 			be_roster->Launch(&fRef);
113 			break;
114 
115 		case DO_ACTION:
116 		{
117 			BString action;
118 			if (message->FindString("action", &action) == B_OK) {
119 				action += " &";
120 				system(action.String());
121 			}
122 			break;
123 		}
124 
125 		default:
126 			BView::MessageReceived(message);
127 			break;
128 	}
129 }
130 
131 
132 void
133 DeskButton::AttachedToWindow()
134 {
135 	BView *parent = Parent();
136 	if (parent)
137 		SetViewColor(parent->ViewColor());
138 
139 	BView::AttachedToWindow();
140 }
141 
142 
143 void
144 DeskButton::Draw(BRect rect)
145 {
146 	BView::Draw(rect);
147 
148 #ifdef __HAIKU__
149 	SetDrawingMode(B_OP_ALPHA);
150 	SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
151 #else
152 	SetDrawingMode(B_OP_OVER);
153 #endif
154 	DrawBitmap(fSegments);
155 }
156 
157 
158 void
159 DeskButton::MouseDown(BPoint point)
160 {
161 	uint32 mouseButtons = 0;
162 	if (Window()->CurrentMessage() != NULL)
163 		mouseButtons = Window()->CurrentMessage()->FindInt32("buttons");
164 
165 	BPoint where = ConvertToScreen(point);
166 
167 	if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) {
168 		BString label = B_TRANSLATE_COMMENT("Open %name", "Don't translate "
169 			"variable %name");
170 		label.ReplaceFirst("%name", fRef.name);
171 		BPopUpMenu *menu = new BPopUpMenu("", false, false);
172 		menu->SetFont(be_plain_font);
173 		menu->AddItem(new BMenuItem(label.String(), new BMessage(OPEN_REF)));
174 		if (fTitleList.CountItems() > 0 && fActionList.CountItems() > 0) {
175 			menu->AddSeparatorItem();
176 			for (int32 i = 0; i < fTitleList.CountItems()
177 					&& i < fActionList.CountItems(); i++) {
178 				BMessage *message = new BMessage(DO_ACTION);
179 				message->AddString("action", *(BString*)fActionList.ItemAt(i));
180 				menu->AddItem(new BMenuItem(((BString*)fTitleList.ItemAt(i))->String(), message));
181 			}
182 		}
183 
184 		menu->SetTargetForItems(this);
185 		menu->Go(where, true, true, BRect(where - BPoint(4, 4),
186 			where + BPoint(4, 4)));
187 	} else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) {
188 		be_roster->Launch(&fRef);
189 	}
190 }
191