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