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" 720d2645e4SJohn Scipione #include "BarMenuBar.h" 73323b6546SOliver Tappe #include "DeskbarUtils.h" 7415eb397eSJohn Scipione #include "ExpandoMenuBar.h" 75cb6afcb1SStephan Aßmus #include "ResourceSet.h" 7641281cf3SAxel Dörfler #include "StatusViewShelf.h" 7741281cf3SAxel Dörfler #include "TimeView.h" 7841281cf3SAxel Dörfler 79615d572dSJohn Scipione 80f9b3a3b1SJohn Scipione static const float kVerticalMiniMultiplier = 2.9f; 81f9b3a3b1SJohn Scipione 82*fac73debSAugustin Cavalier float sIconGap = 0.0f; 839f4bb0f5SAugustin Cavalier float gDragWidth, gDragRegionWidth = 0.0f; 849f4bb0f5SAugustin Cavalier float gMinReplicantHeight, gMinReplicantWidth = 0.0f; 859f4bb0f5SAugustin Cavalier float gMinimumTrayWidth, gMinimumWindowWidth, gMaximumWindowWidth = 0.0f; 869f4bb0f5SAugustin Cavalier 87f9b3a3b1SJohn Scipione 8841281cf3SAxel Dörfler #ifdef DB_ADDONS 8941281cf3SAxel Dörfler // Add-on support 9041281cf3SAxel Dörfler // 9141281cf3SAxel Dörfler // Item - internal item list (node, eref, etc) 9241281cf3SAxel Dörfler // Icon - physical replicant handed to the DeskbarClass class 9341281cf3SAxel Dörfler // AddOn - attribute based add-on 9441281cf3SAxel Dörfler 9541281cf3SAxel Dörfler const char* const kInstantiateItemCFunctionName = "instantiate_deskbar_item"; 9641281cf3SAxel Dörfler const char* const kInstantiateEntryCFunctionName = "instantiate_deskbar_entry"; 9726ea7066SIngo Weinhold const char* const kReplicantSettingsFile = "replicants"; 98c0ad1c91SRene Gollent const char* const kReplicantPathField = "replicant_path"; 9941281cf3SAxel Dörfler 100c3c3360fSJohn Scipione 10141281cf3SAxel Dörfler static void 10241281cf3SAxel Dörfler DumpItem(DeskbarItemInfo* item) 10341281cf3SAxel Dörfler { 104e9632898SAlex Smith printf("is addon: %i, id: %" B_PRId32 "\n", item->isAddOn, item->id); 105e9632898SAlex Smith printf("entry_ref: %" B_PRIdDEV ", %" B_PRIdINO ", %s\n", 106e9632898SAlex Smith item->entryRef.device, item->entryRef.directory, item->entryRef.name); 107e9632898SAlex Smith printf("node_ref: %" B_PRIdDEV ", %" B_PRIdINO "\n", item->nodeRef.device, 108e9632898SAlex Smith item->nodeRef.node); 10941281cf3SAxel Dörfler } 11041281cf3SAxel Dörfler 11141281cf3SAxel Dörfler 11241281cf3SAxel Dörfler static void 11341281cf3SAxel Dörfler DumpList(BList* itemlist) 11441281cf3SAxel Dörfler { 11541281cf3SAxel Dörfler int32 count = itemlist->CountItems() - 1; 11641281cf3SAxel Dörfler if (count < 0) { 11741281cf3SAxel Dörfler printf("no items in list\n"); 11841281cf3SAxel Dörfler return; 11941281cf3SAxel Dörfler } 12041281cf3SAxel Dörfler for (int32 i = count; i >= 0; i--) { 12141281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)itemlist->ItemAt(i); 12241281cf3SAxel Dörfler if (!item) 12341281cf3SAxel Dörfler continue; 12441281cf3SAxel Dörfler 12541281cf3SAxel Dörfler DumpItem(item); 12641281cf3SAxel Dörfler } 12741281cf3SAxel Dörfler } 12841281cf3SAxel Dörfler #endif /* DB_ADDONS */ 12941281cf3SAxel Dörfler 13041281cf3SAxel Dörfler 131546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 132546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Tray" 133ae7a6e3aSAdrien Destugues 1347da06231SAxel Dörfler // don't change the name of this view to anything other than "Status"! 1357da06231SAxel Dörfler 1360d2645e4SJohn Scipione TReplicantTray::TReplicantTray(TBarView* barView) 1370d2ac94cSJohn Scipione : 1389ac6fee1SJohn Scipione BView(BRect(0, 0, 1, 1), "Status", B_FOLLOW_LEFT | B_FOLLOW_TOP, 1390d2ac94cSJohn Scipione B_WILL_DRAW | B_FRAME_EVENTS), 140573f748cSJohn Scipione fTime(NULL), 1410d2645e4SJohn Scipione fBarView(barView), 14241281cf3SAxel Dörfler fShelf(new TReplicantShelf(this)), 14341281cf3SAxel Dörfler fAlignmentSupport(false) 14441281cf3SAxel Dörfler { 1450d2645e4SJohn Scipione // scale replicants by font size 1469f4bb0f5SAugustin Cavalier fMaxReplicantHeight = std::max(gMinReplicantHeight, 1471e0308a8SAugustin Cavalier float(((TBarApp*)be_app)->IconSize())); 1480d2645e4SJohn Scipione // but not bigger than TabHeight which depends on be_bold_font 1490d2645e4SJohn Scipione // TODO this should only apply to mini-mode but we set it once here for all 1500d2645e4SJohn Scipione fMaxReplicantHeight = std::min(fMaxReplicantHeight, 1510d2645e4SJohn Scipione fBarView->TabHeight() - 4); 152efafab64SAxel Dörfler // TODO: depends on window size... (so use something like 153efafab64SAxel Dörfler // max(129, height * 3), and restrict the minimum window width for it) 1540d2645e4SJohn Scipione // Use bold font because it depends on the window tab height. 155efafab64SAxel Dörfler fMaxReplicantWidth = 129; 156efafab64SAxel Dörfler 157efafab64SAxel Dörfler fMinTrayHeight = kGutter + fMaxReplicantHeight + kGutter; 1580d2645e4SJohn Scipione if (fBarView != NULL && fBarView->Vertical() 1590d2645e4SJohn Scipione && (fBarView->ExpandoState() || fBarView->FullState())) { 1609f4bb0f5SAugustin Cavalier fMinimumTrayWidth = gMinimumWindowWidth - kGutter - gDragRegionWidth; 1610d2645e4SJohn Scipione } else 1629f4bb0f5SAugustin Cavalier fMinimumTrayWidth = gMinimumTrayWidth; 163573f748cSJohn Scipione 164573f748cSJohn Scipione // Create the time view 1650d2645e4SJohn Scipione fTime = new TTimeView(fMinimumTrayWidth, fMaxReplicantHeight - 1.0, 1660d2645e4SJohn Scipione fBarView); 16741281cf3SAxel Dörfler } 16841281cf3SAxel Dörfler 16941281cf3SAxel Dörfler 17041281cf3SAxel Dörfler TReplicantTray::~TReplicantTray() 17141281cf3SAxel Dörfler { 17241281cf3SAxel Dörfler delete fShelf; 173573f748cSJohn Scipione delete fTime; 17441281cf3SAxel Dörfler } 17541281cf3SAxel Dörfler 17641281cf3SAxel Dörfler 17741281cf3SAxel Dörfler void 17841281cf3SAxel Dörfler TReplicantTray::AttachedToWindow() 17941281cf3SAxel Dörfler { 18041281cf3SAxel Dörfler BView::AttachedToWindow(); 18141281cf3SAxel Dörfler 182cb6afcb1SStephan Aßmus if (be_control_look != NULL) { 183cef0a7b2Slooncraz AdoptParentColors(); 184cb6afcb1SStephan Aßmus } else { 18516c10517Slooncraz SetViewUIColor(B_MENU_BACKGROUND_COLOR, B_DARKEN_1_TINT); 186cb6afcb1SStephan Aßmus } 18741281cf3SAxel Dörfler SetDrawingMode(B_OP_COPY); 18866eba86fSAxel Dörfler 18941281cf3SAxel Dörfler Window()->SetPulseRate(1000000); 19041281cf3SAxel Dörfler 1913722e640SJohn Scipione clock_settings* clock = ((TBarApp*)be_app)->ClockSettings(); 1923722e640SJohn Scipione fTime->SetShowSeconds(clock->showSeconds); 1933722e640SJohn Scipione fTime->SetShowDayOfWeek(clock->showDayOfWeek); 1943722e640SJohn Scipione fTime->SetShowTimeZone(clock->showTimeZone); 19531c0024dSJohn Scipione 196573f748cSJohn Scipione AddChild(fTime); 1971bb2e623SJohn Scipione 1981be85605SAugustin Cavalier const float trayPadding = ceilf(be_control_look->ComposeSpacing(kTrayPadding) / 2); 1991e0308a8SAugustin Cavalier fTime->MoveTo(Bounds().right - fTime->Bounds().Width() - trayPadding, 2); 2000d2645e4SJohn Scipione // will be moved into place later 201ae7a6e3aSAdrien Destugues 2023722e640SJohn Scipione if (!((TBarApp*)be_app)->Settings()->showClock) 2033722e640SJohn Scipione fTime->Hide(); 2043722e640SJohn Scipione 20541281cf3SAxel Dörfler #ifdef DB_ADDONS 20641281cf3SAxel Dörfler // load addons and rehydrate archives 2073a6add49SAxel Dörfler #if !defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST) 20841281cf3SAxel Dörfler InitAddOnSupport(); 20941281cf3SAxel Dörfler #endif 2109c910f9eSStephan Aßmus #endif 21141281cf3SAxel Dörfler ResizeToPreferred(); 21241281cf3SAxel Dörfler } 21341281cf3SAxel Dörfler 21441281cf3SAxel Dörfler 21541281cf3SAxel Dörfler void 21641281cf3SAxel Dörfler TReplicantTray::DetachedFromWindow() 21741281cf3SAxel Dörfler { 21841281cf3SAxel Dörfler #ifdef DB_ADDONS 21941281cf3SAxel Dörfler // clean up add-on support 220465b54cdSAxel Dörfler #if !defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST) 22141281cf3SAxel Dörfler DeleteAddOnSupport(); 22241281cf3SAxel Dörfler #endif 223465b54cdSAxel Dörfler #endif 22441281cf3SAxel Dörfler BView::DetachedFromWindow(); 22541281cf3SAxel Dörfler } 22641281cf3SAxel Dörfler 22741281cf3SAxel Dörfler 2281ad8c760SFredrik Holmqvist /*! Width is set to a minimum of kMinimumReplicantCount by kMaxReplicantWidth 22966eba86fSAxel Dörfler if not in multirowmode and greater than kMinimumReplicantCount 2302ce9bab8SJohn Scipione the width should be calculated based on the actual replicant widths 23141281cf3SAxel Dörfler */ 23241281cf3SAxel Dörfler void 23341281cf3SAxel Dörfler TReplicantTray::GetPreferredSize(float* preferredWidth, float* preferredHeight) 23441281cf3SAxel Dörfler { 2351bb2e623SJohn Scipione float width = 0; 236efafab64SAxel Dörfler float height = fMinTrayHeight; 2371be85605SAugustin Cavalier const float trayPadding = ceilf(be_control_look->ComposeSpacing(kTrayPadding) / 2); 23841281cf3SAxel Dörfler 239f9b3a3b1SJohn Scipione if (fBarView->Vertical()) { 2401bb2e623SJohn Scipione width = static_cast<TBarApp*>(be_app)->Settings()->width 2419f4bb0f5SAugustin Cavalier - gDragWidth - kGutter; 2429f4bb0f5SAugustin Cavalier width = std::max(gMinimumTrayWidth, width); 2439f4bb0f5SAugustin Cavalier 244a44504a1SJohn Scipione if (fRightBottomReplicant.IsValid()) 2457da06231SAxel Dörfler height = fRightBottomReplicant.bottom; 246a44504a1SJohn Scipione else if (ReplicantCount() > 0) { 247a44504a1SJohn Scipione // The height will be uniform for the number of rows necessary 248a44504a1SJohn Scipione // to show all the replicants and gutters. 249efafab64SAxel Dörfler int32 rowCount = (int32)(height / fMaxReplicantHeight); 250efafab64SAxel Dörfler height = kGutter + (rowCount * fMaxReplicantHeight) 2519f4bb0f5SAugustin Cavalier + ((rowCount - 1) * sIconGap) + kGutter; 252efafab64SAxel Dörfler height = std::max(fMinTrayHeight, height); 253a44504a1SJohn Scipione } else 254efafab64SAxel Dörfler height = fMinTrayHeight; 25541281cf3SAxel Dörfler } else { 2561ad8c760SFredrik Holmqvist // if last replicant overruns clock then resize to accomodate 25732b0035aSJohn Scipione if (ReplicantCount() > 0) { 2581e0308a8SAugustin Cavalier if (!fTime->IsHidden(fTime) && Bounds().right - trayPadding - 2 259c0be5490SJohn Scipione - fTime->Frame().Width() - kClockMargin 2607b7bf68dSJohn Scipione < fRightBottomReplicant.right + kClockMargin) { 2617b7bf68dSJohn Scipione width = fRightBottomReplicant.right + kClockMargin 2621e0308a8SAugustin Cavalier + fTime->Frame().Width() + trayPadding + 2; 26341281cf3SAxel Dörfler } else 2649f4bb0f5SAugustin Cavalier width = fRightBottomReplicant.right + sIconGap + kGutter; 26541281cf3SAxel Dörfler } 2661ad8c760SFredrik Holmqvist 26741281cf3SAxel Dörfler // this view has a fixed minimum width 2689f4bb0f5SAugustin Cavalier width = std::max(gMinimumTrayWidth, width); 2690d2645e4SJohn Scipione 2700d2645e4SJohn Scipione // if mini-mode set to tab height 2710d2645e4SJohn Scipione // else if horizontal mode set to team menu item height 272f9b3a3b1SJohn Scipione if (fBarView->MiniState()) 2730d2645e4SJohn Scipione height = std::max(fMinTrayHeight, fBarView->TabHeight()); 2740d2645e4SJohn Scipione else 27503399b17SJohn Scipione height = fBarView->TeamMenuItemHeight(); 27641281cf3SAxel Dörfler } 27741281cf3SAxel Dörfler 27841281cf3SAxel Dörfler *preferredWidth = width; 2791ad8c760SFredrik Holmqvist // add 1 for the border 28041281cf3SAxel Dörfler *preferredHeight = height + 1; 28141281cf3SAxel Dörfler } 28241281cf3SAxel Dörfler 28341281cf3SAxel Dörfler 28441281cf3SAxel Dörfler void 28541281cf3SAxel Dörfler TReplicantTray::AdjustPlacement() 28641281cf3SAxel Dörfler { 28741281cf3SAxel Dörfler // called when an add-on has been added or removed 28841281cf3SAxel Dörfler // need to resize the parent of this accordingly 289a5210ab1SAxel Dörfler 29041281cf3SAxel Dörfler BRect bounds = Bounds(); 29141281cf3SAxel Dörfler float width, height; 29241281cf3SAxel Dörfler GetPreferredSize(&width, &height); 29341281cf3SAxel Dörfler 29441281cf3SAxel Dörfler if (width == bounds.Width() && height == bounds.Height()) { 29541281cf3SAxel Dörfler // no need to change anything 29641281cf3SAxel Dörfler return; 29741281cf3SAxel Dörfler } 29841281cf3SAxel Dörfler 29941281cf3SAxel Dörfler Parent()->ResizeToPreferred(); 30041281cf3SAxel Dörfler fBarView->UpdatePlacement(); 30141281cf3SAxel Dörfler Parent()->Invalidate(); 30241281cf3SAxel Dörfler Invalidate(); 30341281cf3SAxel Dörfler } 30441281cf3SAxel Dörfler 30541281cf3SAxel Dörfler 30641281cf3SAxel Dörfler void 30741281cf3SAxel Dörfler TReplicantTray::MessageReceived(BMessage* message) 30841281cf3SAxel Dörfler { 30941281cf3SAxel Dörfler switch (message->what) { 31030a55802SJohn Scipione case B_LOCALE_CHANGED: 311573f748cSJohn Scipione if (fTime == NULL) 312573f748cSJohn Scipione return; 313573f748cSJohn Scipione 3144c999927SAdrien Destugues fTime->UpdateTimeFormat(); 31531c0024dSJohn Scipione fTime->Update(); 31641281cf3SAxel Dörfler // time string reformat -> realign 317c0dc265cSJohn Scipione goto realignReplicants; 318573f748cSJohn Scipione 31930a55802SJohn Scipione case kShowHideTime: 32030a55802SJohn Scipione // from context menu in clock and in this view 32130a55802SJohn Scipione ShowHideTime(); 32230a55802SJohn Scipione break; 32330a55802SJohn Scipione 3243cf2d117SJohn Scipione case kShowSeconds: 325573f748cSJohn Scipione if (fTime == NULL) 326573f748cSJohn Scipione return; 327573f748cSJohn Scipione 3283cf2d117SJohn Scipione fTime->SetShowSeconds(!fTime->ShowSeconds()); 329573f748cSJohn Scipione 3303cf2d117SJohn Scipione // time string reformat -> realign 331c0dc265cSJohn Scipione goto realignReplicants; 3323cf2d117SJohn Scipione 3333cf2d117SJohn Scipione case kShowDayOfWeek: 3343cf2d117SJohn Scipione if (fTime == NULL) 3353cf2d117SJohn Scipione return; 3363cf2d117SJohn Scipione 3373cf2d117SJohn Scipione fTime->SetShowDayOfWeek(!fTime->ShowDayOfWeek()); 3383cf2d117SJohn Scipione 3393cf2d117SJohn Scipione // time string reformat -> realign 340c0dc265cSJohn Scipione goto realignReplicants; 3413cf2d117SJohn Scipione 34231c0024dSJohn Scipione case kShowTimeZone: 34331c0024dSJohn Scipione if (fTime == NULL) 34431c0024dSJohn Scipione return; 34531c0024dSJohn Scipione 34631c0024dSJohn Scipione fTime->SetShowTimeZone(!fTime->ShowTimeZone()); 34731c0024dSJohn Scipione 34831c0024dSJohn Scipione // time string reformat -> realign 349c0dc265cSJohn Scipione goto realignReplicants; 35031c0024dSJohn Scipione 35131c0024dSJohn Scipione case kGetClockSettings: 35231c0024dSJohn Scipione { 35331c0024dSJohn Scipione if (fTime == NULL) 35431c0024dSJohn Scipione return; 35531c0024dSJohn Scipione 3561c765f5bSJohn Scipione bool showClock = !fTime->IsHidden(fTime); 35731c0024dSJohn Scipione bool showSeconds = fTime->ShowSeconds(); 35831c0024dSJohn Scipione bool showDayOfWeek = fTime->ShowDayOfWeek(); 35931c0024dSJohn Scipione bool showTimeZone = fTime->ShowTimeZone(); 36031c0024dSJohn Scipione 3610fc30d89SDario Casalinuovo BMessage reply(kGetClockSettings); 3620fc30d89SDario Casalinuovo reply.AddBool("showClock", showClock); 3630fc30d89SDario Casalinuovo reply.AddBool("showSeconds", showSeconds); 3640fc30d89SDario Casalinuovo reply.AddBool("showDayOfWeek", showDayOfWeek); 3650fc30d89SDario Casalinuovo reply.AddBool("showTimeZone", showTimeZone); 3660fc30d89SDario Casalinuovo message->SendReply(&reply); 36731c0024dSJohn Scipione break; 36831c0024dSJohn Scipione } 36931c0024dSJohn Scipione 37041281cf3SAxel Dörfler #ifdef DB_ADDONS 37141281cf3SAxel Dörfler case B_NODE_MONITOR: 37241281cf3SAxel Dörfler HandleEntryUpdate(message); 37341281cf3SAxel Dörfler break; 37441281cf3SAxel Dörfler #endif 37541281cf3SAxel Dörfler 376c0dc265cSJohn Scipione case kRealignReplicants: 377c0dc265cSJohn Scipione realignReplicants: 378c0dc265cSJohn Scipione RealignReplicants(); 379c0dc265cSJohn Scipione AdjustPlacement(); 380c0dc265cSJohn Scipione break; 381c0dc265cSJohn Scipione 38241281cf3SAxel Dörfler default: 38341281cf3SAxel Dörfler BView::MessageReceived(message); 38441281cf3SAxel Dörfler break; 38541281cf3SAxel Dörfler } 38641281cf3SAxel Dörfler } 38741281cf3SAxel Dörfler 38841281cf3SAxel Dörfler 38941281cf3SAxel Dörfler void 39041281cf3SAxel Dörfler TReplicantTray::MouseDown(BPoint where) 39141281cf3SAxel Dörfler { 39241281cf3SAxel Dörfler #ifdef DB_ADDONS 39341281cf3SAxel Dörfler if (modifiers() & B_CONTROL_KEY) 39441281cf3SAxel Dörfler DumpList(fItemList); 39541281cf3SAxel Dörfler #endif 39641281cf3SAxel Dörfler 39741281cf3SAxel Dörfler uint32 buttons; 39841281cf3SAxel Dörfler 39941281cf3SAxel Dörfler Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); 40041281cf3SAxel Dörfler if (buttons == B_SECONDARY_MOUSE_BUTTON) { 40141281cf3SAxel Dörfler ShowReplicantMenu(where); 40241281cf3SAxel Dörfler } else { 40341281cf3SAxel Dörfler BPoint save = where; 40441281cf3SAxel Dörfler bigtime_t doubleClickSpeed; 40541281cf3SAxel Dörfler bigtime_t start = system_time(); 40641281cf3SAxel Dörfler uint32 buttons; 40741281cf3SAxel Dörfler 40841281cf3SAxel Dörfler get_click_speed(&doubleClickSpeed); 40941281cf3SAxel Dörfler 41041281cf3SAxel Dörfler do { 41141281cf3SAxel Dörfler if (fabs(where.x - save.x) > 4 || fabs(where.y - save.y) > 4) 41241281cf3SAxel Dörfler // user moved out of bounds of click area 41341281cf3SAxel Dörfler break; 41441281cf3SAxel Dörfler 41541281cf3SAxel Dörfler if ((system_time() - start) > (2 * doubleClickSpeed)) { 41641281cf3SAxel Dörfler ShowReplicantMenu(where); 41741281cf3SAxel Dörfler break; 41841281cf3SAxel Dörfler } 41941281cf3SAxel Dörfler 42041281cf3SAxel Dörfler snooze(50000); 42141281cf3SAxel Dörfler GetMouse(&where, &buttons); 42241281cf3SAxel Dörfler } while (buttons); 42341281cf3SAxel Dörfler } 42441281cf3SAxel Dörfler BView::MouseDown(where); 42541281cf3SAxel Dörfler } 42641281cf3SAxel Dörfler 4273cf2d117SJohn Scipione 4283cf2d117SJohn Scipione void 4293cf2d117SJohn Scipione TReplicantTray::ShowReplicantMenu(BPoint point) 4303cf2d117SJohn Scipione { 4313cf2d117SJohn Scipione BPopUpMenu* menu = new BPopUpMenu("", false, false); 4323cf2d117SJohn Scipione menu->SetFont(be_plain_font); 4333cf2d117SJohn Scipione 43431c0024dSJohn Scipione // If clock is visible show the extended menu, otherwise show "Show clock" 4353cf2d117SJohn Scipione 4361c765f5bSJohn Scipione if (!fTime->IsHidden(fTime)) 4373cf2d117SJohn Scipione fTime->ShowTimeOptions(ConvertToScreen(point)); 4383cf2d117SJohn Scipione else { 43931c0024dSJohn Scipione BMenuItem* item = new BMenuItem(B_TRANSLATE("Show clock"), 4403cf2d117SJohn Scipione new BMessage(kShowHideTime)); 4413cf2d117SJohn Scipione menu->AddItem(item); 4423cf2d117SJohn Scipione menu->SetTargetForItems(this); 4433cf2d117SJohn Scipione BPoint where = ConvertToScreen(point); 4443cf2d117SJohn Scipione menu->Go(where, true, true, BRect(where - BPoint(4, 4), 4453cf2d117SJohn Scipione where + BPoint(4, 4)), true); 4463cf2d117SJohn Scipione } 4473cf2d117SJohn Scipione } 4483cf2d117SJohn Scipione 4493cf2d117SJohn Scipione 4503cf2d117SJohn Scipione void 4513cf2d117SJohn Scipione TReplicantTray::ShowHideTime() 4523cf2d117SJohn Scipione { 4533cf2d117SJohn Scipione if (fTime == NULL) 4543cf2d117SJohn Scipione return; 4553cf2d117SJohn Scipione 4562a5c1f12SJohn Scipione // Check from the point of view of fTime because we need to ignore 4572a5c1f12SJohn Scipione // whether or not the parent window is hidden. 4582a5c1f12SJohn Scipione if (fTime->IsHidden(fTime)) 4593cf2d117SJohn Scipione fTime->Show(); 4603cf2d117SJohn Scipione else 4613cf2d117SJohn Scipione fTime->Hide(); 4623cf2d117SJohn Scipione 4633cf2d117SJohn Scipione RealignReplicants(); 4643cf2d117SJohn Scipione AdjustPlacement(); 46531c0024dSJohn Scipione 4662a5c1f12SJohn Scipione // Check from the point of view of fTime ignoring parent's state. 4672a5c1f12SJohn Scipione bool showClock = !fTime->IsHidden(fTime); 4683722e640SJohn Scipione 4693722e640SJohn Scipione // Update showClock setting that gets saved to disk on quit 4701bb2e623SJohn Scipione static_cast<TBarApp*>(be_app)->Settings()->showClock = showClock; 4713722e640SJohn Scipione 4723722e640SJohn Scipione // Send a message to Time preferences telling it to update 47331c0024dSJohn Scipione BMessenger messenger("application/x-vnd.Haiku-Time"); 4740fc30d89SDario Casalinuovo BMessage message(kShowHideTime); 4750fc30d89SDario Casalinuovo message.AddBool("showClock", showClock); 4760fc30d89SDario Casalinuovo messenger.SendMessage(&message); 4773cf2d117SJohn Scipione } 4783cf2d117SJohn Scipione 4793cf2d117SJohn Scipione 48041281cf3SAxel Dörfler #ifdef DB_ADDONS 48141281cf3SAxel Dörfler 4823cf2d117SJohn Scipione 48341281cf3SAxel Dörfler void 48441281cf3SAxel Dörfler TReplicantTray::InitAddOnSupport() 48541281cf3SAxel Dörfler { 48641281cf3SAxel Dörfler // list to maintain refs to each rep added/deleted 48741281cf3SAxel Dörfler fItemList = new BList(); 48841281cf3SAxel Dörfler BPath path; 4891ad8c760SFredrik Holmqvist 49026ea7066SIngo Weinhold if (GetDeskbarSettingsDirectory(path, true) == B_OK) { 4913e6ff860SRene Gollent path.Append(kReplicantSettingsFile); 49241281cf3SAxel Dörfler 49341281cf3SAxel Dörfler BFile file(path.Path(), B_READ_ONLY); 4943e6ff860SRene Gollent if (file.InitCheck() == B_OK) { 4953e6ff860SRene Gollent status_t result; 4963e6ff860SRene Gollent BEntry entry; 4973e6ff860SRene Gollent int32 id; 498c0ad1c91SRene Gollent BString path; 4993e6ff860SRene Gollent if (fAddOnSettings.Unflatten(&file) == B_OK) { 500c0ad1c91SRene Gollent for (int32 i = 0; fAddOnSettings.FindString(kReplicantPathField, 501c0ad1c91SRene Gollent i, &path) == B_OK; i++) { 502c0ad1c91SRene Gollent if (entry.SetTo(path.String()) == B_OK && entry.Exists()) { 5033e6ff860SRene Gollent result = LoadAddOn(&entry, &id, false); 5043e6ff860SRene Gollent } else 5053e6ff860SRene Gollent result = B_ENTRY_NOT_FOUND; 50641281cf3SAxel Dörfler 5073e6ff860SRene Gollent if (result != B_OK) { 508c0ad1c91SRene Gollent fAddOnSettings.RemoveData(kReplicantPathField, i); 5093e6ff860SRene Gollent --i; 51041281cf3SAxel Dörfler } 51141281cf3SAxel Dörfler } 51241281cf3SAxel Dörfler } 5133e6ff860SRene Gollent } 5143e6ff860SRene Gollent } 51541281cf3SAxel Dörfler } 51641281cf3SAxel Dörfler 51741281cf3SAxel Dörfler 51841281cf3SAxel Dörfler void 51941281cf3SAxel Dörfler TReplicantTray::DeleteAddOnSupport() 52041281cf3SAxel Dörfler { 5217625ce51SRene Gollent _SaveSettings(); 5223e6ff860SRene Gollent 5239f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 52441281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->RemoveItem(i); 52541281cf3SAxel Dörfler if (item) { 52641281cf3SAxel Dörfler if (item->isAddOn) 52741281cf3SAxel Dörfler watch_node(&(item->nodeRef), B_STOP_WATCHING, this, Window()); 52841281cf3SAxel Dörfler 52941281cf3SAxel Dörfler delete item; 53041281cf3SAxel Dörfler } 53141281cf3SAxel Dörfler } 53241281cf3SAxel Dörfler delete fItemList; 53341281cf3SAxel Dörfler 53441281cf3SAxel Dörfler // stop the volume mount/unmount watch 53541281cf3SAxel Dörfler stop_watching(this, Window()); 53641281cf3SAxel Dörfler } 53741281cf3SAxel Dörfler 53841281cf3SAxel Dörfler 53941281cf3SAxel Dörfler DeskbarItemInfo* 54041281cf3SAxel Dörfler TReplicantTray::DeskbarItemFor(node_ref& nodeRef) 54141281cf3SAxel Dörfler { 5429f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 54366eba86fSAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 54441281cf3SAxel Dörfler if (item == NULL) 54541281cf3SAxel Dörfler continue; 54641281cf3SAxel Dörfler 54741281cf3SAxel Dörfler if (item->nodeRef == nodeRef) 54841281cf3SAxel Dörfler return item; 54941281cf3SAxel Dörfler } 55041281cf3SAxel Dörfler 55141281cf3SAxel Dörfler return NULL; 55241281cf3SAxel Dörfler } 55341281cf3SAxel Dörfler 55441281cf3SAxel Dörfler 55541281cf3SAxel Dörfler DeskbarItemInfo* 55641281cf3SAxel Dörfler TReplicantTray::DeskbarItemFor(int32 id) 55741281cf3SAxel Dörfler { 5589f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 55966eba86fSAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 56041281cf3SAxel Dörfler if (item == NULL) 56141281cf3SAxel Dörfler continue; 56241281cf3SAxel Dörfler 56341281cf3SAxel Dörfler if (item->id == id) 56441281cf3SAxel Dörfler return item; 56541281cf3SAxel Dörfler } 56641281cf3SAxel Dörfler 56741281cf3SAxel Dörfler return NULL; 56841281cf3SAxel Dörfler } 56941281cf3SAxel Dörfler 57041281cf3SAxel Dörfler 57141281cf3SAxel Dörfler bool 57241281cf3SAxel Dörfler TReplicantTray::NodeExists(node_ref& nodeRef) 57341281cf3SAxel Dörfler { 57441281cf3SAxel Dörfler return DeskbarItemFor(nodeRef) != NULL; 57541281cf3SAxel Dörfler } 57641281cf3SAxel Dörfler 57741281cf3SAxel Dörfler 57866eba86fSAxel Dörfler /*! This handles B_NODE_MONITOR & B_QUERY_UPDATE messages received 57966eba86fSAxel Dörfler for the registered add-ons. 58041281cf3SAxel Dörfler */ 58141281cf3SAxel Dörfler void 58241281cf3SAxel Dörfler TReplicantTray::HandleEntryUpdate(BMessage* message) 58341281cf3SAxel Dörfler { 58441281cf3SAxel Dörfler int32 opcode; 58541281cf3SAxel Dörfler if (message->FindInt32("opcode", &opcode) != B_OK) 58641281cf3SAxel Dörfler return; 58741281cf3SAxel Dörfler 58841281cf3SAxel Dörfler BPath path; 58941281cf3SAxel Dörfler switch (opcode) { 59041281cf3SAxel Dörfler case B_ENTRY_MOVED: 59141281cf3SAxel Dörfler { 59241281cf3SAxel Dörfler entry_ref ref; 59341281cf3SAxel Dörfler ino_t todirectory; 59441281cf3SAxel Dörfler ino_t node; 59541281cf3SAxel Dörfler const char* name; 59641281cf3SAxel Dörfler if (message->FindString("name", &name) == B_OK 59771bd3ba5SJonas Sundström && message->FindInt64("from directory", &(ref.directory)) 59871bd3ba5SJonas Sundström == B_OK 59941281cf3SAxel Dörfler && message->FindInt64("to directory", &todirectory) == B_OK 60041281cf3SAxel Dörfler && message->FindInt32("device", &(ref.device)) == B_OK 60141281cf3SAxel Dörfler && message->FindInt64("node", &node) == B_OK ) { 60241281cf3SAxel Dörfler 603e4d65fe7SJohn Scipione if (name == NULL) 60441281cf3SAxel Dörfler break; 60541281cf3SAxel Dörfler 60641281cf3SAxel Dörfler ref.set_name(name); 60741281cf3SAxel Dörfler // change the directory reference to 60841281cf3SAxel Dörfler // the new directory 60941281cf3SAxel Dörfler MoveItem(&ref, todirectory); 61041281cf3SAxel Dörfler } 61141281cf3SAxel Dörfler break; 61266eba86fSAxel Dörfler } 61341281cf3SAxel Dörfler 61441281cf3SAxel Dörfler case B_ENTRY_REMOVED: 61541281cf3SAxel Dörfler { 61641281cf3SAxel Dörfler // entry was rm'd from the device 61741281cf3SAxel Dörfler node_ref nodeRef; 61841281cf3SAxel Dörfler if (message->FindInt32("device", &(nodeRef.device)) == B_OK 61941281cf3SAxel Dörfler && message->FindInt64("node", &(nodeRef.node)) == B_OK) { 62041281cf3SAxel Dörfler DeskbarItemInfo* item = DeskbarItemFor(nodeRef); 62141281cf3SAxel Dörfler if (item == NULL) 62241281cf3SAxel Dörfler break; 62341281cf3SAxel Dörfler 62441281cf3SAxel Dörfler // If there is a team running where the add-on comes from, 62541281cf3SAxel Dörfler // we don't want to remove the icon yet. 62641281cf3SAxel Dörfler if (be_roster->IsRunning(&item->entryRef)) 62741281cf3SAxel Dörfler break; 62841281cf3SAxel Dörfler 62941281cf3SAxel Dörfler UnloadAddOn(&nodeRef, NULL, true, false); 63041281cf3SAxel Dörfler } 63141281cf3SAxel Dörfler break; 63266eba86fSAxel Dörfler } 63341281cf3SAxel Dörfler } 63466eba86fSAxel Dörfler } 63541281cf3SAxel Dörfler 63641281cf3SAxel Dörfler 6371ad8c760SFredrik Holmqvist /*! The add-ons must support the exported C function API 63866eba86fSAxel Dörfler if they do, they will be loaded and added to deskbar 63966eba86fSAxel Dörfler primary function is the Instantiate function 6407da06231SAxel Dörfler */ 64141281cf3SAxel Dörfler status_t 6423e6ff860SRene Gollent TReplicantTray::LoadAddOn(BEntry* entry, int32* id, bool addToSettings) 64341281cf3SAxel Dörfler { 644e4d65fe7SJohn Scipione if (entry == NULL) 645a6be6c4dSJohn Scipione return B_BAD_VALUE; 64641281cf3SAxel Dörfler 64741281cf3SAxel Dörfler node_ref nodeRef; 64841281cf3SAxel Dörfler entry->GetNodeRef(&nodeRef); 64941281cf3SAxel Dörfler // no duplicates 65041281cf3SAxel Dörfler if (NodeExists(nodeRef)) 65141281cf3SAxel Dörfler return B_ERROR; 65241281cf3SAxel Dörfler 65341281cf3SAxel Dörfler BNode node(entry); 65441281cf3SAxel Dörfler BPath path; 65566eba86fSAxel Dörfler status_t status = entry->GetPath(&path); 656e4d65fe7SJohn Scipione if (status != B_OK) 65766eba86fSAxel Dörfler return status; 65841281cf3SAxel Dörfler 65941281cf3SAxel Dörfler // load the add-on 66041281cf3SAxel Dörfler image_id image = load_add_on(path.Path()); 66166eba86fSAxel Dörfler if (image < B_OK) 66266eba86fSAxel Dörfler return image; 66341281cf3SAxel Dörfler 66441281cf3SAxel Dörfler // get the view loading function symbol 66541281cf3SAxel Dörfler // we first look for a symbol that takes an image_id 66641281cf3SAxel Dörfler // and entry_ref pointer, if not found, go with normal 66741281cf3SAxel Dörfler // instantiate function 668efafab64SAxel Dörfler BView* (*entryFunction)(image_id, const entry_ref*, float, float); 669efafab64SAxel Dörfler BView* (*itemFunction)(float, float); 67041281cf3SAxel Dörfler BView* view = NULL; 67141281cf3SAxel Dörfler 67241281cf3SAxel Dörfler entry_ref ref; 67341281cf3SAxel Dörfler entry->GetRef(&ref); 67441281cf3SAxel Dörfler 67541281cf3SAxel Dörfler if (get_image_symbol(image, kInstantiateEntryCFunctionName, 67666eba86fSAxel Dörfler B_SYMBOL_TYPE_TEXT, (void**)&entryFunction) >= B_OK) { 677efafab64SAxel Dörfler view = (*entryFunction)(image, &ref, fMaxReplicantWidth, 678efafab64SAxel Dörfler fMaxReplicantHeight); 67941281cf3SAxel Dörfler } else if (get_image_symbol(image, kInstantiateItemCFunctionName, 68066eba86fSAxel Dörfler B_SYMBOL_TYPE_TEXT, (void**)&itemFunction) >= B_OK) { 681efafab64SAxel Dörfler view = (*itemFunction)(fMaxReplicantWidth, fMaxReplicantHeight); 68241281cf3SAxel Dörfler } else { 68341281cf3SAxel Dörfler unload_add_on(image); 68441281cf3SAxel Dörfler return B_ERROR; 68541281cf3SAxel Dörfler } 68641281cf3SAxel Dörfler 68766eba86fSAxel Dörfler if (view == NULL || IconExists(view->Name())) { 68841281cf3SAxel Dörfler delete view; 68941281cf3SAxel Dörfler unload_add_on(image); 69041281cf3SAxel Dörfler return B_ERROR; 69141281cf3SAxel Dörfler } 69241281cf3SAxel Dörfler 69341281cf3SAxel Dörfler BMessage* data = new BMessage; 69441281cf3SAxel Dörfler view->Archive(data); 69541281cf3SAxel Dörfler delete view; 69641281cf3SAxel Dörfler 69741281cf3SAxel Dörfler // add the rep; adds info to list 6980fc30d89SDario Casalinuovo if (AddIcon(data, id, &ref) != B_OK) 6990fc30d89SDario Casalinuovo delete data; 70041281cf3SAxel Dörfler 7013e6ff860SRene Gollent if (addToSettings) { 702c0ad1c91SRene Gollent fAddOnSettings.AddString(kReplicantPathField, path.Path()); 7037625ce51SRene Gollent _SaveSettings(); 7043e6ff860SRene Gollent } 70541281cf3SAxel Dörfler 70641281cf3SAxel Dörfler return B_OK; 70741281cf3SAxel Dörfler } 70841281cf3SAxel Dörfler 70941281cf3SAxel Dörfler 71041281cf3SAxel Dörfler status_t 71141281cf3SAxel Dörfler TReplicantTray::AddItem(int32 id, node_ref nodeRef, BEntry& entry, bool isAddOn) 71241281cf3SAxel Dörfler { 71341281cf3SAxel Dörfler DeskbarItemInfo* item = new DeskbarItemInfo; 71441281cf3SAxel Dörfler if (item == NULL) 71541281cf3SAxel Dörfler return B_NO_MEMORY; 71641281cf3SAxel Dörfler 71741281cf3SAxel Dörfler item->id = id; 71841281cf3SAxel Dörfler item->isAddOn = isAddOn; 71941281cf3SAxel Dörfler 720e4d65fe7SJohn Scipione if (entry.GetRef(&item->entryRef) != B_OK) { 72141281cf3SAxel Dörfler item->entryRef.device = -1; 72241281cf3SAxel Dörfler item->entryRef.directory = -1; 72341281cf3SAxel Dörfler item->entryRef.name = NULL; 72441281cf3SAxel Dörfler } 72541281cf3SAxel Dörfler item->nodeRef = nodeRef; 72641281cf3SAxel Dörfler 72741281cf3SAxel Dörfler fItemList->AddItem(item); 72841281cf3SAxel Dörfler 72941281cf3SAxel Dörfler if (isAddOn) 73041281cf3SAxel Dörfler watch_node(&nodeRef, B_WATCH_NAME | B_WATCH_ATTR, this, Window()); 73141281cf3SAxel Dörfler 73241281cf3SAxel Dörfler return B_OK; 73341281cf3SAxel Dörfler } 73441281cf3SAxel Dörfler 73541281cf3SAxel Dörfler 73641281cf3SAxel Dörfler /** from entry_removed message, when attribute removed 73741281cf3SAxel Dörfler * or when a device is unmounted (use removeall, by device) 73841281cf3SAxel Dörfler */ 73941281cf3SAxel Dörfler 74041281cf3SAxel Dörfler void 741e4d65fe7SJohn Scipione TReplicantTray::UnloadAddOn(node_ref* nodeRef, dev_t* device, bool which, 742e4d65fe7SJohn Scipione bool removeAll) 74341281cf3SAxel Dörfler { 7449f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 74541281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 746e4d65fe7SJohn Scipione if (item == NULL) 74741281cf3SAxel Dörfler continue; 74841281cf3SAxel Dörfler 749e4d65fe7SJohn Scipione if ((which && nodeRef != NULL && item->nodeRef == *nodeRef) 750e4d65fe7SJohn Scipione || (device != NULL && item->nodeRef.device == *device)) { 75141281cf3SAxel Dörfler 752e4d65fe7SJohn Scipione if (device != NULL && be_roster->IsRunning(&item->entryRef)) 75341281cf3SAxel Dörfler continue; 75441281cf3SAxel Dörfler 75541281cf3SAxel Dörfler RemoveIcon(item->id); 75641281cf3SAxel Dörfler 75741281cf3SAxel Dörfler if (!removeAll) 75841281cf3SAxel Dörfler break; 75941281cf3SAxel Dörfler } 76041281cf3SAxel Dörfler } 76141281cf3SAxel Dörfler } 76241281cf3SAxel Dörfler 76341281cf3SAxel Dörfler 76441281cf3SAxel Dörfler void 76541281cf3SAxel Dörfler TReplicantTray::RemoveItem(int32 id) 76641281cf3SAxel Dörfler { 76741281cf3SAxel Dörfler DeskbarItemInfo* item = DeskbarItemFor(id); 76841281cf3SAxel Dörfler if (item == NULL) 76941281cf3SAxel Dörfler return; 77041281cf3SAxel Dörfler 77141281cf3SAxel Dörfler // attribute was added via Deskbar API (AddItem(entry_ref*, int32*) 77241281cf3SAxel Dörfler if (item->isAddOn) { 7737625ce51SRene Gollent BPath path(&item->entryRef); 7747625ce51SRene Gollent BString storedPath; 7757625ce51SRene Gollent for (int32 i = 0; 7768aab28f1SRene Gollent fAddOnSettings.FindString(kReplicantPathField, i, &storedPath) 7777625ce51SRene Gollent == B_OK; i++) { 7787625ce51SRene Gollent if (storedPath == path.Path()) { 7798aab28f1SRene Gollent fAddOnSettings.RemoveData(kReplicantPathField, i); 7807625ce51SRene Gollent break; 7817625ce51SRene Gollent } 7827625ce51SRene Gollent } 7837625ce51SRene Gollent _SaveSettings(); 7847625ce51SRene Gollent 78541281cf3SAxel Dörfler BNode node(&item->entryRef); 78641281cf3SAxel Dörfler watch_node(&item->nodeRef, B_STOP_WATCHING, this, Window()); 78741281cf3SAxel Dörfler } 78841281cf3SAxel Dörfler 78941281cf3SAxel Dörfler fItemList->RemoveItem(item); 79041281cf3SAxel Dörfler delete item; 79141281cf3SAxel Dörfler } 79241281cf3SAxel Dörfler 79341281cf3SAxel Dörfler 79441281cf3SAxel Dörfler /** ENTRY_MOVED message, moving only occurs on a device 79541281cf3SAxel Dörfler * copying will occur (ENTRY_CREATED) between devices 79641281cf3SAxel Dörfler */ 79741281cf3SAxel Dörfler 79841281cf3SAxel Dörfler void 79941281cf3SAxel Dörfler TReplicantTray::MoveItem(entry_ref* ref, ino_t toDirectory) 80041281cf3SAxel Dörfler { 801e4d65fe7SJohn Scipione if (ref == NULL) 80241281cf3SAxel Dörfler return; 80341281cf3SAxel Dörfler 80441281cf3SAxel Dörfler // scan for a matching entry_ref and update it 80541281cf3SAxel Dörfler // 80641281cf3SAxel Dörfler // don't need to change node info as it does not change 80741281cf3SAxel Dörfler 8089f2cce2fSJohn Scipione for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { 80941281cf3SAxel Dörfler DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); 810e4d65fe7SJohn Scipione if (item == NULL) 81141281cf3SAxel Dörfler continue; 81241281cf3SAxel Dörfler 813e4d65fe7SJohn Scipione if (strcmp(item->entryRef.name, ref->name) == 0 81441281cf3SAxel Dörfler && item->entryRef.device == ref->device 81541281cf3SAxel Dörfler && item->entryRef.directory == ref->directory) { 81641281cf3SAxel Dörfler item->entryRef.directory = toDirectory; 81741281cf3SAxel Dörfler break; 81841281cf3SAxel Dörfler } 81941281cf3SAxel Dörfler } 82041281cf3SAxel Dörfler } 82141281cf3SAxel Dörfler 82241281cf3SAxel Dörfler #endif // add-on support 82341281cf3SAxel Dörfler 82441281cf3SAxel Dörfler // external add-on API routines 82541281cf3SAxel Dörfler // called using the new BDeskbar class 82641281cf3SAxel Dörfler 82741281cf3SAxel Dörfler // existence of icon/replicant by name or ID 82841281cf3SAxel Dörfler // returns opposite 82941281cf3SAxel Dörfler // note: name and id are semi-private limiting 83041281cf3SAxel Dörfler // the ability of non-host apps to remove 83141281cf3SAxel Dörfler // icons without a little bit of work 83241281cf3SAxel Dörfler 83341281cf3SAxel Dörfler /** for a specific id 83441281cf3SAxel Dörfler * return the name of the replicant (name of view) 83541281cf3SAxel Dörfler */ 83641281cf3SAxel Dörfler 83741281cf3SAxel Dörfler status_t 83841281cf3SAxel Dörfler TReplicantTray::ItemInfo(int32 id, const char** name) 83941281cf3SAxel Dörfler { 84041281cf3SAxel Dörfler if (id < 0) 841a6be6c4dSJohn Scipione return B_BAD_VALUE; 84241281cf3SAxel Dörfler 843e4d65fe7SJohn Scipione int32 index; 844e4d65fe7SJohn Scipione int32 temp; 84541281cf3SAxel Dörfler BView* view = ViewAt(&index, &temp, id, false); 846e4d65fe7SJohn Scipione if (view != NULL) { 84741281cf3SAxel Dörfler *name = view->Name(); 84841281cf3SAxel Dörfler return B_OK; 84941281cf3SAxel Dörfler } 85041281cf3SAxel Dörfler 85141281cf3SAxel Dörfler return B_ERROR; 85241281cf3SAxel Dörfler } 85341281cf3SAxel Dörfler 85441281cf3SAxel Dörfler 8557da06231SAxel Dörfler /** for a specific name 8567da06231SAxel Dörfler * return the id (internal to Deskbar) 8577da06231SAxel Dörfler */ 8587da06231SAxel Dörfler 85941281cf3SAxel Dörfler status_t 86041281cf3SAxel Dörfler TReplicantTray::ItemInfo(const char* name, int32* id) 86141281cf3SAxel Dörfler { 862e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 863a6be6c4dSJohn Scipione return B_BAD_VALUE; 86441281cf3SAxel Dörfler 86541281cf3SAxel Dörfler int32 index; 86641281cf3SAxel Dörfler BView* view = ViewAt(&index, id, name); 86741281cf3SAxel Dörfler 868378aa08bSJohn Scipione return view != NULL ? B_OK : B_ERROR; 86941281cf3SAxel Dörfler } 87041281cf3SAxel Dörfler 87141281cf3SAxel Dörfler 8727da06231SAxel Dörfler /** at a specific index 8737da06231SAxel Dörfler * return both the name and the id of the replicant 8747da06231SAxel Dörfler */ 8757da06231SAxel Dörfler 87641281cf3SAxel Dörfler status_t 87741281cf3SAxel Dörfler TReplicantTray::ItemInfo(int32 index, const char** name, int32* id) 87841281cf3SAxel Dörfler { 87941281cf3SAxel Dörfler if (index < 0) 880a6be6c4dSJohn Scipione return B_BAD_VALUE; 88141281cf3SAxel Dörfler 88241281cf3SAxel Dörfler BView* view; 88341281cf3SAxel Dörfler fShelf->ReplicantAt(index, &view, (uint32*)id, NULL); 884e4d65fe7SJohn Scipione if (view != NULL) { 88541281cf3SAxel Dörfler *name = view->Name(); 88641281cf3SAxel Dörfler return B_OK; 88741281cf3SAxel Dörfler } 88841281cf3SAxel Dörfler 88941281cf3SAxel Dörfler return B_ERROR; 89041281cf3SAxel Dörfler } 89141281cf3SAxel Dörfler 89241281cf3SAxel Dörfler 8937da06231SAxel Dörfler /** replicant exists, by id/index */ 8947da06231SAxel Dörfler 89541281cf3SAxel Dörfler bool 89641281cf3SAxel Dörfler TReplicantTray::IconExists(int32 target, bool byIndex) 89741281cf3SAxel Dörfler { 898e4d65fe7SJohn Scipione int32 index; 899e4d65fe7SJohn Scipione int32 id; 90041281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 90141281cf3SAxel Dörfler 90241281cf3SAxel Dörfler return view && index >= 0; 90341281cf3SAxel Dörfler } 90441281cf3SAxel Dörfler 90541281cf3SAxel Dörfler 9067da06231SAxel Dörfler /** replicant exists, by name */ 9077da06231SAxel Dörfler 90841281cf3SAxel Dörfler bool 90941281cf3SAxel Dörfler TReplicantTray::IconExists(const char* name) 91041281cf3SAxel Dörfler { 911e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 91241281cf3SAxel Dörfler return false; 91341281cf3SAxel Dörfler 914e4d65fe7SJohn Scipione int32 index; 915e4d65fe7SJohn Scipione int32 id; 91641281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 91741281cf3SAxel Dörfler 918e4d65fe7SJohn Scipione return view != NULL && index >= 0; 91941281cf3SAxel Dörfler } 92041281cf3SAxel Dörfler 92141281cf3SAxel Dörfler 92241281cf3SAxel Dörfler int32 92332b0035aSJohn Scipione TReplicantTray::ReplicantCount() const 92441281cf3SAxel Dörfler { 92541281cf3SAxel Dörfler return fShelf->CountReplicants(); 92641281cf3SAxel Dörfler } 92741281cf3SAxel Dörfler 92841281cf3SAxel Dörfler 929ced3755cSAxel Dörfler /*! Message must contain an archivable view for later rehydration. 930ced3755cSAxel Dörfler This function takes over ownership of the provided message on success 931ced3755cSAxel Dörfler only. 932ced3755cSAxel Dörfler Returns the current replicant ID. 9337da06231SAxel Dörfler */ 93441281cf3SAxel Dörfler status_t 935ced3755cSAxel Dörfler TReplicantTray::AddIcon(BMessage* archive, int32* id, const entry_ref* addOn) 93641281cf3SAxel Dörfler { 937ced3755cSAxel Dörfler if (archive == NULL || id == NULL) 938a6be6c4dSJohn Scipione return B_BAD_VALUE; 93941281cf3SAxel Dörfler 9409c50f36eSAxel Dörfler // find entry_ref 9419c50f36eSAxel Dörfler 9429c50f36eSAxel Dörfler entry_ref ref; 943e4d65fe7SJohn Scipione if (addOn != NULL) { 9449c50f36eSAxel Dörfler // Use it if we got it 9459c50f36eSAxel Dörfler ref = *addOn; 9469c50f36eSAxel Dörfler } else { 9479c50f36eSAxel Dörfler const char* signature; 9481ad8c760SFredrik Holmqvist 949ced3755cSAxel Dörfler status_t status = archive->FindString("add_on", &signature); 9509c50f36eSAxel Dörfler if (status == B_OK) { 9519c50f36eSAxel Dörfler BRoster roster; 9529c50f36eSAxel Dörfler status = roster.FindApp(signature, &ref); 9539c50f36eSAxel Dörfler } 954e4d65fe7SJohn Scipione if (status != B_OK) 9559c50f36eSAxel Dörfler return status; 9569c50f36eSAxel Dörfler } 9579c50f36eSAxel Dörfler 9589c50f36eSAxel Dörfler BFile file; 9599c50f36eSAxel Dörfler status_t status = file.SetTo(&ref, B_READ_ONLY); 960e4d65fe7SJohn Scipione if (status != B_OK) 9619c50f36eSAxel Dörfler return status; 9629c50f36eSAxel Dörfler 9639c50f36eSAxel Dörfler node_ref nodeRef; 9649c50f36eSAxel Dörfler status = file.GetNodeRef(&nodeRef); 965e4d65fe7SJohn Scipione if (status != B_OK) 9669c50f36eSAxel Dörfler return status; 9679c50f36eSAxel Dörfler 9689c50f36eSAxel Dörfler BEntry entry(&ref, true); 9691ad8c760SFredrik Holmqvist // TODO: this resolves an eventual link for the item being added - this 9701ad8c760SFredrik Holmqvist // is okay for now, but in multi-user environments, one might want to 9711ad8c760SFredrik Holmqvist // have links that carry the be:deskbar_item_status attribute 9729c50f36eSAxel Dörfler status = entry.InitCheck(); 9739c50f36eSAxel Dörfler if (status != B_OK) 9749c50f36eSAxel Dörfler return status; 9759c50f36eSAxel Dörfler 97641281cf3SAxel Dörfler *id = 999; 977ced3755cSAxel Dörfler if (archive->what == B_ARCHIVED_OBJECT) 978ced3755cSAxel Dörfler archive->what = 0; 97941281cf3SAxel Dörfler 980ced3755cSAxel Dörfler BRect originalBounds = archive->FindRect("_frame"); 9811ad8c760SFredrik Holmqvist // this is a work-around for buggy replicants that change their size in 9821ad8c760SFredrik Holmqvist // AttachedToWindow() (such as "SVM") 983a5210ab1SAxel Dörfler 9841ad8c760SFredrik Holmqvist // TODO: check for name collisions? 985ced3755cSAxel Dörfler status = fShelf->AddReplicant(archive, BPoint(1, 1)); 9869c50f36eSAxel Dörfler if (status != B_OK) 9879c50f36eSAxel Dörfler return status; 98841281cf3SAxel Dörfler 98932b0035aSJohn Scipione int32 count = ReplicantCount(); 990a5210ab1SAxel Dörfler BView* view; 991a5210ab1SAxel Dörfler fShelf->ReplicantAt(count - 1, &view, (uint32*)id, NULL); 992a5210ab1SAxel Dörfler 993a6be6c4dSJohn Scipione if (view != NULL && originalBounds != view->Bounds()) { 994a5210ab1SAxel Dörfler // The replicant changed its size when added to the window, so we need 99571bd3ba5SJonas Sundström // to recompute all over again (it's already done once via 99671bd3ba5SJonas Sundström // BShelf::AddReplicant() and TReplicantShelf::CanAcceptReplicantView()) 997a5210ab1SAxel Dörfler RealignReplicants(); 998a5210ab1SAxel Dörfler } 999a5210ab1SAxel Dörfler 100041281cf3SAxel Dörfler float oldWidth = Bounds().Width(); 100141281cf3SAxel Dörfler float oldHeight = Bounds().Height(); 100241281cf3SAxel Dörfler float width, height; 100341281cf3SAxel Dörfler GetPreferredSize(&width, &height); 100441281cf3SAxel Dörfler if (oldWidth != width || oldHeight != height) 100541281cf3SAxel Dörfler AdjustPlacement(); 100641281cf3SAxel Dörfler 100741281cf3SAxel Dörfler // add the item to the add-on list 100841281cf3SAxel Dörfler 100941281cf3SAxel Dörfler AddItem(*id, nodeRef, entry, addOn != NULL); 101041281cf3SAxel Dörfler return B_OK; 101141281cf3SAxel Dörfler } 101241281cf3SAxel Dörfler 101341281cf3SAxel Dörfler 101441281cf3SAxel Dörfler void 101541281cf3SAxel Dörfler TReplicantTray::RemoveIcon(int32 target, bool byIndex) 101641281cf3SAxel Dörfler { 101741281cf3SAxel Dörfler if (target < 0) 101841281cf3SAxel Dörfler return; 101941281cf3SAxel Dörfler 1020e4d65fe7SJohn Scipione int32 index; 1021e4d65fe7SJohn Scipione int32 id; 102241281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 1023e4d65fe7SJohn Scipione if (view != NULL && index >= 0) { 10247da06231SAxel Dörfler // remove the reference from the item list & the shelf 102541281cf3SAxel Dörfler RemoveItem(id); 102641281cf3SAxel Dörfler fShelf->DeleteReplicant(index); 10277da06231SAxel Dörfler 102841281cf3SAxel Dörfler // force a placement update, !! need to fix BShelf 102941281cf3SAxel Dörfler RealReplicantAdjustment(index); 103041281cf3SAxel Dörfler } 103141281cf3SAxel Dörfler } 103241281cf3SAxel Dörfler 103341281cf3SAxel Dörfler 103441281cf3SAxel Dörfler void 103541281cf3SAxel Dörfler TReplicantTray::RemoveIcon(const char* name) 103641281cf3SAxel Dörfler { 1037e4d65fe7SJohn Scipione if (name == NULL || *name == '\0') 103841281cf3SAxel Dörfler return; 103941281cf3SAxel Dörfler 1040378aa08bSJohn Scipione int32 index; 1041378aa08bSJohn Scipione int32 id; 104241281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 1043e4d65fe7SJohn Scipione if (view != NULL && index >= 0) { 10447da06231SAxel Dörfler // remove the reference from the item list & shelf 104541281cf3SAxel Dörfler RemoveItem(id); 104641281cf3SAxel Dörfler fShelf->DeleteReplicant(index); 10477da06231SAxel Dörfler 104841281cf3SAxel Dörfler // force a placement update, !! need to fix BShelf 104941281cf3SAxel Dörfler RealReplicantAdjustment(index); 105041281cf3SAxel Dörfler } 105141281cf3SAxel Dörfler } 105241281cf3SAxel Dörfler 105341281cf3SAxel Dörfler 105441281cf3SAxel Dörfler void 10557da06231SAxel Dörfler TReplicantTray::RealReplicantAdjustment(int32 startIndex) 105641281cf3SAxel Dörfler { 10577da06231SAxel Dörfler if (startIndex < 0) 105841281cf3SAxel Dörfler return; 10597da06231SAxel Dörfler 10607da06231SAxel Dörfler if (startIndex == fLastReplicant) 10617da06231SAxel Dörfler startIndex = 0; 10627da06231SAxel Dörfler 106341281cf3SAxel Dörfler // reset the locations of all replicants after the one deleted 10647da06231SAxel Dörfler RealignReplicants(startIndex); 106541281cf3SAxel Dörfler 106641281cf3SAxel Dörfler float oldWidth = Bounds().Width(); 106741281cf3SAxel Dörfler float oldHeight = Bounds().Height(); 106841281cf3SAxel Dörfler float width, height; 106941281cf3SAxel Dörfler GetPreferredSize(&width, &height); 107041281cf3SAxel Dörfler if (oldWidth != width || oldHeight != height) { 10711ad8c760SFredrik Holmqvist // resize view to accomodate the replicants, redraw as necessary 107241281cf3SAxel Dörfler AdjustPlacement(); 107341281cf3SAxel Dörfler } 107441281cf3SAxel Dörfler } 107541281cf3SAxel Dörfler 107641281cf3SAxel Dörfler 10777da06231SAxel Dörfler /** looking for a replicant by id/index 10787da06231SAxel Dörfler * return the view and index 10797da06231SAxel Dörfler */ 10807da06231SAxel Dörfler 108141281cf3SAxel Dörfler BView* 108241281cf3SAxel Dörfler TReplicantTray::ViewAt(int32* index, int32* id, int32 target, bool byIndex) 108341281cf3SAxel Dörfler { 108441281cf3SAxel Dörfler *index = -1; 108541281cf3SAxel Dörfler 108641281cf3SAxel Dörfler BView* view; 108741281cf3SAxel Dörfler if (byIndex) { 108841281cf3SAxel Dörfler if (fShelf->ReplicantAt(target, &view, (uint32*)id)) { 1089e4d65fe7SJohn Scipione if (view != NULL) { 109041281cf3SAxel Dörfler *index = target; 1091e4d65fe7SJohn Scipione 109241281cf3SAxel Dörfler return view; 109341281cf3SAxel Dörfler } 109441281cf3SAxel Dörfler } 109541281cf3SAxel Dörfler } else { 109632b0035aSJohn Scipione int32 count = ReplicantCount() - 1; 109741281cf3SAxel Dörfler int32 localid; 109841281cf3SAxel Dörfler for (int32 repIndex = count; repIndex >= 0; repIndex--) { 109941281cf3SAxel Dörfler fShelf->ReplicantAt(repIndex, &view, (uint32*)&localid); 1100e4d65fe7SJohn Scipione if (localid == target && view != NULL) { 110141281cf3SAxel Dörfler *index = repIndex; 110241281cf3SAxel Dörfler *id = localid; 1103e4d65fe7SJohn Scipione 110441281cf3SAxel Dörfler return view; 110541281cf3SAxel Dörfler } 110641281cf3SAxel Dörfler } 110741281cf3SAxel Dörfler } 1108e4d65fe7SJohn Scipione 110941281cf3SAxel Dörfler return NULL; 111041281cf3SAxel Dörfler } 111141281cf3SAxel Dörfler 111241281cf3SAxel Dörfler 11137da06231SAxel Dörfler /** looking for a replicant with a view by name 11147da06231SAxel Dörfler * return the view, index and the id of the replicant 11157da06231SAxel Dörfler */ 11167da06231SAxel Dörfler 111741281cf3SAxel Dörfler BView* 111841281cf3SAxel Dörfler TReplicantTray::ViewAt(int32* index, int32* id, const char* name) 111941281cf3SAxel Dörfler { 112041281cf3SAxel Dörfler *index = -1; 112141281cf3SAxel Dörfler *id = -1; 112241281cf3SAxel Dörfler 112341281cf3SAxel Dörfler BView* view; 112432b0035aSJohn Scipione int32 count = ReplicantCount() - 1; 112541281cf3SAxel Dörfler for (int32 repIndex = count; repIndex >= 0; repIndex--) { 112641281cf3SAxel Dörfler fShelf->ReplicantAt(repIndex, &view, (uint32*)id); 11273641948fSJohn Scipione if (view != NULL && view->Name() != NULL 1128e4d65fe7SJohn Scipione && strcmp(name, view->Name()) == 0) { 112941281cf3SAxel Dörfler *index = repIndex; 1130e4d65fe7SJohn Scipione 113141281cf3SAxel Dörfler return view; 113241281cf3SAxel Dörfler } 113341281cf3SAxel Dörfler } 1134e4d65fe7SJohn Scipione 113541281cf3SAxel Dörfler return NULL; 113641281cf3SAxel Dörfler } 113741281cf3SAxel Dörfler 113841281cf3SAxel Dörfler 11397da06231SAxel Dörfler /** Shelf will call to determine where and if 11407da06231SAxel Dörfler * the replicant is to be added 11417da06231SAxel Dörfler */ 11427da06231SAxel Dörfler 114341281cf3SAxel Dörfler bool 114441281cf3SAxel Dörfler TReplicantTray::AcceptAddon(BRect replicantFrame, BMessage* message) 114541281cf3SAxel Dörfler { 1146e4d65fe7SJohn Scipione if (message == NULL) 114741281cf3SAxel Dörfler return false; 114841281cf3SAxel Dörfler 1149efafab64SAxel Dörfler if (replicantFrame.Height() > fMaxReplicantHeight) 115041281cf3SAxel Dörfler return false; 115141281cf3SAxel Dörfler 115241281cf3SAxel Dörfler alignment align = B_ALIGN_LEFT; 115341281cf3SAxel Dörfler if (fAlignmentSupport && message->HasBool("deskbar:dynamic_align")) { 1154f9b3a3b1SJohn Scipione if (!fBarView->Vertical() && !fBarView->MiniState()) 115541281cf3SAxel Dörfler align = B_ALIGN_RIGHT; 115641281cf3SAxel Dörfler else 115741281cf3SAxel Dörfler align = fBarView->Left() ? B_ALIGN_LEFT : B_ALIGN_RIGHT; 115841281cf3SAxel Dörfler } else if (message->HasInt32("deskbar:align")) 115941281cf3SAxel Dörfler message->FindInt32("deskbar:align", (int32*)&align); 116041281cf3SAxel Dörfler 116141281cf3SAxel Dörfler if (message->HasInt32("deskbar:private_align")) 116241281cf3SAxel Dörfler message->FindInt32("deskbar:private_align", (int32*)&align); 116341281cf3SAxel Dörfler else 116441281cf3SAxel Dörfler align = B_ALIGN_LEFT; 116541281cf3SAxel Dörfler 116632b0035aSJohn Scipione BPoint loc = LocationForReplicant(ReplicantCount(), 11677da06231SAxel Dörfler replicantFrame.Width()); 116841281cf3SAxel Dörfler message->AddPoint("_pjp_loc", loc); 1169e4d65fe7SJohn Scipione 117041281cf3SAxel Dörfler return true; 117141281cf3SAxel Dörfler } 117241281cf3SAxel Dörfler 117341281cf3SAxel Dörfler 117441281cf3SAxel Dörfler /** based on the previous (index - 1) replicant in the list 117541281cf3SAxel Dörfler * calculate where the left point should be for this 117641281cf3SAxel Dörfler * replicant. replicant will flow to the right on its own 117741281cf3SAxel Dörfler */ 117841281cf3SAxel Dörfler 117941281cf3SAxel Dörfler BPoint 118032b0035aSJohn Scipione TReplicantTray::LocationForReplicant(int32 index, float replicantWidth) 118141281cf3SAxel Dörfler { 11821be85605SAugustin Cavalier const float trayPadding = ceilf(be_control_look->ComposeSpacing(kTrayPadding) / 2); 11831e0308a8SAugustin Cavalier BPoint loc(trayPadding, 0); 1184f9b3a3b1SJohn Scipione if (fBarView->Vertical() || fBarView->MiniState()) { 1185f9b3a3b1SJohn Scipione if (fBarView->Vertical() && !fBarView->Left()) 11869f4bb0f5SAugustin Cavalier loc.x += gDragWidth; // move past dragger on left 1187f9b3a3b1SJohn Scipione 1188f9b3a3b1SJohn Scipione loc.y = floorf((fBarView->TabHeight() - fMaxReplicantHeight) / 2) - 1; 11890d2645e4SJohn Scipione } else { 11900d2645e4SJohn Scipione loc.x -= 2; // keeps everything lined up nicely 11910d2645e4SJohn Scipione const int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); 11920d2645e4SJohn Scipione float yOffset = iconSize > B_MINI_ICON ? 3 : 2; 11930d2645e4SJohn Scipione // squeeze icons in there at 16x16, reduce border by 1px 1194f9b3a3b1SJohn Scipione 11950d2645e4SJohn Scipione if (fBarView->Top()) { 11960d2645e4SJohn Scipione // align top 11970d2645e4SJohn Scipione loc.y = yOffset; 11980d2645e4SJohn Scipione } else { 11990d2645e4SJohn Scipione // align bottom 12000d2645e4SJohn Scipione loc.y = (fBarView->TeamMenuItemHeight() + 1) 12010d2645e4SJohn Scipione - fMaxReplicantHeight - yOffset; 12020d2645e4SJohn Scipione } 12030d2645e4SJohn Scipione } 120441281cf3SAxel Dörfler 1205f9b3a3b1SJohn Scipione // move clock vertically centered in first row next to replicants 12061e0308a8SAugustin Cavalier fTime->MoveTo(Bounds().right - fTime->Bounds().Width() - trayPadding, 1207f9b3a3b1SJohn Scipione loc.y + floorf((fMaxReplicantHeight - fTime->fHeight) / 2)); 1208f9b3a3b1SJohn Scipione 1209f9b3a3b1SJohn Scipione if (fBarView->Vertical()) { 12107da06231SAxel Dörfler // try to find free space in every row 12119f4bb0f5SAugustin Cavalier for (int32 row = 0; ; loc.y += fMaxReplicantHeight + sIconGap, row++) { 12127da06231SAxel Dörfler // determine free space in this row 1213a44504a1SJohn Scipione BRect rowRect(loc.x, loc.y, 12149f4bb0f5SAugustin Cavalier loc.x + Bounds().Width() - trayPadding, 1215efafab64SAxel Dörfler loc.y + fMaxReplicantHeight); 12161c765f5bSJohn Scipione if (row == 0 && !fTime->IsHidden(fTime)) 1217bc08a7d6SJohn Scipione rowRect.right -= kClockMargin + fTime->Frame().Width(); 12187da06231SAxel Dörfler 1219a44504a1SJohn Scipione BRect replicantRect = rowRect; 12207da06231SAxel Dörfler for (int32 i = 0; i < index; i++) { 12217da06231SAxel Dörfler BView* view = NULL; 12227da06231SAxel Dörfler fShelf->ReplicantAt(i, &view); 1223a44504a1SJohn Scipione if (view == NULL || view->Frame().top != rowRect.top) 12247da06231SAxel Dörfler continue; 12257da06231SAxel Dörfler 1226a44504a1SJohn Scipione // push this replicant placement past the last one 12279f4bb0f5SAugustin Cavalier replicantRect.left = view->Frame().right + sIconGap + 1; 12287da06231SAxel Dörfler } 12297da06231SAxel Dörfler 123015eb397eSJohn Scipione // calculated left position, add replicantWidth to get the 123115eb397eSJohn Scipione // right position 1232bc08a7d6SJohn Scipione replicantRect.right = replicantRect.left + replicantWidth; 1233bc08a7d6SJohn Scipione 1234bc08a7d6SJohn Scipione // check if replicant fits in this row 1235bc08a7d6SJohn Scipione if (replicantRect.right < rowRect.right) { 1236bc08a7d6SJohn Scipione // replicant fits in this row 1237a44504a1SJohn Scipione loc = replicantRect.LeftTop(); 12387da06231SAxel Dörfler break; 12397da06231SAxel Dörfler } 1240bc08a7d6SJohn Scipione 1241bc08a7d6SJohn Scipione // check next row 12427da06231SAxel Dörfler } 124315eb397eSJohn Scipione } else { 1244f9b3a3b1SJohn Scipione // horizontal 124515eb397eSJohn Scipione if (index > 0) { 124641281cf3SAxel Dörfler // get the last replicant added for placement reference 124741281cf3SAxel Dörfler BView* view = NULL; 12487da06231SAxel Dörfler fShelf->ReplicantAt(index - 1, &view); 1249e4d65fe7SJohn Scipione if (view != NULL) { 1250a44504a1SJohn Scipione // push this replicant placement past the last one 12519f4bb0f5SAugustin Cavalier loc.x = view->Frame().right + sIconGap + 1; 125241281cf3SAxel Dörfler } 125341281cf3SAxel Dörfler } 125415eb397eSJohn Scipione } 125515eb397eSJohn Scipione 1256e4d65fe7SJohn Scipione if (loc.y > fRightBottomReplicant.top 1257e4d65fe7SJohn Scipione || (loc.y == fRightBottomReplicant.top 1258e4d65fe7SJohn Scipione && loc.x > fRightBottomReplicant.left)) { 1259a44504a1SJohn Scipione fRightBottomReplicant.Set(loc.x, loc.y, loc.x + replicantWidth, 1260efafab64SAxel Dörfler loc.y + fMaxReplicantHeight); 12617da06231SAxel Dörfler fLastReplicant = index; 126241281cf3SAxel Dörfler } 12637da06231SAxel Dörfler 126441281cf3SAxel Dörfler return loc; 126541281cf3SAxel Dörfler } 126641281cf3SAxel Dörfler 126741281cf3SAxel Dörfler 126841281cf3SAxel Dörfler BRect 126941281cf3SAxel Dörfler TReplicantTray::IconFrame(int32 target, bool byIndex) 127041281cf3SAxel Dörfler { 1271378aa08bSJohn Scipione int32 index; 1272378aa08bSJohn Scipione int32 id; 127341281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, target, byIndex); 127441281cf3SAxel Dörfler 1275378aa08bSJohn Scipione return view != NULL ? view->Frame() : BRect(0, 0, 0, 0); 127641281cf3SAxel Dörfler } 127741281cf3SAxel Dörfler 127841281cf3SAxel Dörfler 127941281cf3SAxel Dörfler BRect 128041281cf3SAxel Dörfler TReplicantTray::IconFrame(const char* name) 128141281cf3SAxel Dörfler { 1282e4d65fe7SJohn Scipione if (name == NULL) 128341281cf3SAxel Dörfler return BRect(0, 0, 0, 0); 128441281cf3SAxel Dörfler 1285378aa08bSJohn Scipione int32 index; 1286378aa08bSJohn Scipione int32 id; 128741281cf3SAxel Dörfler BView* view = ViewAt(&index, &id, name); 128841281cf3SAxel Dörfler 1289378aa08bSJohn Scipione return view != NULL ? view->Frame() : BRect(0, 0, 0, 0); 129041281cf3SAxel Dörfler } 129141281cf3SAxel Dörfler 129241281cf3SAxel Dörfler 12937da06231SAxel Dörfler /** Scan from the startIndex and reset the location 12947da06231SAxel Dörfler * as defined in LocationForReplicant() 129541281cf3SAxel Dörfler */ 129641281cf3SAxel Dörfler 129741281cf3SAxel Dörfler void 129841281cf3SAxel Dörfler TReplicantTray::RealignReplicants(int32 startIndex) 129941281cf3SAxel Dörfler { 130041281cf3SAxel Dörfler if (startIndex < 0) 130141281cf3SAxel Dörfler startIndex = 0; 130241281cf3SAxel Dörfler 130332b0035aSJohn Scipione int32 replicantCount = ReplicantCount(); 130432b0035aSJohn Scipione if (replicantCount <= 0) 130541281cf3SAxel Dörfler return; 130641281cf3SAxel Dörfler 13077da06231SAxel Dörfler if (startIndex == 0) 13087da06231SAxel Dörfler fRightBottomReplicant.Set(0, 0, 0, 0); 13097da06231SAxel Dörfler 131041281cf3SAxel Dörfler BView* view = NULL; 1311a44504a1SJohn Scipione for (int32 index = startIndex; index < replicantCount; index++) { 1312a44504a1SJohn Scipione fShelf->ReplicantAt(index, &view); 1313a44504a1SJohn Scipione if (view == NULL) 1314a44504a1SJohn Scipione continue; 1315a44504a1SJohn Scipione 1316a44504a1SJohn Scipione float replicantWidth = view->Frame().Width(); 1317a44504a1SJohn Scipione BPoint loc = LocationForReplicant(index, replicantWidth); 13180bec7100SStefano Ceccherini if (view->Frame().LeftTop() != loc) 131941281cf3SAxel Dörfler view->MoveTo(loc); 132041281cf3SAxel Dörfler } 132141281cf3SAxel Dörfler } 132241281cf3SAxel Dörfler 132341281cf3SAxel Dörfler 13248aab28f1SRene Gollent status_t 13257625ce51SRene Gollent TReplicantTray::_SaveSettings() 13267625ce51SRene Gollent { 13277625ce51SRene Gollent status_t result; 13287625ce51SRene Gollent BPath path; 132926ea7066SIngo Weinhold if ((result = GetDeskbarSettingsDirectory(path, true)) == B_OK) { 13307625ce51SRene Gollent path.Append(kReplicantSettingsFile); 13317625ce51SRene Gollent 13327625ce51SRene Gollent BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); 13337625ce51SRene Gollent if ((result = file.InitCheck()) == B_OK) 13347625ce51SRene Gollent result = fAddOnSettings.Flatten(&file); 13357625ce51SRene Gollent } 13367625ce51SRene Gollent 13377625ce51SRene Gollent return result; 13387625ce51SRene Gollent } 13397625ce51SRene Gollent 13407625ce51SRene Gollent 13413cf2d117SJohn Scipione void 13423cf2d117SJohn Scipione TReplicantTray::SaveTimeSettings() 13433cf2d117SJohn Scipione { 13443cf2d117SJohn Scipione if (fTime == NULL) 13453cf2d117SJohn Scipione return; 13463cf2d117SJohn Scipione 134731c0024dSJohn Scipione clock_settings* settings = ((TBarApp*)be_app)->ClockSettings(); 13483cf2d117SJohn Scipione settings->showSeconds = fTime->ShowSeconds(); 13493cf2d117SJohn Scipione settings->showDayOfWeek = fTime->ShowDayOfWeek(); 135031c0024dSJohn Scipione settings->showTimeZone = fTime->ShowTimeZone(); 13513cf2d117SJohn Scipione } 13523cf2d117SJohn Scipione 13533cf2d117SJohn Scipione 13541bb2e623SJohn Scipione // #pragma mark - TDragRegion 135541281cf3SAxel Dörfler 135641281cf3SAxel Dörfler 1357ca9acc20SAxel Dörfler /*! Draggable region that is asynchronous so that dragging does not block 1358ca9acc20SAxel Dörfler other activities. 13597da06231SAxel Dörfler */ 13600d2645e4SJohn Scipione TDragRegion::TDragRegion(TBarView* barView, BView* replicantTray) 1361ca9acc20SAxel Dörfler : 1362ca9acc20SAxel Dörfler BControl(BRect(0, 0, 0, 0), "", "", NULL, B_FOLLOW_NONE, 13630d2645e4SJohn Scipione B_WILL_DRAW | B_DRAW_ON_CHILDREN | B_FRAME_EVENTS), 13640d2645e4SJohn Scipione fBarView(barView), 136532b0035aSJohn Scipione fReplicantTray(replicantTray), 136641281cf3SAxel Dörfler fDragLocation(kAutoPlaceDragRegion) 136741281cf3SAxel Dörfler { 136841281cf3SAxel Dörfler } 136941281cf3SAxel Dörfler 137041281cf3SAxel Dörfler 137141281cf3SAxel Dörfler void 137241281cf3SAxel Dörfler TDragRegion::AttachedToWindow() 137341281cf3SAxel Dörfler { 137441281cf3SAxel Dörfler BView::AttachedToWindow(); 1375e4d65fe7SJohn Scipione 13760d2645e4SJohn Scipione CalculateRegions(); 13770d2645e4SJohn Scipione 1378cb6afcb1SStephan Aßmus if (be_control_look != NULL) 13791bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR, 1.1); 1380cb6afcb1SStephan Aßmus else 138116c10517Slooncraz SetViewUIColor(B_MENU_BACKGROUND_COLOR); 1382e4d65fe7SJohn Scipione 138341281cf3SAxel Dörfler ResizeToPreferred(); 138441281cf3SAxel Dörfler } 138541281cf3SAxel Dörfler 138641281cf3SAxel Dörfler 138741281cf3SAxel Dörfler void 138841281cf3SAxel Dörfler TDragRegion::GetPreferredSize(float* width, float* height) 138941281cf3SAxel Dörfler { 139032b0035aSJohn Scipione fReplicantTray->ResizeToPreferred(); 139132b0035aSJohn Scipione *width = fReplicantTray->Bounds().Width(); 139232b0035aSJohn Scipione *height = fReplicantTray->Bounds().Height(); 139341281cf3SAxel Dörfler 139441281cf3SAxel Dörfler if (fDragLocation != kNoDragRegion) 13959f4bb0f5SAugustin Cavalier *width += gDragWidth + kGutter; 139641281cf3SAxel Dörfler else 139741281cf3SAxel Dörfler *width += 6; 139841281cf3SAxel Dörfler 1399f9b3a3b1SJohn Scipione if (fBarView->Vertical() && !fBarView->MiniState()) 14000d2645e4SJohn Scipione *height += 3; // add a pixel for an extra border on top 14010d2645e4SJohn Scipione else 14020d2645e4SJohn Scipione *height += 2; // all other modes have a 1px border on top and bottom 140341281cf3SAxel Dörfler } 140441281cf3SAxel Dörfler 140541281cf3SAxel Dörfler 140641281cf3SAxel Dörfler void 140770ad5289SJohn Scipione TDragRegion::Draw(BRect updateRect) 140841281cf3SAxel Dörfler { 1409eaa9af99SStephan Aßmus rgb_color menuColor = ViewColor(); 141041281cf3SAxel Dörfler rgb_color hilite = tint_color(menuColor, B_DARKEN_1_TINT); 1411cb6afcb1SStephan Aßmus rgb_color ldark = tint_color(menuColor, 1.02); 1412cb6afcb1SStephan Aßmus rgb_color dark = tint_color(menuColor, B_DARKEN_2_TINT); 141341281cf3SAxel Dörfler 141441281cf3SAxel Dörfler BRect frame(Bounds()); 141541281cf3SAxel Dörfler BeginLineArray(4); 141641281cf3SAxel Dörfler 1417f9b3a3b1SJohn Scipione if (fBarView->Vertical()) { 1418f9b3a3b1SJohn Scipione // vertical expando full or mini state, draw 2 lines at the top 1419cb6afcb1SStephan Aßmus AddLine(frame.LeftTop(), frame.RightTop(), dark); 1420cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left, frame.top + 1), 1421cb6afcb1SStephan Aßmus BPoint(frame.right, frame.top + 1), ldark); 14220d2645e4SJohn Scipione // add hilight along bottom 1423cb6afcb1SStephan Aßmus AddLine(BPoint(frame.left + 1, frame.bottom), 1424cb6afcb1SStephan Aßmus BPoint(frame.right - 1, frame.bottom), hilite); 1425f9b3a3b1SJohn Scipione } else { 14260d2645e4SJohn Scipione // mini-mode or horizontal, draw hilight along top left and bottom 14270d2645e4SJohn Scipione AddLine(frame.LeftTop(), frame.RightTop(), hilite); 14280d2645e4SJohn Scipione AddLine(BPoint(frame.left, frame.top + 1), frame.LeftBottom(), hilite); 14290d2645e4SJohn Scipione if (!fBarView->Vertical()) { 14300d2645e4SJohn Scipione // only draw bottom hilight in horizontal mode 14310d2645e4SJohn Scipione AddLine(BPoint(frame.left + 1, frame.bottom - 3), 14320d2645e4SJohn Scipione BPoint(frame.right - 1, frame.bottom - 3), hilite); 1433cb6afcb1SStephan Aßmus } 143441281cf3SAxel Dörfler } 143541281cf3SAxel Dörfler 143641281cf3SAxel Dörfler EndLineArray(); 143741281cf3SAxel Dörfler } 143841281cf3SAxel Dörfler 143941281cf3SAxel Dörfler 144041281cf3SAxel Dörfler void 14410d2645e4SJohn Scipione TDragRegion::DrawAfterChildren(BRect updateRect) 14420d2645e4SJohn Scipione { 14430d2645e4SJohn Scipione if (fDragLocation != kDontDrawDragRegion || fDragLocation != kNoDragRegion) 14440d2645e4SJohn Scipione DrawDragger(); 14450d2645e4SJohn Scipione } 14460d2645e4SJohn Scipione 14470d2645e4SJohn Scipione 14480d2645e4SJohn Scipione void 14490d2645e4SJohn Scipione TDragRegion::DrawDragger() 145041281cf3SAxel Dörfler { 145141281cf3SAxel Dörfler BRect dragRegion(DragRegion()); 145241281cf3SAxel Dörfler 1453cb6afcb1SStephan Aßmus rgb_color menuColor = ViewColor(); 1454cb6afcb1SStephan Aßmus rgb_color menuHilite = menuColor; 145541281cf3SAxel Dörfler if (IsTracking()) { 14561bb2e623SJohn Scipione // draw drag region highlighted if tracking mouse 1457cb6afcb1SStephan Aßmus menuHilite = tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT); 145841281cf3SAxel Dörfler SetHighColor(menuHilite); 14590d2645e4SJohn Scipione FillRect(dragRegion.InsetByCopy(0, -1)); 14601bb2e623SJohn Scipione } else { 14611bb2e623SJohn Scipione SetHighColor(menuColor); 14620d2645e4SJohn Scipione FillRect(dragRegion.InsetByCopy(0, 1)); 146341281cf3SAxel Dörfler } 14641bb2e623SJohn Scipione 1465cb6afcb1SStephan Aßmus rgb_color vdark = tint_color(menuHilite, B_DARKEN_3_TINT); 1466cb6afcb1SStephan Aßmus rgb_color light = tint_color(menuHilite, B_LIGHTEN_2_TINT); 1467cb6afcb1SStephan Aßmus 14680d2645e4SJohn Scipione rgb_color dark = tint_color(menuHilite, B_DARKEN_2_TINT); 14690d2645e4SJohn Scipione 14700d2645e4SJohn Scipione BeginLineArray(dragRegion.IntegerHeight() + 2); 1471e4d65fe7SJohn Scipione BPoint where; 1472e4d65fe7SJohn Scipione where.x = floorf((dragRegion.left + dragRegion.right) / 2 + 0.5) - 1; 1473e4d65fe7SJohn Scipione where.y = dragRegion.top + 2; 1474cb6afcb1SStephan Aßmus 14750d2645e4SJohn Scipione while (where.y + 1 <= dragRegion.bottom - 2) { 1476e4d65fe7SJohn Scipione AddLine(where, where, vdark); 1477e4d65fe7SJohn Scipione AddLine(where + BPoint(1, 1), where + BPoint(1, 1), light); 147841281cf3SAxel Dörfler 1479e4d65fe7SJohn Scipione where.y += 3; 148041281cf3SAxel Dörfler } 14810d2645e4SJohn Scipione 14820d2645e4SJohn Scipione if (fBarView != NULL && fBarView->Vertical() && fBarView->MiniState() 14830d2645e4SJohn Scipione && !fBarView->Top()) { 14840d2645e4SJohn Scipione // extend bottom border in bottom mini-mode 14850d2645e4SJohn Scipione AddLine(BPoint(dragRegion.left, dragRegion.bottom - 2), 14860d2645e4SJohn Scipione BPoint(dragRegion.right, dragRegion.bottom - 2), 14870d2645e4SJohn Scipione IsTracking() ? menuHilite : dark); 14880d2645e4SJohn Scipione } 14890d2645e4SJohn Scipione 149041281cf3SAxel Dörfler EndLineArray(); 149141281cf3SAxel Dörfler } 149241281cf3SAxel Dörfler 149341281cf3SAxel Dörfler 149441281cf3SAxel Dörfler BRect 149541281cf3SAxel Dörfler TDragRegion::DragRegion() const 149641281cf3SAxel Dörfler { 149741281cf3SAxel Dörfler BRect dragRegion(Bounds()); 149841281cf3SAxel Dörfler 149941281cf3SAxel Dörfler bool placeOnLeft = false; 150041281cf3SAxel Dörfler if (fDragLocation == kAutoPlaceDragRegion) { 1501f9b3a3b1SJohn Scipione placeOnLeft = fBarView->Left() 1502f9b3a3b1SJohn Scipione && (fBarView->Vertical() || fBarView->MiniState()); 15031bb2e623SJohn Scipione } else 15041bb2e623SJohn Scipione placeOnLeft = fDragLocation == kDragRegionLeft; 150541281cf3SAxel Dörfler 15060d2645e4SJohn Scipione if (placeOnLeft) 15079f4bb0f5SAugustin Cavalier dragRegion.right = dragRegion.left + gDragWidth; 15080d2645e4SJohn Scipione else 15099f4bb0f5SAugustin Cavalier dragRegion.left = dragRegion.right - gDragWidth; 151041281cf3SAxel Dörfler 151141281cf3SAxel Dörfler return dragRegion; 151241281cf3SAxel Dörfler } 151341281cf3SAxel Dörfler 151441281cf3SAxel Dörfler 151541281cf3SAxel Dörfler void 1516e4d65fe7SJohn Scipione TDragRegion::MouseDown(BPoint where) 151741281cf3SAxel Dörfler { 1518e9632898SAlex Smith uint32 buttons; 1519e4d65fe7SJohn Scipione BPoint mouseLoc; 152041281cf3SAxel Dörfler 1521e4d65fe7SJohn Scipione BRect dragRegion(DragRegion()); 15221bb2e623SJohn Scipione dragRegion.InsetBy(-2, -2); 15237da06231SAxel Dörfler // DragRegion() is designed for drawing, not clicking 152441281cf3SAxel Dörfler 1525e4d65fe7SJohn Scipione if (!dragRegion.Contains(where)) 152641281cf3SAxel Dörfler return; 152741281cf3SAxel Dörfler 152841281cf3SAxel Dörfler while (true) { 1529e4d65fe7SJohn Scipione GetMouse(&mouseLoc, &buttons); 1530e4d65fe7SJohn Scipione if (buttons == 0) 153141281cf3SAxel Dörfler break; 153241281cf3SAxel Dörfler 153341281cf3SAxel Dörfler if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) != 0) { 1534e4d65fe7SJohn Scipione fPreviousPosition = where; 153541281cf3SAxel Dörfler SetTracking(true); 153641281cf3SAxel Dörfler SetMouseEventMask(B_POINTER_EVENTS, 153741281cf3SAxel Dörfler B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); 153841281cf3SAxel Dörfler Invalidate(DragRegion()); 153941281cf3SAxel Dörfler break; 154041281cf3SAxel Dörfler } 154141281cf3SAxel Dörfler 154241281cf3SAxel Dörfler snooze(25000); 154341281cf3SAxel Dörfler } 154441281cf3SAxel Dörfler } 154541281cf3SAxel Dörfler 154641281cf3SAxel Dörfler 154741281cf3SAxel Dörfler void 1548e4d65fe7SJohn Scipione TDragRegion::MouseUp(BPoint where) 154941281cf3SAxel Dörfler { 155041281cf3SAxel Dörfler if (IsTracking()) { 155141281cf3SAxel Dörfler SetTracking(false); 155241281cf3SAxel Dörfler Invalidate(DragRegion()); 155341281cf3SAxel Dörfler } else 1554e4d65fe7SJohn Scipione BControl::MouseUp(where); 155541281cf3SAxel Dörfler } 155641281cf3SAxel Dörfler 155741281cf3SAxel Dörfler 155841281cf3SAxel Dörfler bool 15590d2645e4SJohn Scipione TDragRegion::SwitchModeForRegion(BPoint where, BRegion region, 156041281cf3SAxel Dörfler bool newVertical, bool newLeft, bool newTop, int32 newState) 156141281cf3SAxel Dörfler { 15620d2645e4SJohn Scipione if (!region.Contains(where)) { 15630d2645e4SJohn Scipione // not our region 156441281cf3SAxel Dörfler return false; 15651ad8c760SFredrik Holmqvist } 156641281cf3SAxel Dörfler 15671ad8c760SFredrik Holmqvist if (newVertical == fBarView->Vertical() && newLeft == fBarView->Left() 15681ad8c760SFredrik Holmqvist && newTop == fBarView->Top() && newState == fBarView->State()) { 156941281cf3SAxel Dörfler // already in the correct mode 157041281cf3SAxel Dörfler return true; 15711ad8c760SFredrik Holmqvist } 157241281cf3SAxel Dörfler 1573d7ed9414SRene Gollent fBarView->ChangeState(newState, newVertical, newLeft, newTop, true); 1574e4d65fe7SJohn Scipione 157541281cf3SAxel Dörfler return true; 157641281cf3SAxel Dörfler } 157741281cf3SAxel Dörfler 157841281cf3SAxel Dörfler 1579216bcf7aSJohn Scipione //! Deskbar regions 1580216bcf7aSJohn Scipione // 1581216bcf7aSJohn Scipione // ┌───────3──────────┬─────────────────────────────────┬──────────3───────┐ 1582216bcf7aSJohn Scipione // ├────────────────┬─┘ └─┬────────────────┤ 1583216bcf7aSJohn Scipione // │ 2 │ │ 2 │ 1584216bcf7aSJohn Scipione // ├────────────────┤ ├────────────────┤ 1585216bcf7aSJohn Scipione // │ │ │ │ 1586216bcf7aSJohn Scipione // │ │ │ │ 1587216bcf7aSJohn Scipione // │ │ 4 │ │ 1588216bcf7aSJohn Scipione // │ │ │ │ 1589216bcf7aSJohn Scipione // │ │ │ │ 1590216bcf7aSJohn Scipione // │ 1 │ │ 1 │ 1591216bcf7aSJohn Scipione // │ │ │ │ 1592216bcf7aSJohn Scipione // │ │ │ │ 1593216bcf7aSJohn Scipione // │ ├─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┤ │ 1594216bcf7aSJohn Scipione // │ │ │ │ 1595216bcf7aSJohn Scipione // │ │ │ │ 1596216bcf7aSJohn Scipione // │ │ │ │ 1597216bcf7aSJohn Scipione // ├────────────────┘ └────────────────┤ 1598216bcf7aSJohn Scipione // │ │ 1599216bcf7aSJohn Scipione // │ 4 │ 1600216bcf7aSJohn Scipione // │ │ 1601216bcf7aSJohn Scipione // │ │ 1602216bcf7aSJohn Scipione // ├────────────────┐ ┌────────────────┤ 1603216bcf7aSJohn Scipione // │ 2 │ │ 2 │ 1604216bcf7aSJohn Scipione // ├────────────────┴─┐ ┌─┴────────────────┤ 1605216bcf7aSJohn Scipione // └───────3──────────┴─────────────────────────────────┴──────────3───────┘ 1606216bcf7aSJohn Scipione // 1607216bcf7aSJohn Scipione // 1. Vertical expando-mode, right (default) or left 1608216bcf7aSJohn Scipione // 2. Vertical mini-mode, right-top left-top left-bottom or right-bottom 1609216bcf7aSJohn Scipione // 3. Horizontal mini-mode, right-top left-top left-bottom or right-bottom 1610216bcf7aSJohn Scipione // 4. Horizontal expando-mode top or bottom 1611216bcf7aSJohn Scipione 161241281cf3SAxel Dörfler void 16130d2645e4SJohn Scipione TDragRegion::CalculateRegions() 161441281cf3SAxel Dörfler { 16150d2645e4SJohn Scipione const BRect screenFrame((BScreen(Window())).Frame()); 161641281cf3SAxel Dörfler 16170d2645e4SJohn Scipione float menuBarHeight = fBarView->BarMenuBar()->Frame().Height(); 16180d2645e4SJohn Scipione float hDivider = floorf(screenFrame.Width() / 4); 16190d2645e4SJohn Scipione float halfScreen = floorf(screenFrame.Height() / 2); 16200d2645e4SJohn Scipione 16210d2645e4SJohn Scipione // corners 1622f9b3a3b1SJohn Scipione fTopLeftVertical.Set(BRect(screenFrame.left, 1623f9b3a3b1SJohn Scipione screenFrame.top + menuBarHeight, screenFrame.left + hDivider, 1624f9b3a3b1SJohn Scipione screenFrame.top + floorf(menuBarHeight * kVerticalMiniMultiplier))); 1625f9b3a3b1SJohn Scipione fTopRightVertical.Set(BRect(screenFrame.right - hDivider, 1626f9b3a3b1SJohn Scipione screenFrame.top + menuBarHeight, screenFrame.right, 1627f9b3a3b1SJohn Scipione screenFrame.top + floorf(menuBarHeight * kVerticalMiniMultiplier))); 1628f9b3a3b1SJohn Scipione fBottomLeftVertical.Set(BRect(screenFrame.left, 1629f9b3a3b1SJohn Scipione screenFrame.bottom - floorf(menuBarHeight * kVerticalMiniMultiplier), 1630f9b3a3b1SJohn Scipione screenFrame.left + hDivider, screenFrame.bottom - menuBarHeight)); 1631f9b3a3b1SJohn Scipione fBottomRightVertical.Set(BRect(screenFrame.right - hDivider, 1632f9b3a3b1SJohn Scipione screenFrame.bottom - floorf(menuBarHeight * kVerticalMiniMultiplier), 1633f9b3a3b1SJohn Scipione screenFrame.right, screenFrame.bottom - menuBarHeight)); 1634f9b3a3b1SJohn Scipione 1635f9b3a3b1SJohn Scipione fTopLeftHorizontal.Set(BRect(screenFrame.left, screenFrame.top, 16360d2645e4SJohn Scipione screenFrame.left + hDivider, screenFrame.top + menuBarHeight)); 1637f9b3a3b1SJohn Scipione fTopRightHorizontal.Set(BRect(screenFrame.right - hDivider, screenFrame.top, 16380d2645e4SJohn Scipione screenFrame.right, screenFrame.top + menuBarHeight)); 1639f9b3a3b1SJohn Scipione fBottomLeftHorizontal.Set(BRect(screenFrame.left, screenFrame.bottom - menuBarHeight, 16400d2645e4SJohn Scipione screenFrame.left + hDivider, screenFrame.bottom)); 1641f9b3a3b1SJohn Scipione fBottomRightHorizontal.Set(BRect(screenFrame.right - hDivider, 16420d2645e4SJohn Scipione screenFrame.bottom - menuBarHeight, screenFrame.right, 16430d2645e4SJohn Scipione screenFrame.bottom)); 16440d2645e4SJohn Scipione 16450d2645e4SJohn Scipione // left/right expando 16460d2645e4SJohn Scipione fMiddleLeft.Set(BRect(screenFrame.left, screenFrame.top, 16470d2645e4SJohn Scipione screenFrame.left + hDivider, screenFrame.bottom)); 1648f9b3a3b1SJohn Scipione fMiddleLeft.Exclude(&fTopLeftHorizontal); 1649f9b3a3b1SJohn Scipione fMiddleLeft.Exclude(&fBottomLeftHorizontal); 1650f9b3a3b1SJohn Scipione fMiddleLeft.Exclude(&fTopLeftVertical); 1651f9b3a3b1SJohn Scipione fMiddleLeft.Exclude(&fBottomLeftVertical); 16520d2645e4SJohn Scipione 16530d2645e4SJohn Scipione fMiddleRight.Set(BRect(screenFrame.right - hDivider, 16540d2645e4SJohn Scipione screenFrame.top, screenFrame.right, screenFrame.bottom)); 1655f9b3a3b1SJohn Scipione fMiddleRight.Exclude(&fTopRightHorizontal); 1656f9b3a3b1SJohn Scipione fMiddleRight.Exclude(&fBottomRightHorizontal); 1657f9b3a3b1SJohn Scipione fMiddleRight.Exclude(&fTopRightVertical); 1658f9b3a3b1SJohn Scipione fMiddleRight.Exclude(&fBottomRightVertical); 165941281cf3SAxel Dörfler 166041281cf3SAxel Dörfler #ifdef FULL_MODE 16610d2645e4SJohn Scipione // left/right full 16620d2645e4SJohn Scipione fLeftSide.Set(BRect(screenFrame.left, screenFrame.bottom - halfScreen, 16630d2645e4SJohn Scipione screenFrame.left + hDivider, screenFrame.bottom)); 1664f9b3a3b1SJohn Scipione fLeftSide.Exclude(&fBottomLeftHorizontal); 1665f9b3a3b1SJohn Scipione fLeftSide.Exclude(&fBottomLeftVertical); 16660d2645e4SJohn Scipione fMiddleLeft.Exclude(&fLeftSide); 16670d2645e4SJohn Scipione 16680d2645e4SJohn Scipione fRightSide.Set(BRect(screenFrame.right - hDivider, 16690d2645e4SJohn Scipione screenFrame.bottom - halfScreen, screenFrame.right, 16700d2645e4SJohn Scipione screenFrame.bottom)); 1671f9b3a3b1SJohn Scipione fRightSide.Exclude(&fBottomRightHorizontal); 1672f9b3a3b1SJohn Scipione fRightSide.Exclude(&fBottomRightVertical); 16730d2645e4SJohn Scipione fMiddleRight.Exclude(&fRightSide); 167441281cf3SAxel Dörfler #endif 167541281cf3SAxel Dörfler 16760d2645e4SJohn Scipione // top/bottom 16770d2645e4SJohn Scipione BRect leftSideRect(screenFrame.left, screenFrame.top, 16780d2645e4SJohn Scipione screenFrame.left + hDivider, screenFrame.bottom); 16790d2645e4SJohn Scipione BRect rightSideRect(screenFrame.right - hDivider, screenFrame.top, 16800d2645e4SJohn Scipione screenFrame.right, screenFrame.bottom); 168141281cf3SAxel Dörfler 16820d2645e4SJohn Scipione fTopHalf.Set(BRect(screenFrame.left, screenFrame.top, screenFrame.right, 16830d2645e4SJohn Scipione screenFrame.top + halfScreen)); 16840d2645e4SJohn Scipione fTopHalf.Exclude(leftSideRect); 16850d2645e4SJohn Scipione fTopHalf.Exclude(rightSideRect); 168641281cf3SAxel Dörfler 16870d2645e4SJohn Scipione fBottomHalf.Set(BRect(screenFrame.left, screenFrame.bottom - halfScreen, 16880d2645e4SJohn Scipione screenFrame.right, screenFrame.bottom)); 16890d2645e4SJohn Scipione fBottomHalf.Exclude(leftSideRect); 16900d2645e4SJohn Scipione fBottomHalf.Exclude(rightSideRect); 16910d2645e4SJohn Scipione } 16920d2645e4SJohn Scipione 16930d2645e4SJohn Scipione 16940d2645e4SJohn Scipione void 16950d2645e4SJohn Scipione TDragRegion::MouseMoved(BPoint where, uint32 transit, 16960d2645e4SJohn Scipione const BMessage* dragMessage) 16970d2645e4SJohn Scipione { 16980d2645e4SJohn Scipione if (!IsTracking() || where == fPreviousPosition) 16990d2645e4SJohn Scipione return BControl::MouseMoved(where, transit, dragMessage); 17000d2645e4SJohn Scipione 170141281cf3SAxel Dörfler fPreviousPosition = where; 17020d2645e4SJohn Scipione 17030d2645e4SJohn Scipione // TODO: can't trust the passed in where param, get screen_where from 17040d2645e4SJohn Scipione // Window()->CurrentMessage() instead, why is this necessary? 17050d2645e4SJohn Scipione BPoint whereScreen; 17060d2645e4SJohn Scipione BMessage* currentMessage = Window()->CurrentMessage(); 17070d2645e4SJohn Scipione if (currentMessage == NULL || currentMessage->FindPoint("screen_where", 17080d2645e4SJohn Scipione &whereScreen) != B_OK) { 17090d2645e4SJohn Scipione whereScreen = ConvertToScreen(where); 17100d2645e4SJohn Scipione } 171141281cf3SAxel Dörfler 171241281cf3SAxel Dörfler // use short circuit evaluation for convenience 1713f9b3a3b1SJohn Scipione if (// vertical mini 1714f9b3a3b1SJohn Scipione SwitchModeForRegion(whereScreen, fTopLeftVertical, true, 1715f9b3a3b1SJohn Scipione true, true, kMiniState) 1716f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fTopRightVertical, true, 1717f9b3a3b1SJohn Scipione false, true, kMiniState) 1718f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fBottomLeftVertical, true, 1719f9b3a3b1SJohn Scipione true, false, kMiniState) 1720f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fBottomRightVertical, true, 1721f9b3a3b1SJohn Scipione false, false, kMiniState) 1722f9b3a3b1SJohn Scipione // horizontal mini 1723f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fTopLeftHorizontal, false, 1724f9b3a3b1SJohn Scipione true, true, kMiniState) 1725f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fTopRightHorizontal, false, 1726f9b3a3b1SJohn Scipione false, true, kMiniState) 1727f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fBottomLeftHorizontal, false, 1728f9b3a3b1SJohn Scipione true, false, kMiniState) 1729f9b3a3b1SJohn Scipione || SwitchModeForRegion(whereScreen, fBottomRightHorizontal, false, 1730f9b3a3b1SJohn Scipione false, false, kMiniState) 17310d2645e4SJohn Scipione // expando 17320d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fMiddleLeft, true, true, true, 173371bd3ba5SJonas Sundström kExpandoState) 17340d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fMiddleRight, true, false, true, 173571bd3ba5SJonas Sundström kExpandoState) 173641281cf3SAxel Dörfler #ifdef FULL_MODE 17370d2645e4SJohn Scipione // full 17380d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fLeftSide, true, true, true, 173971bd3ba5SJonas Sundström kFullState) 17400d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fRightSide, true, false, true, 174171bd3ba5SJonas Sundström kFullState) 174241281cf3SAxel Dörfler #endif 17430d2645e4SJohn Scipione // horizontal 17440d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fTopHalf, false, true, true, 174571bd3ba5SJonas Sundström kExpandoState) 17460d2645e4SJohn Scipione || SwitchModeForRegion(whereScreen, fBottomHalf, false, true, false, 17470d2645e4SJohn Scipione kExpandoState) 17480d2645e4SJohn Scipione ); 174941281cf3SAxel Dörfler } 175041281cf3SAxel Dörfler 175141281cf3SAxel Dörfler 175241281cf3SAxel Dörfler int32 175341281cf3SAxel Dörfler TDragRegion::DragRegionLocation() const 175441281cf3SAxel Dörfler { 175541281cf3SAxel Dörfler return fDragLocation; 175641281cf3SAxel Dörfler } 175741281cf3SAxel Dörfler 175841281cf3SAxel Dörfler 175941281cf3SAxel Dörfler void 176041281cf3SAxel Dörfler TDragRegion::SetDragRegionLocation(int32 location) 176141281cf3SAxel Dörfler { 176241281cf3SAxel Dörfler if (location == fDragLocation) 176341281cf3SAxel Dörfler return; 176441281cf3SAxel Dörfler 176541281cf3SAxel Dörfler fDragLocation = location; 176641281cf3SAxel Dörfler Invalidate(); 176741281cf3SAxel Dörfler } 17681bb2e623SJohn Scipione 17691bb2e623SJohn Scipione 17701bb2e623SJohn Scipione // #pragma mark - TResizeControl 17711bb2e623SJohn Scipione 17721bb2e623SJohn Scipione 17731bb2e623SJohn Scipione /*! Draggable region that is asynchronous so that resizing does not block. 17741bb2e623SJohn Scipione */ 17751bb2e623SJohn Scipione TResizeControl::TResizeControl(TBarView* barView) 17761bb2e623SJohn Scipione : 17779f4bb0f5SAugustin Cavalier BControl(BRect(0, gDragWidth, 0, kMenuBarHeight), "", "", NULL, 17781bb2e623SJohn Scipione B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS), 17791bb2e623SJohn Scipione fBarView(barView) 17801bb2e623SJohn Scipione { 17811bb2e623SJohn Scipione } 17821bb2e623SJohn Scipione 17831bb2e623SJohn Scipione 17841bb2e623SJohn Scipione TResizeControl::~TResizeControl() 17851bb2e623SJohn Scipione { 17861bb2e623SJohn Scipione } 17871bb2e623SJohn Scipione 17881bb2e623SJohn Scipione 17891bb2e623SJohn Scipione void 17901bb2e623SJohn Scipione TResizeControl::AttachedToWindow() 17911bb2e623SJohn Scipione { 17921bb2e623SJohn Scipione BView::AttachedToWindow(); 17931bb2e623SJohn Scipione 17941bb2e623SJohn Scipione if (be_control_look != NULL) 17951bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR, 1.1); 17961bb2e623SJohn Scipione else 17971bb2e623SJohn Scipione SetViewUIColor(B_MENU_BACKGROUND_COLOR); 17981bb2e623SJohn Scipione } 17991bb2e623SJohn Scipione 18001bb2e623SJohn Scipione 18011bb2e623SJohn Scipione void 18021bb2e623SJohn Scipione TResizeControl::Draw(BRect updateRect) 18031bb2e623SJohn Scipione { 18041bb2e623SJohn Scipione if (!fBarView->Vertical()) 18051bb2e623SJohn Scipione return; 18061bb2e623SJohn Scipione 1807092e918bSJohn Scipione BRect dragRegion(Bounds()); 18081bb2e623SJohn Scipione 180900171c6fSJohn Scipione int32 height = dragRegion.IntegerHeight(); 181000171c6fSJohn Scipione if (height <= 0) 181100171c6fSJohn Scipione return; 181200171c6fSJohn Scipione 18131bb2e623SJohn Scipione rgb_color menuColor = ViewColor(); 18141bb2e623SJohn Scipione rgb_color menuHilite = menuColor; 18151bb2e623SJohn Scipione if (IsTracking()) { 18161bb2e623SJohn Scipione // draw drag region highlighted if tracking mouse 18171bb2e623SJohn Scipione menuHilite = tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT); 18181bb2e623SJohn Scipione SetHighColor(menuHilite); 18191bb2e623SJohn Scipione FillRect(dragRegion); 18201bb2e623SJohn Scipione } else { 18211bb2e623SJohn Scipione SetHighColor(menuColor); 18221bb2e623SJohn Scipione FillRect(dragRegion); 18231bb2e623SJohn Scipione } 18241bb2e623SJohn Scipione 18251bb2e623SJohn Scipione rgb_color vdark = tint_color(menuHilite, B_DARKEN_3_TINT); 18261bb2e623SJohn Scipione rgb_color light = tint_color(menuHilite, B_LIGHTEN_2_TINT); 18271bb2e623SJohn Scipione 182800171c6fSJohn Scipione BeginLineArray(height); 18291bb2e623SJohn Scipione BPoint where; 18301bb2e623SJohn Scipione where.x = floorf((dragRegion.left + dragRegion.right) / 2 + 0.5) - 1; 18311bb2e623SJohn Scipione where.y = dragRegion.top + 2; 18321bb2e623SJohn Scipione 18331bb2e623SJohn Scipione while (where.y + 1 <= dragRegion.bottom) { 18341bb2e623SJohn Scipione AddLine(where, where, vdark); 18351bb2e623SJohn Scipione AddLine(where + BPoint(1, 1), where + BPoint(1, 1), light); 18361bb2e623SJohn Scipione 18371bb2e623SJohn Scipione where.y += 3; 18381bb2e623SJohn Scipione } 18391bb2e623SJohn Scipione EndLineArray(); 18401bb2e623SJohn Scipione } 18411bb2e623SJohn Scipione 18421bb2e623SJohn Scipione 18431bb2e623SJohn Scipione void 18441bb2e623SJohn Scipione TResizeControl::MouseDown(BPoint where) 18451bb2e623SJohn Scipione { 18461bb2e623SJohn Scipione uint32 buttons; 18471bb2e623SJohn Scipione BPoint mouseLoc; 18481bb2e623SJohn Scipione 18491bb2e623SJohn Scipione while (true) { 18501bb2e623SJohn Scipione GetMouse(&mouseLoc, &buttons); 18511bb2e623SJohn Scipione if (buttons == 0) 18521bb2e623SJohn Scipione break; 18531bb2e623SJohn Scipione 18541bb2e623SJohn Scipione if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) != 0) { 18551bb2e623SJohn Scipione SetTracking(true); 18561bb2e623SJohn Scipione SetMouseEventMask(B_POINTER_EVENTS, 18571bb2e623SJohn Scipione B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); 18581bb2e623SJohn Scipione Invalidate(); 18591bb2e623SJohn Scipione break; 18601bb2e623SJohn Scipione } 18611bb2e623SJohn Scipione 18621bb2e623SJohn Scipione snooze(25000); 18631bb2e623SJohn Scipione } 18641bb2e623SJohn Scipione } 18651bb2e623SJohn Scipione 18661bb2e623SJohn Scipione 18671bb2e623SJohn Scipione void 18681bb2e623SJohn Scipione TResizeControl::MouseUp(BPoint where) 18691bb2e623SJohn Scipione { 18701bb2e623SJohn Scipione if (IsTracking()) { 18711bb2e623SJohn Scipione SetTracking(false); 18721bb2e623SJohn Scipione Invalidate(); 18731bb2e623SJohn Scipione } else 18741bb2e623SJohn Scipione BControl::MouseUp(where); 18751bb2e623SJohn Scipione } 18761bb2e623SJohn Scipione 18771bb2e623SJohn Scipione 18781bb2e623SJohn Scipione void 18791bb2e623SJohn Scipione TResizeControl::MouseMoved(BPoint where, uint32 code, 18801bb2e623SJohn Scipione const BMessage* dragMessage) 18811bb2e623SJohn Scipione { 1882f9b3a3b1SJohn Scipione if (!fBarView->Vertical() || !IsResizing()) 1883f9b3a3b1SJohn Scipione return BControl::MouseMoved(where, code, dragMessage); 1884f9b3a3b1SJohn Scipione 18851bb2e623SJohn Scipione float windowWidth = Window()->Frame().Width(); 18861bb2e623SJohn Scipione float delta = 0; 18871bb2e623SJohn Scipione BPoint whereScreen = ConvertToScreen(where); 18881bb2e623SJohn Scipione 18891bb2e623SJohn Scipione if (fBarView->Left()) { 18901bb2e623SJohn Scipione delta = whereScreen.x - Window()->Frame().right; 18911bb2e623SJohn Scipione if (delta > 0 && windowWidth >= gMaximumWindowWidth) 18921bb2e623SJohn Scipione ; // do nothing 18931bb2e623SJohn Scipione else if (delta < 0 && windowWidth <= gMinimumWindowWidth) 18941bb2e623SJohn Scipione ; // do nothing 18951bb2e623SJohn Scipione else 18961bb2e623SJohn Scipione Window()->ResizeBy(delta, 0); 18971bb2e623SJohn Scipione } else { 18981bb2e623SJohn Scipione delta = Window()->Frame().left - whereScreen.x; 18991bb2e623SJohn Scipione if (delta > 0 && windowWidth >= gMaximumWindowWidth) 19001bb2e623SJohn Scipione ; // do nothing 19011bb2e623SJohn Scipione else if (delta < 0 && windowWidth <= gMinimumWindowWidth) 19021bb2e623SJohn Scipione ; // do nothing 19031bb2e623SJohn Scipione else { 19041bb2e623SJohn Scipione Window()->MoveBy(delta, 0); 19051bb2e623SJohn Scipione Window()->ResizeBy(delta, 0); 19061bb2e623SJohn Scipione } 19071bb2e623SJohn Scipione } 19081bb2e623SJohn Scipione 19091bb2e623SJohn Scipione windowWidth = Window()->Frame().Width(); 19101bb2e623SJohn Scipione 19111bb2e623SJohn Scipione BControl::MouseMoved(where, code, dragMessage); 19121bb2e623SJohn Scipione } 1913