Author: aldeck Date: 2011-07-31 03:41:45 +0200 (Sun, 31 Jul 2011) New Revision: 42518 Changeset: https://dev.haiku-os.org/changeset/42518 Modified: haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.cpp haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.h haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/PoseViewController.cpp haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/TitleView.cpp Log: * Use templating for DefaultAttributeMenu so that the same code can be used for both BMenu and BPopUpMenu version of the same menu while still keeping a BMenu inheritance. Modified: haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.cpp =================================================================== --- haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.cpp 2011-07-30 19:51:28 UTC (rev 42517) +++ haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.cpp 2011-07-31 01:41:45 UTC (rev 42518) @@ -595,14 +595,36 @@ // #pragma mark - DefaultAttributeMenu +// We use templates since we need two versions of the same code, one regular BMenu based for the +// main menu bar, and one BPopUpMenu based for the context menu on column headers. Only the +// inherited class and constructor changes depending on the template<class MenuType>. -DefaultAttributeMenu::DefaultAttributeMenu(PoseViewController* controller) +template<> +DefaultAttributeMenu<BPopUpMenu>::DefaultAttributeMenu(PoseViewController* controller) : BPopUpMenu(B_TRANSLATE("Attributes"), false, false), fController(controller) { - BPoseView* poseView = controller->PoseView(); + _Init(); +} + +template<> +DefaultAttributeMenu<BMenu>::DefaultAttributeMenu(PoseViewController* controller) + : + BMenu(B_TRANSLATE("Attributes")), + fController(controller) +{ + _Init(); +} + + +template<class MenuType> +void +DefaultAttributeMenu<MenuType>::_Init() +{ + BPoseView* poseView = fController->PoseView(); + BMenuItem *item; AddItem(item = new BMenuItem(B_TRANSLATE("Copy layout"), new BMessage(kCopyAttributes))); @@ -654,8 +676,9 @@ } +template<class MenuType> void -DefaultAttributeMenu::MimeTypesChanged() +DefaultAttributeMenu<MenuType>::MimeTypesChanged() { BPoseView* poseView = fController->PoseView(); @@ -748,15 +771,17 @@ } +template<class MenuType> void -DefaultAttributeMenu::ColumnsChanged() +DefaultAttributeMenu<MenuType>::ColumnsChanged() { _MarkItems(); } +template<class MenuType> void -DefaultAttributeMenu::_MarkItems() +DefaultAttributeMenu<MenuType>::_MarkItems() { int32 count = CountItems(); for (int32 index = 0; index < count; index++) { @@ -788,8 +813,9 @@ } +template<class MenuType> BMenuItem * -DefaultAttributeMenu::_NewItem(const char *label, const char *name, +DefaultAttributeMenu<MenuType>::_NewItem(const char *label, const char *name, int32 type, float width, int32 align, bool editable, bool statField) { return _NewItem(label, name, type, NULL, width, align, @@ -797,8 +823,9 @@ } +template<class MenuType> BMenuItem * -DefaultAttributeMenu::_NewItem(const char *label, const char *name, +DefaultAttributeMenu<MenuType>::_NewItem(const char *label, const char *name, int32 type, const char* displayAs, float width, int32 align, bool editable, bool statField) { @@ -823,12 +850,13 @@ /*! Adds a menu for a specific MIME type if it doesn't exist already. Returns the menu, if it existed or not. */ +template<class MenuType> BMenu* -DefaultAttributeMenu::_AddMimeMenu(const BMimeType& mimeType, bool isSuperType, - BMenu* menu, int32 start) +DefaultAttributeMenu<MenuType>::_AddMimeMenu(const BMimeType& mimeType, + bool isSuperType, BMenu* menu, int32 start) { AutoLock<BLooper> _(menu->Looper()); - + if (!mimeType.IsValid()) return NULL; @@ -921,7 +949,7 @@ OpenWithMenu::OpenWithMenu(const char *label, PoseViewController* controller) - : + : BSlowMenu(label), fIterator(NULL), fSupportingAppList(NULL), @@ -975,7 +1003,7 @@ // check if only item in selection list is the root // and do not add if true - // build a list of all refs to open + // build a list of all refs to open BMessage message(B_REFS_RECEIVED); message.AddMessenger("TrackerViewToken", BMessenger(fController->PoseView())); for (int32 index = 0; index < count; index++) { @@ -999,7 +1027,7 @@ OpenWithMenu::SelectionChanged() { // TODO asynchronous rebuild - + if (Superitem() != NULL) { int32 count = fController->PoseView()->SelectionList()->CountItems(); Superitem()->SetEnabled(count > 0); Modified: haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.h =================================================================== --- haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.h 2011-07-30 19:51:28 UTC (rev 42517) +++ haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/DefaultControls.h 2011-07-31 01:41:45 UTC (rev 42518) @@ -81,15 +81,18 @@ }; -class DefaultAttributeMenu : public BPopUpMenu, public PoseViewListener { +template <class MenuType> +class DefaultAttributeMenu : public MenuType, public PoseViewListener { public: DefaultAttributeMenu(PoseViewController* controller); + virtual void TargetModelChanged() {}; virtual void SelectionChanged() {}; virtual void MimeTypesChanged(); virtual void ColumnsChanged(); protected: + void _Init(); void _MarkItems(); BMenuItem* _NewItem(const char *label, @@ -111,7 +114,7 @@ public: OpenWithMenu(const char* label, PoseViewController* controller); - + virtual void AttachedToWindow(); virtual void TargetModelChanged(); virtual void SelectionChanged(); Modified: haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/PoseViewController.cpp =================================================================== --- haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/PoseViewController.cpp 2011-07-30 19:51:28 UTC (rev 42517) +++ haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/PoseViewController.cpp 2011-07-31 01:41:45 UTC (rev 42518) @@ -112,7 +112,7 @@ fWindowMenu = new DefaultWindowMenu(this); - DefaultAttributeMenu* attributesMenu = new DefaultAttributeMenu(this); + DefaultAttributeMenu<BMenu>* attributesMenu = new DefaultAttributeMenu<BMenu>(this); fPoseView->AddListener(attributesMenu); fAttributesMenu = attributesMenu; @@ -137,9 +137,9 @@ menu = new DefaultMoveMenu(B_TRANSLATE("Create link"), kCreateLink, this); fPoseView->AddListener(menu); fCreateLinkMenu = menu; - + OpenWithMenu* openWithMenu = new OpenWithMenu( - B_TRANSLATE("Open with" B_UTF8_ELLIPSIS), this); + B_TRANSLATE("Open with" B_UTF8_ELLIPSIS), this); fPoseView->AddListener(openWithMenu); fOpenWithMenu = openWithMenu; } @@ -172,7 +172,7 @@ { // Insert the 'Move to' 'Copy to' and 'Create link' menus // just below the 'Move to trash' item - + int32 index = 0; if (newParent != NULL) { BMenuItem* trash = newParent->FindItem(kMoveToTrash); @@ -183,8 +183,8 @@ newParent = NULL; // will detach the menu } } - + if (!ReparentMenu(fMoveToMenu, newParent, index++) || !ReparentMenu(fCopyToMenu, newParent, index++) || !ReparentMenu(fCreateLinkMenu, newParent, index)) { @@ -199,9 +199,9 @@ fCopyToMenu->Superitem()->SetMessage(new BMessage(kCopySelectionTo)); if (fCreateLinkMenu != NULL && fCreateLinkMenu->Superitem() != NULL) fCreateLinkMenu->Superitem()->SetMessage(new BMessage(kCreateLink)); - + // Insert 'Open With...' menu just below the 'Open' item. - + index = 0; if (newParent != NULL) { BMenuItem* openItem = newParent->FindItem(kOpenSelection); @@ -212,7 +212,7 @@ newParent = NULL; // will detach the menu } } - + if (!ReparentMenu(fOpenWithMenu, newParent, index)) printf("PoseViewController::ReparentSharedMenus Error reparenting 'Open with' menu!\n"); else if (fOpenWithMenu != NULL && fOpenWithMenu->Superitem() != NULL) { Modified: haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/TitleView.cpp =================================================================== --- haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/TitleView.cpp 2011-07-30 19:51:28 UTC (rev 42517) +++ haiku/branches/developer/aldeck/tracker_layout/src/kits/tracker/TitleView.cpp 2011-07-31 01:41:45 UTC (rev 42518) @@ -99,7 +99,7 @@ BTitleView::BTitleView(BPoseView *poseView) - : + : BView("TitleView", B_WILL_DRAW), fPoseView(poseView), fTitleList(10, true), @@ -109,7 +109,7 @@ { SetExplicitMaxSize(BSize(B_SIZE_UNSET, 16)); SetExplicitMinSize(BSize(0, 16)); - + sTitleBackground = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 0.88f); // 216 -> 220 sDarkTitleBackground = tint_color(sTitleBackground, B_DARKEN_1_TINT); sShineColor = tint_color(sTitleBackground, B_LIGHTEN_MAX_TINT); @@ -199,7 +199,7 @@ } -void +void BTitleView::Draw(BRect /*updateRect*/, bool useOffscreen, bool updateOnly, const BColumnTitle *pressedColumn, void (*trackRectBlitter)(BView *, BRect), BRect passThru) @@ -236,7 +236,7 @@ // fill background with light gray background if (!updateOnly) view->FillRect(bounds, B_SOLID_LOW); - + view->BeginLineArray(4); view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShadowColor); view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sShadowColor); @@ -315,8 +315,8 @@ // if so, display the attribute menu: if (buttons & B_SECONDARY_MOUSE_BUTTON) { - DefaultAttributeMenu* menu = - new DefaultAttributeMenu(fPoseView->Controller()); + DefaultAttributeMenu<BPopUpMenu>* menu = + new DefaultAttributeMenu<BPopUpMenu>(fPoseView->Controller()); menu->MimeTypesChanged(); menu->Go(ConvertToScreen(where), true, false); return; @@ -386,7 +386,7 @@ else SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); break; - + case B_EXITED_VIEW: SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); break; @@ -448,7 +448,7 @@ } -bool +bool BColumnTitle::InColumnResizeArea(BPoint where) const { BRect edge(Bounds()); @@ -529,10 +529,10 @@ triangle[1] = center + BPoint(3.5, -1.5); triangle[2] = center + BPoint(0.0, 2.0); } - + uint32 flags = view->Flags(); view->SetFlags(flags | B_SUBPIXEL_PRECISE); - + if (secondary) { view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.3)); view->FillTriangle(triangle[0], triangle[1], triangle[2]); @@ -540,7 +540,7 @@ view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.6)); view->FillTriangle(triangle[0], triangle[1], triangle[2]); } - + view->SetFlags(flags); } @@ -555,12 +555,12 @@ view->BeginLineArray(4); // draw lighter gray and white inset lines - rect.InsetBy(1, 1); + rect.InsetBy(1, 1); view->AddLine(rect.LeftBottom(), rect.RightBottom(), pressed ? sLightShadowColor : sLightShadowColor); view->AddLine(rect.LeftTop(), rect.RightTop(), pressed ? sDarkShadowColor : sShineColor); - + view->AddLine(rect.LeftTop(), rect.LeftBottom(), pressed ? sDarkShadowColor : sShineColor); view->AddLine(rect.RightTop(), rect.RightBottom(), @@ -589,9 +589,9 @@ void ColumnTrackState::MouseUp(BPoint where) { - // if it is pressed shortly and not moved, it is a click + // if it is pressed shortly and not moved, it is a click // all else is a track - if (system_time() <= fPastClickTime && !fHasMoved) + if (system_time() <= fPastClickTime && !fHasMoved) Clicked(where); else Done(where); @@ -644,12 +644,12 @@ float newWidth = where.x + fInitialTrackOffset - fTitle->fColumn->Offset(); if (newWidth < kMinColumnWidth) newWidth = kMinColumnWidth; - + BPoseView *poseView = fTitleView->PoseView(); // bool shrink = (newWidth < fTitle->fColumn->Width()); - // resize the column + // resize the column poseView->ResizeColumn(fTitle->fColumn, newWidth, &fLastLineDrawPos, _DrawLine, _UndrawLine); @@ -657,7 +657,7 @@ bounds.left = fTitle->fColumn->Offset(); // force title redraw - fTitleView->Draw(bounds, true, false); + fTitleView->Draw(bounds, true, false); } @@ -749,7 +749,7 @@ BColumn *column = BColumn::InstantiateFromStream(&fColumnArchive); ASSERT(column); const BColumn *after = NULL; - if (overTitle) + if (overTitle) after = overTitle->Column(); fTitleView->PoseView()->AddColumn(column, after); fTrackingRemovedColumn = false; @@ -761,7 +761,7 @@ if (!inMarginRect) { // dragged a title out of the hysteresis margin around the // title bar - remove it and start dragging it as a dotted outline - + BRect rect(fTitle->Bounds()); rect.OffsetBy(where.x - fInitialMouseTrackOffset, where.y - 5); fColumnArchive.Seek(0, SEEK_SET); @@ -779,7 +779,7 @@ // over the one to the right || where.x < overTitle->Bounds().left + fTitle->Bounds().Width())){ // over the one to the left, far enough to not snap right back - + BColumn *column = fTitle->Column(); fInitialMouseTrackOffset -= fTitle->Bounds().left; // swap the columns @@ -792,7 +792,7 @@ } else drawOutline = true; } - + if (drawOutline) DrawOutline(where.x - fInitialMouseTrackOffset); else if (undrawOutline) @@ -817,7 +817,7 @@ uint32 primarySort = poseView->PrimarySort(); uint32 secondarySort = poseView->SecondarySort(); bool shift = (modifiers() & B_SHIFT_KEY) != 0; - + // For now: // if we hit the primary sort field again // then if shift key was down, switch primary and secondary @@ -871,7 +871,7 @@ } -void +void ColumnDragState::UndrawOutline() { fTitleView->Draw(fTitleView->Bounds(), true, false);