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