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