141281cf3SAxel Dörfler /* 241281cf3SAxel Dörfler Open Tracker License 341281cf3SAxel Dörfler 441281cf3SAxel Dörfler Terms and Conditions 541281cf3SAxel Dörfler 641281cf3SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 741281cf3SAxel Dörfler 841281cf3SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of 941281cf3SAxel Dörfler this software and associated documentation files (the "Software"), to deal in 1041281cf3SAxel Dörfler the Software without restriction, including without limitation the rights to 1141281cf3SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1241281cf3SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do 1341281cf3SAxel Dörfler so, subject to the following conditions: 1441281cf3SAxel Dörfler 1541281cf3SAxel Dörfler The above copyright notice and this permission notice applies to all licensees 1641281cf3SAxel Dörfler and shall be included in all copies or substantial portions of the Software. 1741281cf3SAxel Dörfler 1841281cf3SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1941281cf3SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 2041281cf3SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2141281cf3SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2241281cf3SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 2341281cf3SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2441281cf3SAxel Dörfler 2541281cf3SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be 2641281cf3SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in 2741281cf3SAxel Dörfler this Software without prior written authorization from Be Incorporated. 2841281cf3SAxel Dörfler 291ad8c760SFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 301ad8c760SFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other 311ad8c760SFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective 321ad8c760SFredrik Holmqvist holders. 3341281cf3SAxel Dörfler All rights reserved. 3441281cf3SAxel Dörfler */ 3541281cf3SAxel Dörfler 361cd61330SJohn Scipione 371cd61330SJohn Scipione #include "StatusView.h" 3841281cf3SAxel Dörfler 3941281cf3SAxel Dörfler #include <errno.h> 4041281cf3SAxel Dörfler #include <stdio.h> 4141281cf3SAxel Dörfler #include <string.h> 4241281cf3SAxel Dörfler #include <time.h> 4341281cf3SAxel Dörfler #include <unistd.h> 4441281cf3SAxel Dörfler #include <algorithm> 4541281cf3SAxel Dörfler 4641281cf3SAxel Dörfler #include <fs_index.h> 4741281cf3SAxel Dörfler #include <fs_info.h> 4841281cf3SAxel Dörfler 4941281cf3SAxel Dörfler #include <Application.h> 5041281cf3SAxel Dörfler #include <Beep.h> 51cb6afcb1SStephan Aßmus #include <Bitmap.h> 52ae7a6e3aSAdrien Destugues #include <Catalog.h> 53cb6afcb1SStephan Aßmus #include <ControlLook.h> 541cd61330SJohn Scipione #include <Debug.h> 5541281cf3SAxel Dörfler #include <Directory.h> 5641281cf3SAxel Dörfler #include <FindDirectory.h> 57ae7a6e3aSAdrien Destugues #include <Locale.h> 5841281cf3SAxel Dörfler #include <MenuItem.h> 5941281cf3SAxel Dörfler #include <NodeInfo.h> 6041281cf3SAxel Dörfler #include <NodeMonitor.h> 6141281cf3SAxel Dörfler #include <Path.h> 6241281cf3SAxel Dörfler #include <PopUpMenu.h> 6341281cf3SAxel Dörfler #include <Roster.h> 6441281cf3SAxel Dörfler #include <Screen.h> 6541281cf3SAxel Dörfler #include <Volume.h> 6641281cf3SAxel Dörfler #include <VolumeRoster.h> 6741281cf3SAxel Dörfler #include <Window.h> 6841281cf3SAxel Dörfler 69615d572dSJohn Scipione #include "icons.h" 70615d572dSJohn Scipione 71cb6afcb1SStephan Aßmus #include "BarApp.h" 72323b6546SOliver Tappe #include "DeskbarUtils.h" 73cb6afcb1SStephan Aßmus #include "ResourceSet.h" 7441281cf3SAxel Dörfler #include "StatusViewShelf.h" 7541281cf3SAxel Dörfler #include "TimeView.h" 7641281cf3SAxel Dörfler 77615d572dSJohn Scipione 7841281cf3SAxel Dörfler #ifdef DB_ADDONS 7941281cf3SAxel Dörfler // Add-on support 8041281cf3SAxel Dörfler // 8141281cf3SAxel Dörfler // Item - internal item list (node, eref, etc) 8241281cf3SAxel Dörfler // Icon - physical replicant handed to the DeskbarClass class 8341281cf3SAxel Dörfler // AddOn - attribute based add-on 8441281cf3SAxel Dörfler 8541281cf3SAxel Dörfler const char* const kInstantiateItemCFunctionName = "instantiate_deskbar_item"; 8641281cf3SAxel Dörfler const char* const kInstantiateEntryCFunctionName = "instantiate_deskbar_entry"; 8726ea7066SIngo Weinhold const char* const kReplicantSettingsFile = "replicants"; 88c0ad1c91SRene Gollent const char* const kReplicantPathField = "replicant_path"; 8941281cf3SAxel Dörfler 90b49e806dSAxel Dörfler float gMinimumWindowWidth = kGutter + kMinimumTrayWidth + kDragRegionWidth; 911bb2e623SJohn Scipione float gMaximumWindowWidth = gMinimumWindowWidth * 2; 9241281cf3SAxel Dörfler 93c3c3360fSJohn Scipione 9441281cf3SAxel Dörfler static void 9541281cf3SAxel Dörfler DumpItem(DeskbarItemInfo* item) 9641281cf3SAxel Dörfler { 97e9632898SAlex Smith printf("is addon: %i, id: %" B_PRId32 "\n", item->isAddOn, item->id); 98e9632898SAlex Smith printf("entry_ref: %" B_PRIdDEV ", %" B_PRIdINO ", %s\n", 99e9632898SAlex Smith item->entryRef.device, item->entryRef.directory, item->entryRef.name); 100e9632898SAlex Smith printf("node_ref: %" B_PRIdDEV ", %" B_PRIdINO "\n", item->nodeRef.device, 101e9632898SAlex Smith item->nodeRef.node); 10241281cf3SAxel Dörfler } 10341281cf3SAxel Dörfler 10441281cf3SAxel Dörfler 10541281cf3SAxel Dörfler static void 10641281cf3SAxel Dörfler DumpList(BList* itemlist) 10741281cf3SAxel Dörfler { 10841281cf3SAxel Dörfler int32 count = itemlist->CountItems() - 1; 10941281cf3SAxel Dörfler if (count < 0) { 11041281cf3SAxel Dörfler printf("no items in list\n"); 11141281cf3SAxel Dörfler return; 11241281cf3SAxel Dörfler } 11341281cf3SAxel Dörfler for (int32 i = count; i >= 0; i--) { 11441281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)itemlist->ItemAt(i); 11541281cf3SAxel Dörfler if (!item) 11641281cf3SAxel Dörfler continue; 11741281cf3SAxel Dörfler 11841281cf3SAxel Dörfler DumpItem(item); 11941281cf3SAxel Dörfler } 12041281cf3SAxel Dörfler } 12141281cf3SAxel Dörfler #endif /* DB_ADDONS */ 12241281cf3SAxel Dörfler 12341281cf3SAxel Dörfler 124546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 125546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Tray" 126ae7a6e3aSAdrien Destugues 1277da06231SAxel Dörfler // don't change the name of this view to anything other than "Status"! 1287da06231SAxel Dörfler 12941281cf3SAxel Dörfler TReplicantTray::TReplicantTray(TBarView* parent, bool vertical) 1300d2ac94cSJohn Scipione : 1319ac6fee1SJohn Scipione BView(BRect(0, 0, 1, 1), "Status", B_FOLLOW_LEFT | B_FOLLOW_TOP, 1320d2ac94cSJohn Scipione B_WILL_DRAW | B_FRAME_EVENTS), 133573f748cSJohn Scipione fTime(NULL), 13441281cf3SAxel Dörfler fBarView(parent), 13541281cf3SAxel Dörfler fShelf(new TReplicantShelf(this)), 13641281cf3SAxel Dörfler fMultiRowMode(vertical), 13741281cf3SAxel Dörfler fAlignmentSupport(false) 13841281cf3SAxel Dörfler { 139*efafab64SAxel Dörfler fMaxReplicantHeight = std::max(kMinReplicantHeight, 140*efafab64SAxel Dörfler floorf(kMinReplicantHeight * be_plain_font->Size() / 12)); 141*efafab64SAxel Dörfler // TODO: depends on window size... (so use something like 142*efafab64SAxel Dörfler // max(129, height * 3), and restrict the minimum window width for it) 143*efafab64SAxel Dörfler fMaxReplicantWidth = 129; 144*efafab64SAxel Dörfler 145*efafab64SAxel Dörfler fMinTrayHeight = kGutter + fMaxReplicantHeight + kGutter; 146fb956f25SAxel Dörfler if (vertical) 147fb956f25SAxel Dörfler fMinimumTrayWidth = gMinimumWindowWidth - kGutter - kDragRegionWidth; 1481bb2e623SJohn Scipione else 1491bb2e623SJohn Scipione fMinimumTrayWidth = kMinimumTrayWidth; 150573f748cSJohn Scipione 151573f748cSJohn Scipione // Create the time view 152*efafab64SAxel Dörfler fTime = new TTimeView(fMinimumTrayWidth, fMaxReplicantHeight - 1.0); 15341281cf3SAxel Dörfler } 15441281cf3SAxel Dörfler 15541281cf3SAxel Dörfler 15641281cf3SAxel Dörfler TReplicantTray::~TReplicantTray() 15741281cf3SAxel Dörfler { 15841281cf3SAxel Dörfler delete fShelf; 159573f748cSJohn Scipione delete fTime; 16041281cf3SAxel Dörfler } 16141281cf3SAxel Dörfler 16241281cf3SAxel Dörfler 16341281cf3SAxel Dörfler void 16441281cf3SAxel Dörfler TReplicantTray::AttachedToWindow() 16541281cf3SAxel Dörfler { 16641281cf3SAxel Dörfler BView::AttachedToWindow(); 16741281cf3SAxel Dörfler 168cb6afcb1SStephan Aßmus if (be_control_look != NULL) { 169cef0a7b2Slooncraz AdoptParentColors(); 170cb6afcb1SStephan Aßmus } else { 17116c10517Slooncraz SetViewUIColor(B_MENU_BACKGROUND_COLOR, B_DARKEN_1_TINT); 172cb6afcb1SStephan Aßmus } 17341281cf3SAxel Dörfler SetDrawingMode(B_OP_COPY); 17466eba86fSAxel Dörfler 17541281cf3SAxel Dörfler Window()->SetPulseRate(1000000); 17641281cf3SAxel Dörfler 1773722e640SJohn Scipione clock_settings* clock = ((TBarApp*)be_app)->ClockSettings(); 1783722e640SJohn Scipione fTime->SetShowSeconds(clock->showSeconds); 1793722e640SJohn Scipione fTime->SetShowDayOfWeek(clock->showDayOfWeek); 1803722e640SJohn Scipione fTime->SetShowTimeZone(clock->showTimeZone); 18131c0024dSJohn Scipione 182573f748cSJohn Scipione AddChild(fTime); 1831bb2e623SJohn Scipione 18470ad5289SJohn Scipione fTime->MoveTo(Bounds().right - fTime->Bounds().Width() - kTrayPadding, 2); 1851dd1976fSJohn Scipione fTime->SetOrientation(fMultiRowMode); 186ae7a6e3aSAdrien Destugues 1873722e640SJohn Scipione if (!((TBarApp*)be_app)->Settings()->showClock) 1883722e640SJohn Scipione fTime->Hide(); 1893722e640SJohn Scipione 19041281cf3SAxel Dörfler #ifdef DB_ADDONS 19141281cf3SAxel Dörfler // load addons and rehydrate archives 1923a6add49SAxel Dörfler #if !defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST) 19341281cf3SAxel Dörfler InitAddOnSupport(); 19441281cf3SAxel Dörfler #endif 1959c910f9eSStephan Aßmus #endif 19641281cf3SAxel Dörfler ResizeToPreferred(); 19741281cf3SAxel Dörfler } 19841281cf3SAxel Dörfler 19941281cf3SAxel Dörfler 20041281cf3SAxel Dörfler void 20141281cf3SAxel Dörfler TReplicantTray::DetachedFromWindow() 20241281cf3SAxel Dörfler { 20341281cf3SAxel Dörfler #ifdef DB_ADDONS 20441281cf3SAxel Dörfler // clean up add-on support 205465b54cdSAxel Dörfler #if !defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST) 20641281cf3SAxel Dörfler DeleteAddOnSupport(); 20741281cf3SAxel Dörfler #endif 208465b54cdSAxel Dörfler #endif 20941281cf3SAxel Dörfler BView::DetachedFromWindow(); 21041281cf3SAxel Dörfler } 21141281cf3SAxel Dörfler 21241281cf3SAxel Dörfler 2131ad8c760SFredrik Holmqvist /*! Width is set to a minimum of kMinimumReplicantCount by kMaxReplicantWidth 21466eba86fSAxel Dörfler if not in multirowmode and greater than kMinimumReplicantCount 2152ce9bab8SJohn Scipione the width should be calculated based on the actual replicant widths 21641281cf3SAxel Dörfler */ 21741281cf3SAxel Dörfler void 21841281cf3SAxel Dörfler TReplicantTray::GetPreferredSize(float* preferredWidth, float* preferredHeight) 21941281cf3SAxel Dörfler { 2201bb2e623SJohn Scipione float width = 0; 221*efafab64SAxel Dörfler float height = fMinTrayHeight; 22241281cf3SAxel Dörfler 22341281cf3SAxel Dörfler if (fMultiRowMode) { 2241bb2e623SJohn Scipione width = static_cast<TBarApp*>(be_app)->Settings()->width 2251bb2e623SJohn Scipione - kDragWidth - kGutter; 226a44504a1SJohn Scipione if (fRightBottomReplicant.IsValid()) 2277da06231SAxel Dörfler height = fRightBottomReplicant.bottom; 228a44504a1SJohn Scipione else if (ReplicantCount() > 0) { 229a44504a1SJohn Scipione // The height will be uniform for the number of rows necessary 230a44504a1SJohn Scipione // to show all the replicants and gutters. 231*efafab64SAxel Dörfler int32 rowCount = (int32)(height / fMaxReplicantHeight); 232*efafab64SAxel Dörfler height = kGutter + (rowCount * fMaxReplicantHeight) 23341281cf3SAxel Dörfler + ((rowCount - 1) * kIconGap) + kGutter; 234*efafab64SAxel Dörfler height = std::max(fMinTrayHeight, height); 235a44504a1SJohn Scipione } else 236*efafab64SAxel Dörfler height = fMinTrayHeight; 23741281cf3SAxel Dörfler } else { 2381ad8c760SFredrik Holmqvist // if last replicant overruns clock then resize to accomodate 23932b0035aSJohn Scipione if (ReplicantCount() > 0) { 240c0be5490SJohn Scipione if (!fTime->IsHidden() && Bounds().right - kTrayPadding - 2 241c0be5490SJohn Scipione - fTime->Frame().Width() - kClockMargin 2427b7bf68dSJohn Scipione < fRightBottomReplicant.right + kClockMargin) { 2437b7bf68dSJohn Scipione width = fRightBottomReplicant.right + kClockMargin 244c0be5490SJohn Scipione + fTime->Frame().Width() + kTrayPadding + 2; 24541281cf3SAxel Dörfler } else 24670ad5289SJohn Scipione width = fRightBottomReplicant.right + kIconGap + kGutter; 24741281cf3SAxel Dörfler } 2481ad8c760SFredrik Holmqvist 24941281cf3SAxel Dörfler // this view has a fixed minimum width 250*efafab64SAxel Dörfler width = std::max(kMinimumTrayWidth, width); 2512ce9bab8SJohn Scipione height = kGutter + static_cast<TBarApp*>(be_app)->IconSize() + kGutter; 25241281cf3SAxel Dörfler } 25341281cf3SAxel Dörfler 25441281cf3SAxel Dörfler *preferredWidth = width; 2551ad8c760SFredrik Holmqvist // add 1 for the border 25641281cf3SAxel Dörfler *preferredHeight = height + 1; 25741281cf3SAxel Dörfler } 25841281cf3SAxel Dörfler 25941281cf3SAxel Dörfler 26041281cf3SAxel Dörfler void 26141281cf3SAxel Dörfler TReplicantTray::AdjustPlacement() 26241281cf3SAxel Dörfler { 26341281cf3SAxel Dörfler // called when an add-on has been added or removed 26441281cf3SAxel Dörfler // need to resize the parent of this accordingly 265a5210ab1SAxel Dörfler 26641281cf3SAxel Dörfler BRect bounds = Bounds(); 26741281cf3SAxel Dörfler float width, height; 26841281cf3SAxel Dörfler GetPreferredSize(&width, &height); 26941281cf3SAxel Dörfler 27041281cf3SAxel Dörfler if (width == bounds.Width() && height == bounds.Height()) { 27141281cf3SAxel Dörfler // no need to change anything 27241281cf3SAxel Dörfler return; 27341281cf3SAxel Dörfler } 27441281cf3SAxel Dörfler 27541281cf3SAxel Dörfler Parent()->ResizeToPreferred(); 27641281cf3SAxel Dörfler fBarView->UpdatePlacement(); 27741281cf3SAxel Dörfler Parent()->Invalidate(); 27841281cf3SAxel Dörfler Invalidate(); 27941281cf3SAxel Dörfler } 28041281cf3SAxel Dörfler 28141281cf3SAxel Dörfler 28241281cf3SAxel Dörfler void 28341281cf3SAxel Dörfler TReplicantTray::MessageReceived(BMessage* message) 28441281cf3SAxel Dörfler { 28541281cf3SAxel Dörfler switch (message->what) { 28630a55802SJohn Scipione case B_LOCALE_CHANGED: 287573f748cSJohn Scipione if (fTime == NULL) 288573f748cSJohn Scipione return; 289573f748cSJohn Scipione 2904c999927SAdrien Destugues fTime->UpdateTimeFormat(); 29131c0024dSJohn Scipione fTime->Update(); 29241281cf3SAxel Dörfler // time string reformat -> realign 293c0dc265cSJohn Scipione goto realignReplicants; 294573f748cSJohn Scipione 29530a55802SJohn Scipione case kShowHideTime: 29630a55802SJohn Scipione // from context menu in clock and in this view 29730a55802SJohn Scipione ShowHideTime(); 29830a55802SJohn Scipione break; 29930a55802SJohn Scipione 3003cf2d117SJohn Scipione case kShowSeconds: 301573f748cSJohn Scipione if (fTime == NULL) 302573f748cSJohn Scipione return; 303573f748cSJohn Scipione 3043cf2d117SJohn Scipione fTime->SetShowSeconds(!fTime->ShowSeconds()); 305573f748cSJohn Scipione 3063cf2d117SJohn Scipione // time string reformat -> realign 307c0dc265cSJohn Scipione goto realignReplicants; 3083cf2d117SJohn Scipione 3093cf2d117SJohn Scipione case kShowDayOfWeek: 3103cf2d117SJohn Scipione if (fTime == NULL) 3113cf2d117SJohn Scipione return; 3123cf2d117SJohn Scipione 3133cf2d117SJohn Scipione fTime->SetShowDayOfWeek(!fTime->ShowDayOfWeek()); 3143cf2d117SJohn Scipione 3153cf2d117SJohn Scipione // time string reformat -> realign 316c0dc265cSJohn Scipione goto realignReplicants; 3173cf2d117SJohn Scipione 31831c0024dSJohn Scipione case kShowTimeZone: 31931c0024dSJohn Scipione if (fTime == NULL) 32031c0024dSJohn Scipione return; 32131c0024dSJohn Scipione 32231c0024dSJohn Scipione fTime->SetShowTimeZone(!fTime->ShowTimeZone()); 32331c0024dSJohn Scipione 32431c0024dSJohn Scipione // time string reformat -> realign 325c0dc265cSJohn Scipione goto realignReplicants; 32631c0024dSJohn Scipione 32731c0024dSJohn Scipione case kGetClockSettings: 32831c0024dSJohn Scipione { 32931c0024dSJohn Scipione if (fTime == NULL) 33031c0024dSJohn Scipione return; 33131c0024dSJohn Scipione 33231c0024dSJohn Scipione bool showClock = !fTime->IsHidden(); 33331c0024dSJohn Scipione bool showSeconds = fTime->ShowSeconds(); 33431c0024dSJohn Scipione bool showDayOfWeek = fTime->ShowDayOfWeek(); 33531c0024dSJohn Scipione bool showTimeZone = fTime->ShowTimeZone(); 33631c0024dSJohn Scipione 3370fc30d89SDario Casalinuovo BMessage reply(kGetClockSettings); 3380fc30d89SDario Casalinuovo reply.AddBool("showClock", showClock); 3390fc30d89SDario Casalinuovo reply.AddBool("showSeconds", showSeconds); 3400fc30d89SDario Casalinuovo reply.AddBool("showDayOfWeek", showDayOfWeek); 3410fc30d89SDario Casalinuovo reply.AddBool("showTimeZone", showTimeZone); 3420fc30d89SDario Casalinuovo message->SendReply(&reply); 34331c0024dSJohn Scipione break; 34431c0024dSJohn Scipione } 34531c0024dSJohn Scipione 34641281cf3SAxel Dörfler #ifdef DB_ADDONS 34741281cf3SAxel Dörfler case B_NODE_MONITOR: 34841281cf3SAxel Dörfler HandleEntryUpdate(message); 34941281cf3SAxel Dörfler break; 35041281cf3SAxel Dörfler #endif 35141281cf3SAxel Dörfler 352c0dc265cSJohn Scipione case kRealignReplicants: 353c0dc265cSJohn Scipione realignReplicants: 354c0dc265cSJohn Scipione RealignReplicants(); 355c0dc265cSJohn Scipione AdjustPlacement(); 356c0dc265cSJohn Scipione break; 357c0dc265cSJohn Scipione 35841281cf3SAxel Dörfler default: 35941281cf3SAxel Dörfler BView::MessageReceived(message); 36041281cf3SAxel Dörfler break; 36141281cf3SAxel Dörfler } 36241281cf3SAxel Dörfler } 36341281cf3SAxel Dörfler 36441281cf3SAxel Dörfler 36541281cf3SAxel Dörfler void 36641281cf3SAxel Dörfler TReplicantTray::MouseDown(BPoint where) 36741281cf3SAxel Dörfler { 36841281cf3SAxel Dörfler #ifdef DB_ADDONS 36941281cf3SAxel Dörfler if (modifiers() & B_CONTROL_KEY) 37041281cf3SAxel Dörfler DumpList(fItemList); 37141281cf3SAxel Dörfler #endif 37241281cf3SAxel Dörfler 37341281cf3SAxel Dörfler uint32 buttons; 37441281cf3SAxel Dörfler 37541281cf3SAxel Dörfler Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); 37641281cf3SAxel Dörfler if (buttons == B_SECONDARY_MOUSE_BUTTON) { 37741281cf3SAxel Dörfler ShowReplicantMenu(where); 37841281cf3SAxel Dörfler } else { 37941281cf3SAxel Dörfler BPoint save = where; 38041281cf3SAxel Dörfler bigtime_t doubleClickSpeed; 38141281cf3SAxel Dörfler bigtime_t start = system_time(); 38241281cf3SAxel Dörfler uint32 buttons; 38341281cf3SAxel Dörfler 38441281cf3SAxel Dörfler get_click_speed(&doubleClickSpeed); 38541281cf3SAxel Dörfler 38641281cf3SAxel Dörfler do { 38741281cf3SAxel Dörfler if (fabs(where.x - save.x) > 4 || fabs(where.y - save.y) > 4) 38841281cf3SAxel Dörfler // user moved out of bounds of click area 38941281cf3SAxel Dörfler break; 39041281cf3SAxel Dörfler 39141281cf3SAxel Dörfler if ((system_time() - start) > (2 * doubleClickSpeed)) { 39241281cf3SAxel Dörfler ShowReplicantMenu(where); 39341281cf3SAxel Dörfler break; 39441281cf3SAxel Dörfler } 39541281cf3SAxel Dörfler 39641281cf3SAxel Dörfler snooze(50000); 39741281cf3SAxel Dörfler GetMouse(&where, &buttons); 39841281cf3SAxel Dörfler } while (buttons); 39941281cf3SAxel Dörfler } 40041281cf3SAxel Dörfler BView::MouseDown(where); 40141281cf3SAxel Dörfler } 40241281cf3SAxel Dörfler 4033cf2d117SJohn Scipione 4043cf2d117SJohn Scipione void 4053cf2d117SJohn Scipione TReplicantTray::ShowReplicantMenu(BPoint point) 4063cf2d117SJohn Scipione { 4073cf2d117SJohn Scipione BPopUpMenu* menu = new BPopUpMenu("", false, false); 4083cf2d117SJohn Scipione menu->SetFont(be_plain_font); 4093cf2d117SJohn Scipione 41031c0024dSJohn Scipione // If clock is visible show the extended menu, otherwise show "Show clock" 4113cf2d117SJohn Scipione 4123cf2d117SJohn Scipione if (!fTime->IsHidden()) 4133cf2d117SJohn Scipione fTime->ShowTimeOptions(ConvertToScreen(point)); 4143cf2d117SJohn Scipione else { 41531c0024dSJohn Scipione BMenuItem* item = new BMenuItem(B_TRANSLATE("Show clock"), 4163cf2d117SJohn Scipione new BMessage(kShowHideTime)); 4173cf2d117SJohn Scipione menu->AddItem(item); 4183cf2d117SJohn Scipione menu->SetTargetForItems(this); 4193cf2d117SJohn Scipione BPoint where = ConvertToScreen(point); 4203cf2d117SJohn Scipione menu->Go(where, true, true, BRect(where - BPoint(4, 4), 4213cf2d117SJohn Scipione where + BPoint(4, 4)), true); 4223cf2d117SJohn Scipione } 4233cf2d117SJohn Scipione } 4243cf2d117SJohn Scipione 4253cf2d117SJohn Scipione 4263cf2d117SJohn Scipione void 4273cf2d117SJohn Scipione TReplicantTray::SetMultiRow(bool state) 4283cf2d117SJohn Scipione { 4293cf2d117SJohn Scipione fMultiRowMode = state; 4303cf2d117SJohn Scipione } 4313cf2d117SJohn Scipione 4323cf2d117SJohn Scipione 4333cf2d117SJohn Scipione void 4343cf2d117SJohn Scipione TReplicantTray::ShowHideTime() 4353cf2d117SJohn Scipione { 4363cf2d117SJohn Scipione if (fTime == NULL) 4373cf2d117SJohn Scipione return; 4383cf2d117SJohn Scipione 4392a5c1f12SJohn Scipione // Check from the point of view of fTime because we need to ignore 4402a5c1f12SJohn Scipione // whether or not the parent window is hidden. 4412a5c1f12SJohn Scipione if (fTime->IsHidden(fTime)) 4423cf2d117SJohn Scipione fTime->Show(); 4433cf2d117SJohn Scipione else 4443cf2d117SJohn Scipione fTime->Hide(); 4453cf2d117SJohn Scipione 4463cf2d117SJohn Scipione RealignReplicants(); 4473cf2d117SJohn Scipione AdjustPlacement(); 44831c0024dSJohn Scipione 4492a5c1f12SJohn Scipione // Check from the point of view of fTime ignoring parent's state. 4502a5c1f12SJohn Scipione bool showClock = !fTime->IsHidden(fTime); 4513722e640SJohn Scipione 4523722e640SJohn Scipione // Update showClock setting that gets saved to disk on quit 4531bb2e623SJohn Scipione static_cast<TBarApp*>(be_app)->Settings()->showClock = showClock; 4543722e640SJohn Scipione 4553722e640SJohn Scipione // Send a message to Time preferences telling it to update 45631c0024dSJohn Scipione BMessenger messenger("application/x-vnd.Haiku-Time"); 4570fc30d89SDario Casalinuovo BMessage message(kShowHideTime); 4580fc30d89SDario Casalinuovo message.AddBool("showClock", showClock); 4590fc30d89SDario Casalinuovo messenger.SendMessage(&message); 4603cf2d117SJohn Scipione } 4613cf2d117SJohn Scipione 4623cf2d117SJohn Scipione 46341281cf3SAxel Dörfler #ifdef DB_ADDONS 46441281cf3SAxel Dörfler 4653cf2d117SJohn Scipione 46641281cf3SAxel Dörfler void 46741281cf3SAxel Dörfler TReplicantTray::InitAddOnSupport() 46841281cf3SAxel Dörfler { 46941281cf3SAxel Dörfler // list to maintain refs to each rep added/deleted 47041281cf3SAxel Dörfler fItemList = new BList(); 47141281cf3SAxel Dörfler BPath path; 4721ad8c760SFredrik Holmqvist 47326ea7066SIngo Weinhold if (GetDeskbarSettingsDirectory(path, true) == B_OK) { 4743e6ff860SRene Gollent path.Append(kReplicantSettingsFile); 47541281cf3SAxel Dörfler 47641281cf3SAxel Dörfler BFile file(path.Path(), B_READ_ONLY); 4773e6ff860SRene Gollent if (file.InitCheck() == B_OK) { 4783e6ff860SRene Gollent status_t result; 4793e6ff860SRene Gollent BEntry entry; 4803e6ff860SRene Gollent int32 id; 481c0ad1c91SRene Gollent BString path; 4823e6ff860SRene Gollent if (fAddOnSettings.Unflatten(&file) == B_OK) { 483c0ad1c91SRene Gollent for (int32 i = 0; fAddOnSettings.FindString(kReplicantPathField, 484c0ad1c91SRene Gollent i, &path) == B_OK; i++) { 485c0ad1c91SRene Gollent if (entry.SetTo(path.String()) == B_OK && entry.Exists()) { 4863e6ff860SRene Gollent result = LoadAddOn(&entry, &id, false); 4873e6ff860SRene Gollent } else 4883e6ff860SRene Gollent result = B_ENTRY_NOT_FOUND; 48941281cf3SAxel Dörfler 4903e6ff860SRene Gollent if (result != B_OK) { 491c0ad1c91SRene Gollent fAddOnSettings.RemoveData(kReplicantPathField, i); 4923e6ff860SRene Gollent --i; 49341281cf3SAxel Dörfler } 49441281cf3SAxel Dörfler } 49541281cf3SAxel Dörfler } 4963e6ff860SRene Gollent } 4973e6ff860SRene Gollent } 49841281cf3SAxel Dörfler } 49941281cf3SAxel Dörfler 50041281cf3SAxel Dörfler 50141281cf3SAxel Dörfler void 50241281cf3SAxel Dörfler TReplicantTray::DeleteAddOnSupport() 50341281cf3SAxel Dörfler { 5047625ce51SRene Gollent _SaveSettings(); 5053e6ff860SRene Gollent 5069f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 50741281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->RemoveItem(i); 50841281cf3SAxel Dörfler if (item) { 50941281cf3SAxel Dörfler if (item->isAddOn) 51041281cf3SAxel Dörfler watch_node(&(item->nodeRef), B_STOP_WATCHING, this, Window()); 51141281cf3SAxel Dörfler 51241281cf3SAxel Dörfler delete item; 51341281cf3SAxel Dörfler } 51441281cf3SAxel Dörfler } 51541281cf3SAxel Dörfler delete fItemList; 51641281cf3SAxel Dörfler 51741281cf3SAxel Dörfler // stop the volume mount/unmount watch 51841281cf3SAxel Dörfler stop_watching(this, Window()); 51941281cf3SAxel Dörfler } 52041281cf3SAxel Dörfler 52141281cf3SAxel Dörfler 52241281cf3SAxel Dörfler DeskbarItemInfo* 52341281cf3SAxel Dörfler TReplicantTray::DeskbarItemFor(node_ref& nodeRef) 52441281cf3SAxel Dörfler { 5259f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 52666eba86fSAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 52741281cf3SAxel Dörfler if (item == NULL) 52841281cf3SAxel Dörfler continue; 52941281cf3SAxel Dörfler 53041281cf3SAxel Dörfler if (item->nodeRef == nodeRef) 53141281cf3SAxel Dörfler return item; 53241281cf3SAxel Dörfler } 53341281cf3SAxel Dörfler 53441281cf3SAxel Dörfler return NULL; 53541281cf3SAxel Dörfler } 53641281cf3SAxel Dörfler 53741281cf3SAxel Dörfler 53841281cf3SAxel Dörfler DeskbarItemInfo* 53941281cf3SAxel Dörfler TReplicantTray::DeskbarItemFor(int32 id) 54041281cf3SAxel Dörfler { 5419f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 54266eba86fSAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 54341281cf3SAxel Dörfler if (item == NULL) 54441281cf3SAxel Dörfler continue; 54541281cf3SAxel Dörfler 54641281cf3SAxel Dörfler if (item->id == id) 54741281cf3SAxel Dörfler return item; 54841281cf3SAxel Dörfler } 54941281cf3SAxel Dörfler 55041281cf3SAxel Dörfler return NULL; 55141281cf3SAxel Dörfler } 55241281cf3SAxel Dörfler 55341281cf3SAxel Dörfler 55441281cf3SAxel Dörfler bool 55541281cf3SAxel Dörfler TReplicantTray::NodeExists(node_ref& nodeRef) 55641281cf3SAxel Dörfler { 55741281cf3SAxel Dörfler return DeskbarItemFor(nodeRef) != NULL; 55841281cf3SAxel Dörfler } 55941281cf3SAxel Dörfler 56041281cf3SAxel Dörfler 56166eba86fSAxel Dörfler /*! This handles B_NODE_MONITOR & B_QUERY_UPDATE messages received 56266eba86fSAxel Dörfler for the registered add-ons. 56341281cf3SAxel Dörfler */ 56441281cf3SAxel Dörfler void 56541281cf3SAxel Dörfler TReplicantTray::HandleEntryUpdate(BMessage* message) 56641281cf3SAxel Dörfler { 56741281cf3SAxel Dörfler int32 opcode; 56841281cf3SAxel Dörfler if (message->FindInt32("opcode", &opcode) != B_OK) 56941281cf3SAxel Dörfler return; 57041281cf3SAxel Dörfler 57141281cf3SAxel Dörfler BPath path; 57241281cf3SAxel Dörfler switch (opcode) { 57341281cf3SAxel Dörfler case B_ENTRY_MOVED: 57441281cf3SAxel Dörfler { 57541281cf3SAxel Dörfler entry_ref ref; 57641281cf3SAxel Dörfler ino_t todirectory; 57741281cf3SAxel Dörfler ino_t node; 57841281cf3SAxel Dörfler const char* name; 57941281cf3SAxel Dörfler if (message->FindString("name", &name) == B_OK 58071bd3ba5SJonas Sundström && message->FindInt64("from directory", &(ref.directory)) 58171bd3ba5SJonas Sundström == B_OK 58241281cf3SAxel Dörfler && message->FindInt64("to directory", &todirectory) == B_OK 58341281cf3SAxel Dörfler && message->FindInt32("device", &(ref.device)) == B_OK 58441281cf3SAxel Dörfler && message->FindInt64("node", &node) == B_OK ) { 58541281cf3SAxel Dörfler 586e4d65fe7SJohn Scipione if (name == NULL) 58741281cf3SAxel Dörfler break; 58841281cf3SAxel Dörfler 58941281cf3SAxel Dörfler ref.set_name(name); 59041281cf3SAxel Dörfler // change the directory reference to 59141281cf3SAxel Dörfler // the new directory 59241281cf3SAxel Dörfler MoveItem(&ref, todirectory); 59341281cf3SAxel Dörfler } 59441281cf3SAxel Dörfler break; 59566eba86fSAxel Dörfler } 59641281cf3SAxel Dörfler 59741281cf3SAxel Dörfler case B_ENTRY_REMOVED: 59841281cf3SAxel Dörfler { 59941281cf3SAxel Dörfler // entry was rm'd from the device 60041281cf3SAxel Dörfler node_ref nodeRef; 60141281cf3SAxel Dörfler if (message->FindInt32("device", &(nodeRef.device)) == B_OK 60241281cf3SAxel Dörfler && message->FindInt64("node", &(nodeRef.node)) == B_OK) { 60341281cf3SAxel Dörfler DeskbarItemInfo* item = DeskbarItemFor(nodeRef); 60441281cf3SAxel Dörfler if (item == NULL) 60541281cf3SAxel Dörfler break; 60641281cf3SAxel Dörfler 60741281cf3SAxel Dörfler // If there is a team running where the add-on comes from, 60841281cf3SAxel Dörfler // we don't want to remove the icon yet. 60941281cf3SAxel Dörfler if (be_roster->IsRunning(&item->entryRef)) 61041281cf3SAxel Dörfler break; 61141281cf3SAxel Dörfler 61241281cf3SAxel Dörfler UnloadAddOn(&nodeRef, NULL, true, false); 61341281cf3SAxel Dörfler } 61441281cf3SAxel Dörfler break; 61566eba86fSAxel Dörfler } 61641281cf3SAxel Dörfler } 61766eba86fSAxel Dörfler } 61841281cf3SAxel Dörfler 61941281cf3SAxel Dörfler 6201ad8c760SFredrik Holmqvist /*! The add-ons must support the exported C function API 62166eba86fSAxel Dörfler if they do, they will be loaded and added to deskbar 62266eba86fSAxel Dörfler primary function is the Instantiate function 6237da06231SAxel Dörfler */ 62441281cf3SAxel Dörfler status_t 6253e6ff860SRene Gollent TReplicantTray::LoadAddOn(BEntry* entry, int32* id, bool addToSettings) 62641281cf3SAxel Dörfler { 627e4d65fe7SJohn Scipione if (entry == NULL) 628a6be6c4dSJohn Scipione return B_BAD_VALUE; 62941281cf3SAxel Dörfler 63041281cf3SAxel Dörfler node_ref nodeRef; 63141281cf3SAxel Dörfler entry->GetNodeRef(&nodeRef); 63241281cf3SAxel Dörfler // no duplicates 63341281cf3SAxel Dörfler if (NodeExists(nodeRef)) 63441281cf3SAxel Dörfler return B_ERROR; 63541281cf3SAxel Dörfler 63641281cf3SAxel Dörfler BNode node(entry); 63741281cf3SAxel Dörfler BPath path; 63866eba86fSAxel Dörfler status_t status = entry->GetPath(&path); 639e4d65fe7SJohn Scipione if (status != B_OK) 64066eba86fSAxel Dörfler return status; 64141281cf3SAxel Dörfler 64241281cf3SAxel Dörfler // load the add-on 64341281cf3SAxel Dörfler image_id image = load_add_on(path.Path()); 64466eba86fSAxel Dörfler if (image < B_OK) 64566eba86fSAxel Dörfler return image; 64641281cf3SAxel Dörfler 64741281cf3SAxel Dörfler // get the view loading function symbol 64841281cf3SAxel Dörfler // we first look for a symbol that takes an image_id 64941281cf3SAxel Dörfler // and entry_ref pointer, if not found, go with normal 65041281cf3SAxel Dörfler // instantiate function 651*efafab64SAxel Dörfler BView* (*entryFunction)(image_id, const entry_ref*, float, float); 652*efafab64SAxel Dörfler BView* (*itemFunction)(float, float); 65341281cf3SAxel Dörfler BView* view = NULL; 65441281cf3SAxel Dörfler 65541281cf3SAxel Dörfler entry_ref ref; 65641281cf3SAxel Dörfler entry->GetRef(&ref); 65741281cf3SAxel Dörfler 65841281cf3SAxel Dörfler if (get_image_symbol(image, kInstantiateEntryCFunctionName, 65966eba86fSAxel Dörfler B_SYMBOL_TYPE_TEXT, (void**)&entryFunction) >= B_OK) { 660*efafab64SAxel Dörfler view = (*entryFunction)(image, &ref, fMaxReplicantWidth, 661*efafab64SAxel Dörfler fMaxReplicantHeight); 66241281cf3SAxel Dörfler } else if (get_image_symbol(image, kInstantiateItemCFunctionName, 66366eba86fSAxel Dörfler B_SYMBOL_TYPE_TEXT, (void**)&itemFunction) >= B_OK) { 664*efafab64SAxel Dörfler view = (*itemFunction)(fMaxReplicantWidth, fMaxReplicantHeight); 66541281cf3SAxel Dörfler } else { 66641281cf3SAxel Dörfler unload_add_on(image); 66741281cf3SAxel Dörfler return B_ERROR; 66841281cf3SAxel Dörfler } 66941281cf3SAxel Dörfler 67066eba86fSAxel Dörfler if (view == NULL || IconExists(view->Name())) { 67141281cf3SAxel Dörfler delete view; 67241281cf3SAxel Dörfler unload_add_on(image); 67341281cf3SAxel Dörfler return B_ERROR; 67441281cf3SAxel Dörfler } 67541281cf3SAxel Dörfler 67641281cf3SAxel Dörfler BMessage* data = new BMessage; 67741281cf3SAxel Dörfler view->Archive(data); 67841281cf3SAxel Dörfler delete view; 67941281cf3SAxel Dörfler 68041281cf3SAxel Dörfler // add the rep; adds info to list 6810fc30d89SDario Casalinuovo if (AddIcon(data, id, &ref) != B_OK) 6820fc30d89SDario Casalinuovo delete data; 68341281cf3SAxel Dörfler 6843e6ff860SRene Gollent if (addToSettings) { 685c0ad1c91SRene Gollent fAddOnSettings.AddString(kReplicantPathField, path.Path()); 6867625ce51SRene Gollent _SaveSettings(); 6873e6ff860SRene Gollent } 68841281cf3SAxel Dörfler 68941281cf3SAxel Dörfler return B_OK; 69041281cf3SAxel Dörfler } 69141281cf3SAxel Dörfler 69241281cf3SAxel Dörfler 69341281cf3SAxel Dörfler status_t 69441281cf3SAxel Dörfler TReplicantTray::AddItem(int32 id, node_ref nodeRef, BEntry& entry, bool isAddOn) 69541281cf3SAxel Dörfler { 69641281cf3SAxel Dörfler DeskbarItemInfo* item = new DeskbarItemInfo; 69741281cf3SAxel Dörfler if (item == NULL) 69841281cf3SAxel Dörfler return B_NO_MEMORY; 69941281cf3SAxel Dörfler 70041281cf3SAxel Dörfler item->id = id; 70141281cf3SAxel Dörfler item->isAddOn = isAddOn; 70241281cf3SAxel Dörfler 703e4d65fe7SJohn Scipione if (entry.GetRef(&item->entryRef) != B_OK) { 70441281cf3SAxel Dörfler item->entryRef.device = -1; 70541281cf3SAxel Dörfler item->entryRef.directory = -1; 70641281cf3SAxel Dörfler item->entryRef.name = NULL; 70741281cf3SAxel Dörfler } 70841281cf3SAxel Dörfler item->nodeRef = nodeRef; 70941281cf3SAxel Dörfler 71041281cf3SAxel Dörfler fItemList->AddItem(item); 71141281cf3SAxel Dörfler 71241281cf3SAxel Dörfler if (isAddOn) 71341281cf3SAxel Dörfler watch_node(&nodeRef, B_WATCH_NAME | B_WATCH_ATTR, this, Window()); 71441281cf3SAxel Dörfler 71541281cf3SAxel Dörfler return B_OK; 71641281cf3SAxel Dörfler } 71741281cf3SAxel Dörfler 71841281cf3SAxel Dörfler 71941281cf3SAxel Dörfler /** from entry_removed message, when attribute removed 72041281cf3SAxel Dörfler * or when a device is unmounted (use removeall, by device) 72141281cf3SAxel Dörfler */ 72241281cf3SAxel Dörfler 72341281cf3SAxel Dörfler void 724e4d65fe7SJohn Scipione TReplicantTray::UnloadAddOn(node_ref* nodeRef, dev_t* device, bool which, 725e4d65fe7SJohn Scipione bool removeAll) 72641281cf3SAxel Dörfler { 7279f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 72841281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 729e4d65fe7SJohn Scipione if (item == NULL) 73041281cf3SAxel Dörfler continue; 73141281cf3SAxel Dörfler 732e4d65fe7SJohn Scipione if ((which && nodeRef != NULL && item->nodeRef == *nodeRef) 733e4d65fe7SJohn Scipione || (device != NULL && item->nodeRef.device == *device)) { 73441281cf3SAxel Dörfler 735e4d65fe7SJohn Scipione if (device != NULL && be_roster->IsRunning(&item->entryRef)) 73641281cf3SAxel Dörfler continue; 73741281cf3SAxel Dörfler 73841281cf3SAxel Dörfler RemoveIcon(item->id); 73941281cf3SAxel Dörfler 74041281cf3SAxel Dörfler if (!removeAll) 74141281cf3SAxel Dörfler break; 74241281cf3SAxel Dörfler } 74341281cf3SAxel Dörfler } 74441281cf3SAxel Dörfler } 74541281cf3SAxel Dörfler 74641281cf3SAxel Dörfler 74741281cf3SAxel Dörfler void 74841281cf3SAxel Dörfler TReplicantTray::RemoveItem(int32 id) 74941281cf3SAxel Dörfler { 75041281cf3SAxel Dörfler DeskbarItemInfo* item = DeskbarItemFor(id); 75141281cf3SAxel Dörfler if (item == NULL) 75241281cf3SAxel Dörfler return; 75341281cf3SAxel Dörfler 75441281cf3SAxel Dörfler // attribute was added via Deskbar API (AddItem(entry_ref*, int32*) 75541281cf3SAxel Dörfler if (item->isAddOn) { 7567625ce51SRene Gollent BPath path(&item->entryRef); 7577625ce51SRene Gollent BString storedPath; 7587625ce51SRene Gollent for (int32 i = 0; 7598aab28f1SRene Gollent fAddOnSettings.FindString(kReplicantPathField, i, &storedPath) 7607625ce51SRene Gollent == B_OK; i++) { 7617625ce51SRene Gollent if (storedPath == path.Path()) { 7628aab28f1SRene Gollent fAddOnSettings.RemoveData(kReplicantPathField, i); 7637625ce51SRene Gollent break; 7647625ce51SRene Gollent } 7657625ce51SRene Gollent } 7667625ce51SRene Gollent _SaveSettings(); 7677625ce51SRene Gollent 76841281cf3SAxel Dörfler BNode node(&item->entryRef); 76941281cf3SAxel Dörfler watch_node(&item->nodeRef, B_STOP_WATCHING, this, Window()); 77041281cf3SAxel Dörfler } 77141281cf3SAxel Dörfler 77241281cf3SAxel Dörfler fItemList->RemoveItem(item); 77341281cf3SAxel Dörfler delete item; 77441281cf3SAxel Dörfler } 77541281cf3SAxel Dörfler 77641281cf3SAxel Dörfler 77741281cf3SAxel Dörfler /** ENTRY_MOVED message, moving only occurs on a device 77841281cf3SAxel Dörfler * copying will occur (ENTRY_CREATED) between devices 77941281cf3SAxel Dörfler */ 78041281cf3SAxel Dörfler 78141281cf3SAxel Dörfler void 78241281cf3SAxel Dörfler TReplicantTray::MoveItem(entry_ref* ref, ino_t toDirectory) 78341281cf3SAxel Dörfler { 784e4d65fe7SJohn Scipione if (ref == NULL) 78541281cf3SAxel Dörfler return; 78641281cf3SAxel Dörfler 78741281cf3SAxel Dörfler // scan for a matching entry_ref and update it 78841281cf3SAxel Dörfler // 78941281cf3SAxel Dörfler // don't need to change node info as it does not change 79041281cf3SAxel Dörfler 7919f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 79241281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 793e4d65fe7SJohn Scipione if (item == NULL) 79441281cf3SAxel Dörfler continue; 79541281cf3SAxel Dörfler 796e4d65fe7SJohn Scipione if (strcmp(item->entryRef.name, ref->name) == 0 79741281cf3SAxel Dörfler && item->entryRef.device == ref->device 79841281cf3SAxel Dörfler && item->entryRef.directory == ref->directory) { 79941281cf3SAxel Dörfler item->entryRef.directory = toDirectory; 80041281cf3SAxel Dörfler break; 80141281cf3SAxel Dörfler } 80241281cf3SAxel Dörfler } 80341281cf3SAxel Dörfler } 80441281cf3SAxel Dörfler 80541281cf3SAxel Dörfler #endif // add-on support 80641281cf3SAxel Dörfler 80741281cf3SAxel Dörfler // external add-on API routines 80841281cf3SAxel Dörfler // called using the new BDeskbar class 80941281cf3SAxel Dörfler 81041281cf3SAxel Dörfler // existence of icon/replicant by name or ID 81141281cf3SAxel Dörfler // returns opposite 81241281cf3SAxel Dörfler // note: name and id are semi-private limiting 81341281cf3SAxel Dörfler // the ability of non-host apps to remove 81441281cf3SAxel Dörfler // icons without a little bit of work 81541281cf3SAxel Dörfler 81641281cf3SAxel Dörfler /** for a specific id 81741281cf3SAxel Dörfler * return the name of the replicant (name of view) 81841281cf3SAxel Dörfler */ 81941281cf3SAxel Dörfler 82041281cf3SAxel Dörfler status_t 82141281cf3SAxel Dörfler TReplicantTray::ItemInfo(int32 id, const char** name) 82241281cf3SAxel Dörfler { 82341281cf3SAxel Dörfler if (id < 0) 824a6be6c4dSJohn Scipione return B_BAD_VALUE; 82541281cf3SAxel Dörfler 826e4d65fe7SJohn Scipione int32 index; 827e4d65fe7SJohn Scipione int32 temp; 82841281cf3SAxel Dörfler BView* view = ViewAt(&index, &temp, id, false); 829e4d65fe7SJohn Scipione if (view != NULL) { 83041281cf3SAxel Dörfler *name = view->Name(); 83141281cf3SAxel Dörfler return B_OK; 83241281cf3SAxel Dörfler } 83341281cf3SAxel Dörfler 83441281cf3SAxel Dörfler return B_ERROR; 83541281cf3SAxel Dörfler } 83641281cf3SAxel Dörfler 83741281cf3SAxel Dörfler 8387da06231SAxel Dörfler /** for a specific name 8397da06231SAxel Dörfler * return the id (internal to Deskbar) 8407da06231SAxel Dörfler */ 8417da06231SAxel Dörfler 84241281cf3SAxel Dörfler status_t 84341281cf3SAxel Dörfler TReplicantTray::ItemInfo(const char* name, int32* id) 84441281cf3SAxel Dörfler { 845e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 846a6be6c4dSJohn Scipione return B_BAD_VALUE; 84741281cf3SAxel Dörfler 84841281cf3SAxel Dörfler int32 index; 84941281cf3SAxel Dörfler BView* view = ViewAt(&index, id, name); 85041281cf3SAxel Dörfler 851378aa08bSJohn Scipione return view != NULL ? B_OK : B_ERROR; 85241281cf3SAxel Dörfler } 85341281cf3SAxel Dörfler 85441281cf3SAxel Dörfler 8557da06231SAxel Dörfler /** at a specific index 8567da06231SAxel Dörfler * return both the name and the id of the replicant 8577da06231SAxel Dörfler */ 8587da06231SAxel Dörfler 85941281cf3SAxel Dörfler status_t 86041281cf3SAxel Dörfler TReplicantTray::ItemInfo(int32 index, const char** name, int32* id) 86141281cf3SAxel Dörfler { 86241281cf3SAxel Dörfler if (index < 0) 863a6be6c4dSJohn Scipione return B_BAD_VALUE; 86441281cf3SAxel Dörfler 86541281cf3SAxel Dörfler BView* view; 86641281cf3SAxel Dörfler fShelf->ReplicantAt(index, &view, (uint32*)id, NULL); 867e4d65fe7SJohn Scipione if (view != NULL) { 86841281cf3SAxel Dörfler *name = view->Name(); 86941281cf3SAxel Dörfler return B_OK; 87041281cf3SAxel Dörfler } 87141281cf3SAxel Dörfler 87241281cf3SAxel Dörfler return B_ERROR; 87341281cf3SAxel Dörfler } 87441281cf3SAxel Dörfler 87541281cf3SAxel Dörfler 8767da06231SAxel Dörfler /** replicant exists, by id/index */ 8777da06231SAxel Dörfler 87841281cf3SAxel Dörfler bool 87941281cf3SAxel Dörfler TReplicantTray::IconExists(int32 target, bool byIndex) 88041281cf3SAxel Dörfler { 881e4d65fe7SJohn Scipione int32 index; 882e4d65fe7SJohn Scipione int32 id; 88341281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 88441281cf3SAxel Dörfler 88541281cf3SAxel Dörfler return view && index >= 0; 88641281cf3SAxel Dörfler } 88741281cf3SAxel Dörfler 88841281cf3SAxel Dörfler 8897da06231SAxel Dörfler /** replicant exists, by name */ 8907da06231SAxel Dörfler 89141281cf3SAxel Dörfler bool 89241281cf3SAxel Dörfler TReplicantTray::IconExists(const char* name) 89341281cf3SAxel Dörfler { 894e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 89541281cf3SAxel Dörfler return false; 89641281cf3SAxel Dörfler 897e4d65fe7SJohn Scipione int32 index; 898e4d65fe7SJohn Scipione int32 id; 89941281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 90041281cf3SAxel Dörfler 901e4d65fe7SJohn Scipione return view != NULL && index >= 0; 90241281cf3SAxel Dörfler } 90341281cf3SAxel Dörfler 90441281cf3SAxel Dörfler 90541281cf3SAxel Dörfler int32 90632b0035aSJohn Scipione TReplicantTray::ReplicantCount() const 90741281cf3SAxel Dörfler { 90841281cf3SAxel Dörfler return fShelf->CountReplicants(); 90941281cf3SAxel Dörfler } 91041281cf3SAxel Dörfler 91141281cf3SAxel Dörfler 912ced3755cSAxel Dörfler /*! Message must contain an archivable view for later rehydration. 913ced3755cSAxel Dörfler This function takes over ownership of the provided message on success 914ced3755cSAxel Dörfler only. 915ced3755cSAxel Dörfler Returns the current replicant ID. 9167da06231SAxel Dörfler */ 91741281cf3SAxel Dörfler status_t 918ced3755cSAxel Dörfler TReplicantTray::AddIcon(BMessage* archive, int32* id, const entry_ref* addOn) 91941281cf3SAxel Dörfler { 920ced3755cSAxel Dörfler if (archive == NULL || id == NULL) 921a6be6c4dSJohn Scipione return B_BAD_VALUE; 92241281cf3SAxel Dörfler 9239c50f36eSAxel Dörfler // find entry_ref 9249c50f36eSAxel Dörfler 9259c50f36eSAxel Dörfler entry_ref ref; 926e4d65fe7SJohn Scipione if (addOn != NULL) { 9279c50f36eSAxel Dörfler // Use it if we got it 9289c50f36eSAxel Dörfler ref = *addOn; 9299c50f36eSAxel Dörfler } else { 9309c50f36eSAxel Dörfler const char* signature; 9311ad8c760SFredrik Holmqvist 932ced3755cSAxel Dörfler status_t status = archive->FindString("add_on", &signature); 9339c50f36eSAxel Dörfler if (status == B_OK) { 9349c50f36eSAxel Dörfler BRoster roster; 9359c50f36eSAxel Dörfler status = roster.FindApp(signature, &ref); 9369c50f36eSAxel Dörfler } 937e4d65fe7SJohn Scipione if (status != B_OK) 9389c50f36eSAxel Dörfler return status; 9399c50f36eSAxel Dörfler } 9409c50f36eSAxel Dörfler 9419c50f36eSAxel Dörfler BFile file; 9429c50f36eSAxel Dörfler status_t status = file.SetTo(&ref, B_READ_ONLY); 943e4d65fe7SJohn Scipione if (status != B_OK) 9449c50f36eSAxel Dörfler return status; 9459c50f36eSAxel Dörfler 9469c50f36eSAxel Dörfler node_ref nodeRef; 9479c50f36eSAxel Dörfler status = file.GetNodeRef(&nodeRef); 948e4d65fe7SJohn Scipione if (status != B_OK) 9499c50f36eSAxel Dörfler return status; 9509c50f36eSAxel Dörfler 9519c50f36eSAxel Dörfler BEntry entry(&ref, true); 9521ad8c760SFredrik Holmqvist // TODO: this resolves an eventual link for the item being added - this 9531ad8c760SFredrik Holmqvist // is okay for now, but in multi-user environments, one might want to 9541ad8c760SFredrik Holmqvist // have links that carry the be:deskbar_item_status attribute 9559c50f36eSAxel Dörfler status = entry.InitCheck(); 9569c50f36eSAxel Dörfler if (status != B_OK) 9579c50f36eSAxel Dörfler return status; 9589c50f36eSAxel Dörfler 95941281cf3SAxel Dörfler *id = 999; 960ced3755cSAxel Dörfler if (archive->what == B_ARCHIVED_OBJECT) 961ced3755cSAxel Dörfler archive->what = 0; 96241281cf3SAxel Dörfler 963ced3755cSAxel Dörfler BRect originalBounds = archive->FindRect("_frame"); 9641ad8c760SFredrik Holmqvist // this is a work-around for buggy replicants that change their size in 9651ad8c760SFredrik Holmqvist // AttachedToWindow() (such as "SVM") 966a5210ab1SAxel Dörfler 9671ad8c760SFredrik Holmqvist // TODO: check for name collisions? 968ced3755cSAxel Dörfler status = fShelf->AddReplicant(archive, BPoint(1, 1)); 9699c50f36eSAxel Dörfler if (status != B_OK) 9709c50f36eSAxel Dörfler return status; 97141281cf3SAxel Dörfler 97232b0035aSJohn Scipione int32 count = ReplicantCount(); 973a5210ab1SAxel Dörfler BView* view; 974a5210ab1SAxel Dörfler fShelf->ReplicantAt(count - 1, &view, (uint32*)id, NULL); 975a5210ab1SAxel Dörfler 976a6be6c4dSJohn Scipione if (view != NULL && originalBounds != view->Bounds()) { 977a5210ab1SAxel Dörfler // The replicant changed its size when added to the window, so we need 97871bd3ba5SJonas Sundström // to recompute all over again (it's already done once via 97971bd3ba5SJonas Sundström // BShelf::AddReplicant() and TReplicantShelf::CanAcceptReplicantView()) 980a5210ab1SAxel Dörfler RealignReplicants(); 981a5210ab1SAxel Dörfler } 982a5210ab1SAxel Dörfler 98341281cf3SAxel Dörfler float oldWidth = Bounds().Width(); 98441281cf3SAxel Dörfler float oldHeight = Bounds().Height(); 98541281cf3SAxel Dörfler float width, height; 98641281cf3SAxel Dörfler GetPreferredSize(&width, &height); 98741281cf3SAxel Dörfler if (oldWidth != width || oldHeight != height) 98841281cf3SAxel Dörfler AdjustPlacement(); 98941281cf3SAxel Dörfler 99041281cf3SAxel Dörfler // add the item to the add-on list 99141281cf3SAxel Dörfler 99241281cf3SAxel Dörfler AddItem(*id, nodeRef, entry, addOn != NULL); 99341281cf3SAxel Dörfler return B_OK; 99441281cf3SAxel Dörfler } 99541281cf3SAxel Dörfler 99641281cf3SAxel Dörfler 99741281cf3SAxel Dörfler void 99841281cf3SAxel Dörfler TReplicantTray::RemoveIcon(int32 target, bool byIndex) 99941281cf3SAxel Dörfler { 100041281cf3SAxel Dörfler if (target < 0) 100141281cf3SAxel Dörfler return; 100241281cf3SAxel Dörfler 1003e4d65fe7SJohn Scipione int32 index; 1004e4d65fe7SJohn Scipione int32 id; 100541281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 1006e4d65fe7SJohn Scipione if (view != NULL && index >= 0) { 10077da06231SAxel Dörfler // remove the reference from the item list & the shelf 100841281cf3SAxel Dörfler RemoveItem(id); 100941281cf3SAxel Dörfler fShelf->DeleteReplicant(index); 10107da06231SAxel Dörfler 101141281cf3SAxel Dörfler // force a placement update, !! need to fix BShelf 101241281cf3SAxel Dörfler RealReplicantAdjustment(index); 101341281cf3SAxel Dörfler } 101441281cf3SAxel Dörfler } 101541281cf3SAxel Dörfler 101641281cf3SAxel Dörfler 101741281cf3SAxel Dörfler void 101841281cf3SAxel Dörfler TReplicantTray::RemoveIcon(const char* name) 101941281cf3SAxel Dörfler { 1020e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 102141281cf3SAxel Dörfler return; 102241281cf3SAxel Dörfler 1023378aa08bSJohn Scipione int32 index; 1024378aa08bSJohn Scipione int32 id; 102541281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 1026e4d65fe7SJohn Scipione if (view != NULL && index >= 0) { 10277da06231SAxel Dörfler // remove the reference from the item list & shelf 102841281cf3SAxel Dörfler RemoveItem(id); 102941281cf3SAxel Dörfler fShelf->DeleteReplicant(index); 10307da06231SAxel Dörfler 103141281cf3SAxel Dörfler // force a placement update, !! need to fix BShelf 103241281cf3SAxel Dörfler RealReplicantAdjustment(index); 103341281cf3SAxel Dörfler } 103441281cf3SAxel Dörfler } 103541281cf3SAxel Dörfler 103641281cf3SAxel Dörfler 103741281cf3SAxel Dörfler void 10387da06231SAxel Dörfler TReplicantTray::RealReplicantAdjustment(int32 startIndex) 103941281cf3SAxel Dörfler { 10407da06231SAxel Dörfler if (startIndex < 0) 104141281cf3SAxel Dörfler return; 10427da06231SAxel Dörfler 10437da06231SAxel Dörfler if (startIndex == fLastReplicant) 10447da06231SAxel Dörfler startIndex = 0; 10457da06231SAxel Dörfler 104641281cf3SAxel Dörfler // reset the locations of all replicants after the one deleted 10477da06231SAxel Dörfler RealignReplicants(startIndex); 104841281cf3SAxel Dörfler 104941281cf3SAxel Dörfler float oldWidth = Bounds().Width(); 105041281cf3SAxel Dörfler float oldHeight = Bounds().Height(); 105141281cf3SAxel Dörfler float width, height; 105241281cf3SAxel Dörfler GetPreferredSize(&width, &height); 105341281cf3SAxel Dörfler if (oldWidth != width || oldHeight != height) { 10541ad8c760SFredrik Holmqvist // resize view to accomodate the replicants, redraw as necessary 105541281cf3SAxel Dörfler AdjustPlacement(); 105641281cf3SAxel Dörfler } 105741281cf3SAxel Dörfler } 105841281cf3SAxel Dörfler 105941281cf3SAxel Dörfler 10607da06231SAxel Dörfler /** looking for a replicant by id/index 10617da06231SAxel Dörfler * return the view and index 10627da06231SAxel Dörfler */ 10637da06231SAxel Dörfler 106441281cf3SAxel Dörfler BView* 106541281cf3SAxel Dörfler TReplicantTray::ViewAt(int32* index, int32* id, int32 target, bool byIndex) 106641281cf3SAxel Dörfler { 106741281cf3SAxel Dörfler *index = -1; 106841281cf3SAxel Dörfler 106941281cf3SAxel Dörfler BView* view; 107041281cf3SAxel Dörfler if (byIndex) { 107141281cf3SAxel Dörfler if (fShelf->ReplicantAt(target, &view, (uint32*)id)) { 1072e4d65fe7SJohn Scipione if (view != NULL) { 107341281cf3SAxel Dörfler *index = target; 1074e4d65fe7SJohn Scipione 107541281cf3SAxel Dörfler return view; 107641281cf3SAxel Dörfler } 107741281cf3SAxel Dörfler } 107841281cf3SAxel Dörfler } else { 107932b0035aSJohn Scipione int32 count = ReplicantCount() - 1; 108041281cf3SAxel Dörfler int32 localid; 108141281cf3SAxel Dörfler for (int32 repIndex = count; repIndex >= 0; repIndex--) { 108241281cf3SAxel Dörfler fShelf->ReplicantAt(repIndex, &view, (uint32*)&localid); 1083e4d65fe7SJohn Scipione if (localid == target && view != NULL) { 108441281cf3SAxel Dörfler *index = repIndex; 108541281cf3SAxel Dörfler *id = localid; 1086e4d65fe7SJohn Scipione 108741281cf3SAxel Dörfler return view; 108841281cf3SAxel Dörfler } 108941281cf3SAxel Dörfler } 109041281cf3SAxel Dörfler } 1091e4d65fe7SJohn Scipione 109241281cf3SAxel Dörfler return NULL; 109341281cf3SAxel Dörfler } 109441281cf3SAxel Dörfler 109541281cf3SAxel Dörfler 10967da06231SAxel Dörfler /** looking for a replicant with a view by name 10977da06231SAxel Dörfler * return the view, index and the id of the replicant 10987da06231SAxel Dörfler */ 10997da06231SAxel Dörfler 110041281cf3SAxel Dörfler BView* 110141281cf3SAxel Dörfler TReplicantTray::ViewAt(int32* index, int32* id, const char* name) 110241281cf3SAxel Dörfler { 110341281cf3SAxel Dörfler *index = -1; 110441281cf3SAxel Dörfler *id = -1; 110541281cf3SAxel Dörfler 110641281cf3SAxel Dörfler BView* view; 110732b0035aSJohn Scipione int32 count = ReplicantCount() - 1; 110841281cf3SAxel Dörfler for (int32 repIndex = count; repIndex >= 0; repIndex--) { 110941281cf3SAxel Dörfler fShelf->ReplicantAt(repIndex, &view, (uint32*)id); 11103641948fSJohn Scipione if (view != NULL && view->Name() != NULL 1111e4d65fe7SJohn Scipione && strcmp(name, view->Name()) == 0) { 111241281cf3SAxel Dörfler *index = repIndex; 1113e4d65fe7SJohn Scipione 111441281cf3SAxel Dörfler return view; 111541281cf3SAxel Dörfler } 111641281cf3SAxel Dörfler } 1117e4d65fe7SJohn Scipione 111841281cf3SAxel Dörfler return NULL; 111941281cf3SAxel Dörfler } 112041281cf3SAxel Dörfler 112141281cf3SAxel Dörfler 11227da06231SAxel Dörfler /** Shelf will call to determine where and if 11237da06231SAxel Dörfler * the replicant is to be added 11247da06231SAxel Dörfler */ 11257da06231SAxel Dörfler 112641281cf3SAxel Dörfler bool 112741281cf3SAxel Dörfler TReplicantTray::AcceptAddon(BRect replicantFrame, BMessage* message) 112841281cf3SAxel Dörfler { 1129e4d65fe7SJohn Scipione if (message == NULL) 113041281cf3SAxel Dörfler return false; 113141281cf3SAxel Dörfler 1132*efafab64SAxel Dörfler if (replicantFrame.Height() > fMaxReplicantHeight) 113341281cf3SAxel Dörfler return false; 113441281cf3SAxel Dörfler 113541281cf3SAxel Dörfler alignment align = B_ALIGN_LEFT; 113641281cf3SAxel Dörfler if (fAlignmentSupport && message->HasBool("deskbar:dynamic_align")) { 113741281cf3SAxel Dörfler if (!fBarView->Vertical()) 113841281cf3SAxel Dörfler align = B_ALIGN_RIGHT; 113941281cf3SAxel Dörfler else 114041281cf3SAxel Dörfler align = fBarView->Left() ? B_ALIGN_LEFT : B_ALIGN_RIGHT; 114141281cf3SAxel Dörfler } else if (message->HasInt32("deskbar:align")) 114241281cf3SAxel Dörfler message->FindInt32("deskbar:align", (int32*)&align); 114341281cf3SAxel Dörfler 114441281cf3SAxel Dörfler if (message->HasInt32("deskbar:private_align")) 114541281cf3SAxel Dörfler message->FindInt32("deskbar:private_align", (int32*)&align); 114641281cf3SAxel Dörfler else 114741281cf3SAxel Dörfler align = B_ALIGN_LEFT; 114841281cf3SAxel Dörfler 114932b0035aSJohn Scipione BPoint loc = LocationForReplicant(ReplicantCount(), 11507da06231SAxel Dörfler replicantFrame.Width()); 115141281cf3SAxel Dörfler message->AddPoint("_pjp_loc", loc); 1152e4d65fe7SJohn Scipione 115341281cf3SAxel Dörfler return true; 115441281cf3SAxel Dörfler } 115541281cf3SAxel Dörfler 115641281cf3SAxel Dörfler 115741281cf3SAxel Dörfler /** based on the previous (index - 1) replicant in the list 115841281cf3SAxel Dörfler * calculate where the left point should be for this 115941281cf3SAxel Dörfler * replicant. replicant will flow to the right on its own 116041281cf3SAxel Dörfler */ 116141281cf3SAxel Dörfler 116241281cf3SAxel Dörfler BPoint 116332b0035aSJohn Scipione TReplicantTray::LocationForReplicant(int32 index, float replicantWidth) 116441281cf3SAxel Dörfler { 116570ad5289SJohn Scipione BPoint loc(kTrayPadding, 2); 116670ad5289SJohn Scipione if (fBarView->Vertical()) { 116770ad5289SJohn Scipione if (!fBarView->Left()) 116870ad5289SJohn Scipione loc.x += kDragWidth; // move past dragger 116970ad5289SJohn Scipione } else 117070ad5289SJohn Scipione loc.x += 1; // keeps everything lined up nicely 117141281cf3SAxel Dörfler 11727da06231SAxel Dörfler if (fMultiRowMode) { 11737da06231SAxel Dörfler // try to find free space in every row 1174*efafab64SAxel Dörfler for (int32 row = 0; ; loc.y += fMaxReplicantHeight + kIconGap, row++) { 11757da06231SAxel Dörfler // determine free space in this row 1176a44504a1SJohn Scipione BRect rowRect(loc.x, loc.y, 11771bb2e623SJohn Scipione loc.x + static_cast<TBarApp*>(be_app)->Settings()->width 1178015b5dd6SJohn Scipione - (kTrayPadding + kDragWidth + kGutter) * 2, 1179*efafab64SAxel Dörfler loc.y + fMaxReplicantHeight); 1180bc08a7d6SJohn Scipione if (row == 0 && !fTime->IsHidden()) 1181bc08a7d6SJohn Scipione rowRect.right -= kClockMargin + fTime->Frame().Width(); 11827da06231SAxel Dörfler 1183a44504a1SJohn Scipione BRect replicantRect = rowRect; 11847da06231SAxel Dörfler for (int32 i = 0; i < index; i++) { 11857da06231SAxel Dörfler BView* view = NULL; 11867da06231SAxel Dörfler fShelf->ReplicantAt(i, &view); 1187a44504a1SJohn Scipione if (view == NULL || view->Frame().top != rowRect.top) 11887da06231SAxel Dörfler continue; 11897da06231SAxel Dörfler 1190a44504a1SJohn Scipione // push this replicant placement past the last one 1191a44504a1SJohn Scipione replicantRect.left = view->Frame().right + kIconGap + 1; 11927da06231SAxel Dörfler } 11937da06231SAxel Dörfler 1194bc08a7d6SJohn Scipione // calculated left position, add replicantWidth to get right position 1195bc08a7d6SJohn Scipione replicantRect.right = replicantRect.left + replicantWidth; 1196bc08a7d6SJohn Scipione 1197bc08a7d6SJohn Scipione // check if replicant fits in this row 1198bc08a7d6SJohn Scipione if (replicantRect.right < rowRect.right) { 1199bc08a7d6SJohn Scipione // replicant fits in this row 1200a44504a1SJohn Scipione loc = replicantRect.LeftTop(); 12017da06231SAxel Dörfler break; 12027da06231SAxel Dörfler } 1203bc08a7d6SJohn Scipione 1204bc08a7d6SJohn Scipione // check next row 12057da06231SAxel Dörfler } 1206bc08a7d6SJohn Scipione } else if (index > 0) { 120741281cf3SAxel Dörfler // get the last replicant added for placement reference 120841281cf3SAxel Dörfler BView* view = NULL; 12097da06231SAxel Dörfler fShelf->ReplicantAt(index - 1, &view); 1210e4d65fe7SJohn Scipione if (view != NULL) { 1211a44504a1SJohn Scipione // push this replicant placement past the last one 121241281cf3SAxel Dörfler loc.x = view->Frame().right + kIconGap + 1; 121341281cf3SAxel Dörfler loc.y = view->Frame().top; 121441281cf3SAxel Dörfler } 121541281cf3SAxel Dörfler } 121641281cf3SAxel Dörfler 1217e4d65fe7SJohn Scipione if (loc.y > fRightBottomReplicant.top 1218e4d65fe7SJohn Scipione || (loc.y == fRightBottomReplicant.top 1219e4d65fe7SJohn Scipione && loc.x > fRightBottomReplicant.left)) { 1220a44504a1SJohn Scipione fRightBottomReplicant.Set(loc.x, loc.y, loc.x + replicantWidth, 1221*efafab64SAxel Dörfler loc.y + fMaxReplicantHeight); 12227da06231SAxel Dörfler fLastReplicant = index; 122341281cf3SAxel Dörfler } 12247da06231SAxel Dörfler 122541281cf3SAxel Dörfler return loc; 122641281cf3SAxel Dörfler } 122741281cf3SAxel Dörfler 122841281cf3SAxel Dörfler 122941281cf3SAxel Dörfler BRect 123041281cf3SAxel Dörfler TReplicantTray::IconFrame(int32 target, bool byIndex) 123141281cf3SAxel Dörfler { 1232378aa08bSJohn Scipione int32 index; 1233378aa08bSJohn Scipione int32 id; 123441281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 123541281cf3SAxel Dörfler 1236378aa08bSJohn Scipione return view != NULL ? view->Frame() : BRect(0, 0, 0, 0); 123741281cf3SAxel Dörfler } 123841281cf3SAxel Dörfler 123941281cf3SAxel Dörfler 124041281cf3SAxel Dörfler BRect 124141281cf3SAxel Dörfler TReplicantTray::IconFrame(const char* name) 124241281cf3SAxel Dörfler { 1243e4d65fe7SJohn Scipione if (name == NULL) 124441281cf3SAxel Dörfler return BRect(0, 0, 0, 0); 124541281cf3SAxel Dörfler 1246378aa08bSJohn Scipione int32 index; 1247378aa08bSJohn Scipione int32 id; 124841281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 124941281cf3SAxel Dörfler 1250378aa08bSJohn Scipione return view != NULL ? view->Frame() : BRect(0, 0, 0, 0); 125141281cf3SAxel Dörfler } 125241281cf3SAxel Dörfler 125341281cf3SAxel Dörfler 12547da06231SAxel Dörfler /** Scan from the startIndex and reset the location 12557da06231SAxel Dörfler * as defined in LocationForReplicant() 125641281cf3SAxel Dörfler */ 125741281cf3SAxel Dörfler 125841281cf3SAxel Dörfler void 125941281cf3SAxel Dörfler TReplicantTray::RealignReplicants(int32 startIndex) 126041281cf3SAxel Dörfler { 126141281cf3SAxel Dörfler if (startIndex < 0) 126241281cf3SAxel Dörfler startIndex = 0; 126341281cf3SAxel Dörfler 126432b0035aSJohn Scipione int32 replicantCount = ReplicantCount(); 126532b0035aSJohn Scipione if (replicantCount <= 0) 126641281cf3SAxel Dörfler return; 126741281cf3SAxel Dörfler 12687da06231SAxel Dörfler if (startIndex == 0) 12697da06231SAxel Dörfler fRightBottomReplicant.Set(0, 0, 0, 0); 12707da06231SAxel Dörfler 127141281cf3SAxel Dörfler BView* view = NULL; 1272a44504a1SJohn Scipione for (int32 index = startIndex; index < replicantCount; index++) { 1273a44504a1SJohn Scipione fShelf->ReplicantAt(index, &view); 1274a44504a1SJohn Scipione if (view == NULL) 1275a44504a1SJohn Scipione continue; 1276a44504a1SJohn Scipione 1277a44504a1SJohn Scipione float replicantWidth = view->Frame().Width(); 1278a44504a1SJohn Scipione BPoint loc = LocationForReplicant(index, replicantWidth); 12790bec7100SStefano Ceccherini if (view->Frame().LeftTop() != loc) 128041281cf3SAxel Dörfler view->MoveTo(loc); 128141281cf3SAxel Dörfler } 128241281cf3SAxel Dörfler } 128341281cf3SAxel Dörfler 128441281cf3SAxel Dörfler 12858aab28f1SRene Gollent status_t 12867625ce51SRene Gollent TReplicantTray::_SaveSettings() 12877625ce51SRene Gollent { 12887625ce51SRene Gollent status_t result; 12897625ce51SRene Gollent BPath path; 129026ea7066SIngo Weinhold if ((result = GetDeskbarSettingsDirectory(path, true)) == B_OK) { 12917625ce51SRene Gollent path.Append(kReplicantSettingsFile); 12927625ce51SRene Gollent 12937625ce51SRene Gollent BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); 12947625ce51SRene Gollent if ((result = file.InitCheck()) == B_OK) 12957625ce51SRene Gollent result = fAddOnSettings.Flatten(&file); 12967625ce51SRene Gollent } 12977625ce51SRene Gollent 12987625ce51SRene Gollent return result; 12997625ce51SRene Gollent } 13007625ce51SRene Gollent 13017625ce51SRene Gollent 13023cf2d117SJohn Scipione void 13033cf2d117SJohn Scipione TReplicantTray::SaveTimeSettings() 13043cf2d117SJohn Scipione { 13053cf2d117SJohn Scipione if (fTime == NULL) 13063cf2d117SJohn Scipione return; 13073cf2d117SJohn Scipione 130831c0024dSJohn Scipione clock_settings* settings = ((TBarApp*)be_app)->ClockSettings(); 13093cf2d117SJohn Scipione settings->showSeconds = fTime->ShowSeconds(); 13103cf2d117SJohn Scipione settings->showDayOfWeek = fTime->ShowDayOfWeek(); 131131c0024dSJohn Scipione settings->showTimeZone = fTime->ShowTimeZone(); 13123cf2d117SJohn Scipione } 13133cf2d117SJohn Scipione 13143cf2d117SJohn Scipione 13151bb2e623SJohn Scipione // #pragma mark - TDragRegion 131641281cf3SAxel Dörfler 131741281cf3SAxel Dörfler 1318ca9acc20SAxel Dörfler /*! Draggable region that is asynchronous so that dragging does not block 1319ca9acc20SAxel Dörfler other activities. 13207da06231SAxel Dörfler */ 132132b0035aSJohn Scipione TDragRegion::TDragRegion(TBarView* parent, BView* replicantTray) 1322ca9acc20SAxel Dörfler : 1323ca9acc20SAxel Dörfler BControl(BRect(0, 0, 0, 0), "", "", NULL, B_FOLLOW_NONE, 132441281cf3SAxel Dörfler B_WILL_DRAW | B_FRAME_EVENTS), 132541281cf3SAxel Dörfler fBarView(parent), 132632b0035aSJohn Scipione fReplicantTray(replicantTray), 132741281cf3SAxel Dörfler fDragLocation(kAutoPlaceDragRegion) 132841281cf3SAxel Dörfler { 132941281cf3SAxel Dörfler } 133041281cf3SAxel Dörfler 133141281cf3SAxel Dörfler 133241281cf3SAxel Dörfler void 133341281cf3SAxel Dörfler TDragRegion::AttachedToWindow() 133441281cf3SAxel Dörfler { 133541281cf3SAxel Dörfler BView::AttachedToWindow(); 1336e4d65fe7SJohn Scipione 1337cb6afcb1SStephan Aßmus if (be_control_look != NULL) 13381bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR, 1.1); 1339cb6afcb1SStephan Aßmus else 134016c10517Slooncraz SetViewUIColor(B_MENU_BACKGROUND_COLOR); 1341e4d65fe7SJohn Scipione 134241281cf3SAxel Dörfler ResizeToPreferred(); 134341281cf3SAxel Dörfler } 134441281cf3SAxel Dörfler 134541281cf3SAxel Dörfler 134641281cf3SAxel Dörfler void 134741281cf3SAxel Dörfler TDragRegion::GetPreferredSize(float* width, float* height) 134841281cf3SAxel Dörfler { 134932b0035aSJohn Scipione fReplicantTray->ResizeToPreferred(); 135032b0035aSJohn Scipione *width = fReplicantTray->Bounds().Width(); 135132b0035aSJohn Scipione *height = fReplicantTray->Bounds().Height(); 135241281cf3SAxel Dörfler 135341281cf3SAxel Dörfler if (fDragLocation != kNoDragRegion) 13541bb2e623SJohn Scipione *width += kDragWidth + kGutter; 135541281cf3SAxel Dörfler else 135641281cf3SAxel Dörfler *width += 6; 135741281cf3SAxel Dörfler 13581bb2e623SJohn Scipione *height += 2; 135941281cf3SAxel Dörfler } 136041281cf3SAxel Dörfler 136141281cf3SAxel Dörfler 136241281cf3SAxel Dörfler void 136370ad5289SJohn Scipione TDragRegion::Draw(BRect updateRect) 136441281cf3SAxel Dörfler { 1365eaa9af99SStephan Aßmus rgb_color menuColor = ViewColor(); 136641281cf3SAxel Dörfler rgb_color hilite = tint_color(menuColor, B_DARKEN_1_TINT); 1367cb6afcb1SStephan Aßmus rgb_color ldark = tint_color(menuColor, 1.02); 1368cb6afcb1SStephan Aßmus rgb_color dark = tint_color(menuColor, B_DARKEN_2_TINT); 136941281cf3SAxel Dörfler rgb_color vvdark = tint_color(menuColor, B_DARKEN_4_TINT); 137041281cf3SAxel Dörfler rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT); 137141281cf3SAxel Dörfler 137241281cf3SAxel Dörfler BRect frame(Bounds()); 137341281cf3SAxel Dörfler BeginLineArray(4); 137441281cf3SAxel Dörfler 1375cb6afcb1SStephan Aßmus if (be_control_look != NULL) { 1376cb6afcb1SStephan Aßmus if (fBarView->Vertical()) { 1377cb6afcb1SStephan Aßmus AddLine(frame.LeftTop(), frame.RightTop(), dark); 1378cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left, frame.top + 1), 1379cb6afcb1SStephan Aßmus BPoint(frame.right, frame.top + 1), ldark); 1380cb6afcb1SStephan Aßmus AddLine(frame.LeftBottom(), frame.RightBottom(), hilite); 1381cb6afcb1SStephan Aßmus } else if (fBarView->AcrossTop() || fBarView->AcrossBottom()) { 1382cb6afcb1SStephan Aßmus AddLine(frame.LeftTop(), 1383cb6afcb1SStephan Aßmus BPoint(frame.left, frame.bottom), dark); 1384cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left + 1, frame.top + 1), 1385cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.top + 1), light); 1386cb6afcb1SStephan Aßmus AddLine(BPoint(frame.right, frame.top + 2), 1387cb6afcb1SStephan Aßmus BPoint(frame.right, frame.bottom), hilite); 1388cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left + 1, frame.bottom), 1389cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.bottom), hilite); 1390cb6afcb1SStephan Aßmus } 1391cb6afcb1SStephan Aßmus } else { 139241281cf3SAxel Dörfler if (fBarView->Vertical()) { 139341281cf3SAxel Dörfler AddLine(frame.LeftTop(), frame.RightTop(), light); 139441281cf3SAxel Dörfler AddLine(frame.LeftTop(), frame.LeftBottom(), light); 139541281cf3SAxel Dörfler AddLine(frame.RightBottom(), frame.RightTop(), hilite); 139641281cf3SAxel Dörfler } else if (fBarView->AcrossTop()) { 1397cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left, frame.top + 1), 1398cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.top + 1), light); 139941281cf3SAxel Dörfler AddLine(frame.RightTop(), frame.RightBottom(), vvdark); 1400cb6afcb1SStephan Aßmus AddLine(BPoint(frame.right - 1, frame.top + 2), 1401cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.bottom - 1), hilite); 1402cb6afcb1SStephan Aßmus AddLine(frame.LeftBottom(), 1403cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.bottom), hilite); 140441281cf3SAxel Dörfler } else if (fBarView->AcrossBottom()) { 1405cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left, frame.top + 1), 1406cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.top + 1), light); 140741281cf3SAxel Dörfler AddLine(frame.LeftBottom(), frame.RightBottom(), hilite); 140841281cf3SAxel Dörfler AddLine(frame.RightTop(), frame.RightBottom(), vvdark); 1409cb6afcb1SStephan Aßmus AddLine(BPoint(frame.right - 1, frame.top + 1), 1410cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.bottom - 1), hilite); 1411cb6afcb1SStephan Aßmus } 141241281cf3SAxel Dörfler } 141341281cf3SAxel Dörfler 141441281cf3SAxel Dörfler EndLineArray(); 141541281cf3SAxel Dörfler 141641281cf3SAxel Dörfler if (fDragLocation != kDontDrawDragRegion || fDragLocation != kNoDragRegion) 141741281cf3SAxel Dörfler DrawDragRegion(); 141841281cf3SAxel Dörfler } 141941281cf3SAxel Dörfler 142041281cf3SAxel Dörfler 142141281cf3SAxel Dörfler void 142241281cf3SAxel Dörfler TDragRegion::DrawDragRegion() 142341281cf3SAxel Dörfler { 142441281cf3SAxel Dörfler BRect dragRegion(DragRegion()); 142541281cf3SAxel Dörfler 1426cb6afcb1SStephan Aßmus rgb_color menuColor = ViewColor(); 1427cb6afcb1SStephan Aßmus rgb_color menuHilite = menuColor; 142841281cf3SAxel Dörfler if (IsTracking()) { 14291bb2e623SJohn Scipione // draw drag region highlighted if tracking mouse 1430cb6afcb1SStephan Aßmus menuHilite = tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT); 143141281cf3SAxel Dörfler SetHighColor(menuHilite); 143241281cf3SAxel Dörfler FillRect(dragRegion); 14331bb2e623SJohn Scipione } else { 14341bb2e623SJohn Scipione SetHighColor(menuColor); 14351bb2e623SJohn Scipione FillRect(dragRegion); 143641281cf3SAxel Dörfler } 14371bb2e623SJohn Scipione 1438cb6afcb1SStephan Aßmus rgb_color vdark = tint_color(menuHilite, B_DARKEN_3_TINT); 1439cb6afcb1SStephan Aßmus rgb_color light = tint_color(menuHilite, B_LIGHTEN_2_TINT); 1440cb6afcb1SStephan Aßmus 1441cb6afcb1SStephan Aßmus BeginLineArray(dragRegion.IntegerHeight()); 1442e4d65fe7SJohn Scipione BPoint where; 1443e4d65fe7SJohn Scipione where.x = floorf((dragRegion.left + dragRegion.right) / 2 + 0.5) - 1; 1444e4d65fe7SJohn Scipione where.y = dragRegion.top + 2; 1445cb6afcb1SStephan Aßmus 1446e4d65fe7SJohn Scipione while (where.y + 1 <= dragRegion.bottom) { 1447e4d65fe7SJohn Scipione AddLine(where, where, vdark); 1448e4d65fe7SJohn Scipione AddLine(where + BPoint(1, 1), where + BPoint(1, 1), light); 144941281cf3SAxel Dörfler 1450e4d65fe7SJohn Scipione where.y += 3; 145141281cf3SAxel Dörfler } 145241281cf3SAxel Dörfler EndLineArray(); 145341281cf3SAxel Dörfler } 145441281cf3SAxel Dörfler 145541281cf3SAxel Dörfler 145641281cf3SAxel Dörfler BRect 145741281cf3SAxel Dörfler TDragRegion::DragRegion() const 145841281cf3SAxel Dörfler { 1459cb6afcb1SStephan Aßmus float kTopBottomInset = 2; 1460cb6afcb1SStephan Aßmus float kLeftRightInset = 1; 1461cb6afcb1SStephan Aßmus if (be_control_look != NULL) { 1462cb6afcb1SStephan Aßmus kTopBottomInset = 1; 1463cb6afcb1SStephan Aßmus kLeftRightInset = 0; 1464cb6afcb1SStephan Aßmus } 1465cb6afcb1SStephan Aßmus 146641281cf3SAxel Dörfler BRect dragRegion(Bounds()); 1467cb6afcb1SStephan Aßmus dragRegion.top += kTopBottomInset; 1468cb6afcb1SStephan Aßmus dragRegion.bottom -= kTopBottomInset; 146941281cf3SAxel Dörfler 147041281cf3SAxel Dörfler bool placeOnLeft = false; 147141281cf3SAxel Dörfler if (fDragLocation == kAutoPlaceDragRegion) { 147241281cf3SAxel Dörfler if (fBarView->Vertical() && fBarView->Left()) 147341281cf3SAxel Dörfler placeOnLeft = true; 147441281cf3SAxel Dörfler else 147541281cf3SAxel Dörfler placeOnLeft = false; 14761bb2e623SJohn Scipione } else 14771bb2e623SJohn Scipione placeOnLeft = fDragLocation == kDragRegionLeft; 147841281cf3SAxel Dörfler 147941281cf3SAxel Dörfler if (placeOnLeft) { 1480cb6afcb1SStephan Aßmus dragRegion.left += kLeftRightInset; 1481cb6afcb1SStephan Aßmus dragRegion.right = dragRegion.left + kDragWidth; 148241281cf3SAxel Dörfler } else { 14831bb2e623SJohn Scipione dragRegion.right += kLeftRightInset; 1484cb6afcb1SStephan Aßmus dragRegion.left = dragRegion.right - kDragWidth; 148541281cf3SAxel Dörfler } 148641281cf3SAxel Dörfler 148741281cf3SAxel Dörfler return dragRegion; 148841281cf3SAxel Dörfler } 148941281cf3SAxel Dörfler 149041281cf3SAxel Dörfler 149141281cf3SAxel Dörfler void 1492e4d65fe7SJohn Scipione TDragRegion::MouseDown(BPoint where) 149341281cf3SAxel Dörfler { 1494e9632898SAlex Smith uint32 buttons; 1495e4d65fe7SJohn Scipione BPoint mouseLoc; 149641281cf3SAxel Dörfler 1497e4d65fe7SJohn Scipione BRect dragRegion(DragRegion()); 14981bb2e623SJohn Scipione dragRegion.InsetBy(-2, -2); 14997da06231SAxel Dörfler // DragRegion() is designed for drawing, not clicking 150041281cf3SAxel Dörfler 1501e4d65fe7SJohn Scipione if (!dragRegion.Contains(where)) 150241281cf3SAxel Dörfler return; 150341281cf3SAxel Dörfler 150441281cf3SAxel Dörfler while (true) { 1505e4d65fe7SJohn Scipione GetMouse(&mouseLoc, &buttons); 1506e4d65fe7SJohn Scipione if (buttons == 0) 150741281cf3SAxel Dörfler break; 150841281cf3SAxel Dörfler 150941281cf3SAxel Dörfler if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) != 0) { 1510e4d65fe7SJohn Scipione fPreviousPosition = where; 151141281cf3SAxel Dörfler SetTracking(true); 151241281cf3SAxel Dörfler SetMouseEventMask(B_POINTER_EVENTS, 151341281cf3SAxel Dörfler B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); 151441281cf3SAxel Dörfler Invalidate(DragRegion()); 151541281cf3SAxel Dörfler break; 151641281cf3SAxel Dörfler } 151741281cf3SAxel Dörfler 151841281cf3SAxel Dörfler snooze(25000); 151941281cf3SAxel Dörfler } 152041281cf3SAxel Dörfler } 152141281cf3SAxel Dörfler 152241281cf3SAxel Dörfler 152341281cf3SAxel Dörfler void 1524e4d65fe7SJohn Scipione TDragRegion::MouseUp(BPoint where) 152541281cf3SAxel Dörfler { 152641281cf3SAxel Dörfler if (IsTracking()) { 152741281cf3SAxel Dörfler SetTracking(false); 152841281cf3SAxel Dörfler Invalidate(DragRegion()); 152941281cf3SAxel Dörfler } else 1530e4d65fe7SJohn Scipione BControl::MouseUp(where); 153141281cf3SAxel Dörfler } 153241281cf3SAxel Dörfler 153341281cf3SAxel Dörfler 153441281cf3SAxel Dörfler bool 1535e4d65fe7SJohn Scipione TDragRegion::SwitchModeForRect(BPoint where, BRect rect, 153641281cf3SAxel Dörfler bool newVertical, bool newLeft, bool newTop, int32 newState) 153741281cf3SAxel Dörfler { 1538e4d65fe7SJohn Scipione if (!rect.Contains(where)) { 153941281cf3SAxel Dörfler // not our rect 154041281cf3SAxel Dörfler return false; 15411ad8c760SFredrik Holmqvist } 154241281cf3SAxel Dörfler 15431ad8c760SFredrik Holmqvist if (newVertical == fBarView->Vertical() && newLeft == fBarView->Left() 15441ad8c760SFredrik Holmqvist && newTop == fBarView->Top() && newState == fBarView->State()) { 154541281cf3SAxel Dörfler // already in the correct mode 154641281cf3SAxel Dörfler return true; 15471ad8c760SFredrik Holmqvist } 154841281cf3SAxel Dörfler 1549d7ed9414SRene Gollent fBarView->ChangeState(newState, newVertical, newLeft, newTop, true); 1550e4d65fe7SJohn Scipione 155141281cf3SAxel Dörfler return true; 155241281cf3SAxel Dörfler } 155341281cf3SAxel Dörfler 155441281cf3SAxel Dörfler 155541281cf3SAxel Dörfler void 155641281cf3SAxel Dörfler TDragRegion::MouseMoved(BPoint where, uint32 code, const BMessage* message) 155741281cf3SAxel Dörfler { 155841281cf3SAxel Dörfler if (IsTracking()) { 155941281cf3SAxel Dörfler BScreen screen; 156041281cf3SAxel Dörfler BRect frame = screen.Frame(); 156141281cf3SAxel Dörfler 156241281cf3SAxel Dörfler float hDivider = frame.Width() / 6; 15631bb2e623SJohn Scipione hDivider = (hDivider < gMinimumWindowWidth + 10) 15641bb2e623SJohn Scipione ? gMinimumWindowWidth + 10 : hDivider; 15651bb2e623SJohn Scipione float miniDivider = frame.top + kMiniHeight + 10; 156641281cf3SAxel Dörfler float vDivider = frame.Height() / 2; 156741281cf3SAxel Dörfler #ifdef FULL_MODE 156841281cf3SAxel Dörfler float thirdScreen = frame.Height() / 3; 156941281cf3SAxel Dörfler #endif 157071bd3ba5SJonas Sundström BRect topLeft(frame.left, frame.top, frame.left + hDivider, 157171bd3ba5SJonas Sundström miniDivider); 157271bd3ba5SJonas Sundström BRect topMiddle(frame.left + hDivider, frame.top, frame.right 157371bd3ba5SJonas Sundström - hDivider, vDivider); 157471bd3ba5SJonas Sundström BRect topRight(frame.right - hDivider, frame.top, frame.right, 157571bd3ba5SJonas Sundström miniDivider); 157641281cf3SAxel Dörfler 157741281cf3SAxel Dörfler #ifdef FULL_MODE 157841281cf3SAxel Dörfler vDivider = miniDivider + thirdScreen; 157941281cf3SAxel Dörfler #endif 158071bd3ba5SJonas Sundström BRect middleLeft(frame.left, miniDivider, frame.left + hDivider, 158171bd3ba5SJonas Sundström vDivider); 158271bd3ba5SJonas Sundström BRect middleRight(frame.right - hDivider, miniDivider, frame.right, 158371bd3ba5SJonas Sundström vDivider); 158441281cf3SAxel Dörfler 158541281cf3SAxel Dörfler #ifdef FULL_MODE 158671bd3ba5SJonas Sundström BRect leftSide(frame.left, vDivider, frame.left + hDivider, 158771bd3ba5SJonas Sundström frame.bottom - thirdScreen); 158871bd3ba5SJonas Sundström BRect rightSide(frame.right - hDivider, vDivider, frame.right, 158971bd3ba5SJonas Sundström frame.bottom - thirdScreen); 159041281cf3SAxel Dörfler 159141281cf3SAxel Dörfler vDivider = frame.bottom - thirdScreen; 159241281cf3SAxel Dörfler #endif 159371bd3ba5SJonas Sundström BRect bottomLeft(frame.left, vDivider, frame.left + hDivider, 159471bd3ba5SJonas Sundström frame.bottom); 159571bd3ba5SJonas Sundström BRect bottomMiddle(frame.left + hDivider, vDivider, frame.right 159671bd3ba5SJonas Sundström - hDivider, frame.bottom); 159771bd3ba5SJonas Sundström BRect bottomRight(frame.right - hDivider, vDivider, frame.right, 159871bd3ba5SJonas Sundström frame.bottom); 159941281cf3SAxel Dörfler 160041281cf3SAxel Dörfler if (where != fPreviousPosition) { 160141281cf3SAxel Dörfler fPreviousPosition = where; 160241281cf3SAxel Dörfler ConvertToScreen(&where); 160341281cf3SAxel Dörfler 160441281cf3SAxel Dörfler // use short circuit evaluation for convenience 160541281cf3SAxel Dörfler if (SwitchModeForRect(where, topLeft, true, true, true, kMiniState) 160671bd3ba5SJonas Sundström || SwitchModeForRect(where, topMiddle, false, true, true, 160771bd3ba5SJonas Sundström kExpandoState) 160871bd3ba5SJonas Sundström || SwitchModeForRect(where, topRight, true, false, true, 160971bd3ba5SJonas Sundström kMiniState) 161071bd3ba5SJonas Sundström || SwitchModeForRect(where, middleLeft, true, true, true, 161171bd3ba5SJonas Sundström kExpandoState) 161271bd3ba5SJonas Sundström || SwitchModeForRect(where, middleRight, true, false, true, 161371bd3ba5SJonas Sundström kExpandoState) 161441281cf3SAxel Dörfler 161541281cf3SAxel Dörfler #ifdef FULL_MODE 161671bd3ba5SJonas Sundström || SwitchModeForRect(where, leftSide, true, true, true, 161771bd3ba5SJonas Sundström kFullState) 161871bd3ba5SJonas Sundström || SwitchModeForRect(where, rightSide, true, false, true, 161971bd3ba5SJonas Sundström kFullState) 162041281cf3SAxel Dörfler #endif 162171bd3ba5SJonas Sundström || SwitchModeForRect(where, bottomLeft, true, true, false, 162271bd3ba5SJonas Sundström kMiniState) 162371bd3ba5SJonas Sundström || SwitchModeForRect(where, bottomMiddle, false, true, false, 162471bd3ba5SJonas Sundström kExpandoState) 162571bd3ba5SJonas Sundström || SwitchModeForRect(where, bottomRight, true, false, false, 162671bd3ba5SJonas Sundström kMiniState)) 162741281cf3SAxel Dörfler ; 162841281cf3SAxel Dörfler } 162941281cf3SAxel Dörfler } else 163041281cf3SAxel Dörfler BControl::MouseMoved(where, code, message); 163141281cf3SAxel Dörfler } 163241281cf3SAxel Dörfler 163341281cf3SAxel Dörfler 163441281cf3SAxel Dörfler int32 163541281cf3SAxel Dörfler TDragRegion::DragRegionLocation() const 163641281cf3SAxel Dörfler { 163741281cf3SAxel Dörfler return fDragLocation; 163841281cf3SAxel Dörfler } 163941281cf3SAxel Dörfler 164041281cf3SAxel Dörfler 164141281cf3SAxel Dörfler void 164241281cf3SAxel Dörfler TDragRegion::SetDragRegionLocation(int32 location) 164341281cf3SAxel Dörfler { 164441281cf3SAxel Dörfler if (location == fDragLocation) 164541281cf3SAxel Dörfler return; 164641281cf3SAxel Dörfler 164741281cf3SAxel Dörfler fDragLocation = location; 164841281cf3SAxel Dörfler Invalidate(); 164941281cf3SAxel Dörfler } 16501bb2e623SJohn Scipione 16511bb2e623SJohn Scipione 16521bb2e623SJohn Scipione // #pragma mark - TResizeControl 16531bb2e623SJohn Scipione 16541bb2e623SJohn Scipione 16551bb2e623SJohn Scipione /*! Draggable region that is asynchronous so that resizing does not block. 16561bb2e623SJohn Scipione */ 16571bb2e623SJohn Scipione TResizeControl::TResizeControl(TBarView* barView) 16581bb2e623SJohn Scipione : 16591bb2e623SJohn Scipione BControl(BRect(0, kDragWidth, 0, kMenuBarHeight), "", "", NULL, 16601bb2e623SJohn Scipione B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS), 16611bb2e623SJohn Scipione fBarView(barView) 16621bb2e623SJohn Scipione { 16631bb2e623SJohn Scipione } 16641bb2e623SJohn Scipione 16651bb2e623SJohn Scipione 16661bb2e623SJohn Scipione TResizeControl::~TResizeControl() 16671bb2e623SJohn Scipione { 16681bb2e623SJohn Scipione } 16691bb2e623SJohn Scipione 16701bb2e623SJohn Scipione 16711bb2e623SJohn Scipione void 16721bb2e623SJohn Scipione TResizeControl::AttachedToWindow() 16731bb2e623SJohn Scipione { 16741bb2e623SJohn Scipione BView::AttachedToWindow(); 16751bb2e623SJohn Scipione 16761bb2e623SJohn Scipione if (be_control_look != NULL) 16771bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR, 1.1); 16781bb2e623SJohn Scipione else 16791bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR); 16801bb2e623SJohn Scipione } 16811bb2e623SJohn Scipione 16821bb2e623SJohn Scipione 16831bb2e623SJohn Scipione void 16841bb2e623SJohn Scipione TResizeControl::Draw(BRect updateRect) 16851bb2e623SJohn Scipione { 16861bb2e623SJohn Scipione if (!fBarView->Vertical()) 16871bb2e623SJohn Scipione return; 16881bb2e623SJohn Scipione 1689092e918bSJohn Scipione BRect dragRegion(Bounds()); 16901bb2e623SJohn Scipione 169100171c6fSJohn Scipione int32 height = dragRegion.IntegerHeight(); 169200171c6fSJohn Scipione if (height <= 0) 169300171c6fSJohn Scipione return; 169400171c6fSJohn Scipione 16951bb2e623SJohn Scipione rgb_color menuColor = ViewColor(); 16961bb2e623SJohn Scipione rgb_color menuHilite = menuColor; 16971bb2e623SJohn Scipione if (IsTracking()) { 16981bb2e623SJohn Scipione // draw drag region highlighted if tracking mouse 16991bb2e623SJohn Scipione menuHilite = tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT); 17001bb2e623SJohn Scipione SetHighColor(menuHilite); 17011bb2e623SJohn Scipione FillRect(dragRegion); 17021bb2e623SJohn Scipione } else { 17031bb2e623SJohn Scipione SetHighColor(menuColor); 17041bb2e623SJohn Scipione FillRect(dragRegion); 17051bb2e623SJohn Scipione } 17061bb2e623SJohn Scipione 17071bb2e623SJohn Scipione rgb_color vdark = tint_color(menuHilite, B_DARKEN_3_TINT); 17081bb2e623SJohn Scipione rgb_color light = tint_color(menuHilite, B_LIGHTEN_2_TINT); 17091bb2e623SJohn Scipione 171000171c6fSJohn Scipione BeginLineArray(height); 17111bb2e623SJohn Scipione BPoint where; 17121bb2e623SJohn Scipione where.x = floorf((dragRegion.left + dragRegion.right) / 2 + 0.5) - 1; 17131bb2e623SJohn Scipione where.y = dragRegion.top + 2; 17141bb2e623SJohn Scipione 17151bb2e623SJohn Scipione while (where.y + 1 <= dragRegion.bottom) { 17161bb2e623SJohn Scipione AddLine(where, where, vdark); 17171bb2e623SJohn Scipione AddLine(where + BPoint(1, 1), where + BPoint(1, 1), light); 17181bb2e623SJohn Scipione 17191bb2e623SJohn Scipione where.y += 3; 17201bb2e623SJohn Scipione } 17211bb2e623SJohn Scipione EndLineArray(); 17221bb2e623SJohn Scipione } 17231bb2e623SJohn Scipione 17241bb2e623SJohn Scipione 17251bb2e623SJohn Scipione void 17261bb2e623SJohn Scipione TResizeControl::MouseDown(BPoint where) 17271bb2e623SJohn Scipione { 17281bb2e623SJohn Scipione uint32 buttons; 17291bb2e623SJohn Scipione BPoint mouseLoc; 17301bb2e623SJohn Scipione 17311bb2e623SJohn Scipione while (true) { 17321bb2e623SJohn Scipione GetMouse(&mouseLoc, &buttons); 17331bb2e623SJohn Scipione if (buttons == 0) 17341bb2e623SJohn Scipione break; 17351bb2e623SJohn Scipione 17361bb2e623SJohn Scipione if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) != 0) { 17371bb2e623SJohn Scipione SetTracking(true); 17381bb2e623SJohn Scipione SetMouseEventMask(B_POINTER_EVENTS, 17391bb2e623SJohn Scipione B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); 17401bb2e623SJohn Scipione Invalidate(); 17411bb2e623SJohn Scipione break; 17421bb2e623SJohn Scipione } 17431bb2e623SJohn Scipione 17441bb2e623SJohn Scipione snooze(25000); 17451bb2e623SJohn Scipione } 17461bb2e623SJohn Scipione } 17471bb2e623SJohn Scipione 17481bb2e623SJohn Scipione 17491bb2e623SJohn Scipione void 17501bb2e623SJohn Scipione TResizeControl::MouseUp(BPoint where) 17511bb2e623SJohn Scipione { 17521bb2e623SJohn Scipione if (IsTracking()) { 17531bb2e623SJohn Scipione SetTracking(false); 17541bb2e623SJohn Scipione Invalidate(); 17551bb2e623SJohn Scipione } else 17561bb2e623SJohn Scipione BControl::MouseUp(where); 17571bb2e623SJohn Scipione } 17581bb2e623SJohn Scipione 17591bb2e623SJohn Scipione 17601bb2e623SJohn Scipione void 17611bb2e623SJohn Scipione TResizeControl::MouseMoved(BPoint where, uint32 code, 17621bb2e623SJohn Scipione const BMessage* dragMessage) 17631bb2e623SJohn Scipione { 17641bb2e623SJohn Scipione if (fBarView->Vertical()) { 17651bb2e623SJohn Scipione if (IsResizing()) { 17661bb2e623SJohn Scipione float windowWidth = Window()->Frame().Width(); 17671bb2e623SJohn Scipione float delta = 0; 17681bb2e623SJohn Scipione BPoint whereScreen = ConvertToScreen(where); 17691bb2e623SJohn Scipione 17701bb2e623SJohn Scipione if (fBarView->Left()) { 17711bb2e623SJohn Scipione delta = whereScreen.x - Window()->Frame().right; 17721bb2e623SJohn Scipione if (delta > 0 && windowWidth >= gMaximumWindowWidth) 17731bb2e623SJohn Scipione ; // do nothing 17741bb2e623SJohn Scipione else if (delta < 0 && windowWidth <= gMinimumWindowWidth) 17751bb2e623SJohn Scipione ; // do nothing 17761bb2e623SJohn Scipione else 17771bb2e623SJohn Scipione Window()->ResizeBy(delta, 0); 17781bb2e623SJohn Scipione } else { 17791bb2e623SJohn Scipione delta = Window()->Frame().left - whereScreen.x; 17801bb2e623SJohn Scipione if (delta > 0 && windowWidth >= gMaximumWindowWidth) 17811bb2e623SJohn Scipione ; // do nothing 17821bb2e623SJohn Scipione else if (delta < 0 && windowWidth <= gMinimumWindowWidth) 17831bb2e623SJohn Scipione ; // do nothing 17841bb2e623SJohn Scipione else { 17851bb2e623SJohn Scipione Window()->MoveBy(delta, 0); 17861bb2e623SJohn Scipione Window()->ResizeBy(delta, 0); 17871bb2e623SJohn Scipione } 17881bb2e623SJohn Scipione } 17891bb2e623SJohn Scipione 17901bb2e623SJohn Scipione windowWidth = Window()->Frame().Width(); 17911bb2e623SJohn Scipione } 17921bb2e623SJohn Scipione } 17931bb2e623SJohn Scipione 17941bb2e623SJohn Scipione BControl::MouseMoved(where, code, dragMessage); 17951bb2e623SJohn Scipione } 1796