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