From 4900de3f9555139fc3522e9a575ae804950b02cc Mon Sep 17 00:00:00 2001 From: Freaxed Date: Tue, 10 Dec 2024 15:34:43 +0100 Subject: [PATCH 01/29] first lite version of GenioTabView --- .genio | Bin 785 -> 789 bytes Makefile | 2 + src/helpers/gtab/GTab.cpp | 29 +++ src/helpers/gtab/GTab.h | 30 +++ src/helpers/gtab/GenioTabView.cpp | 368 ++++++++++++++++++++++++++++++ src/helpers/gtab/GenioTabView.h | 52 +++++ src/ui/GenioWindow.cpp | 12 +- src/ui/GenioWindow.h | 10 +- src/ui/ProblemsPanel.cpp | 11 +- src/ui/ProblemsPanel.h | 6 +- src/ui/SearchResultPanel.cpp | 11 +- src/ui/SearchResultPanel.h | 6 +- src/ui/SearchResultTab.cpp | 2 +- src/ui/SearchResultTab.h | 6 +- 14 files changed, 510 insertions(+), 35 deletions(-) create mode 100644 src/helpers/gtab/GTab.cpp create mode 100644 src/helpers/gtab/GTab.h create mode 100644 src/helpers/gtab/GenioTabView.cpp create mode 100644 src/helpers/gtab/GenioTabView.h diff --git a/.genio b/.genio index d4d610d46188d009a5038ee3a70f43c321ceb2a7..22b293b6c342487b4541d04863aa1e05fcfc5f5f 100644 GIT binary patch delta 225 zcmbQpHkECHitI*41_mAm1_o9jW(MN_K)?c|L4a+dqrM~)kip0xzz`G?>HaBhW@Ju&gLtRt(6`ovh0!&NySTE29E`QfX#RN_<*oPHKEXVoAp2 M2aIByOBst90m|DbDgXcg delta 242 zcmbQrHj!K)?*7L4b9lqrM~?kip0x#}E_}>WdHyG diff --git a/Makefile b/Makefile index 8f34051b..c328c4af 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,8 @@ SRCS += src/helpers/tabview/CircleColorMenuItem.cpp SRCS += src/helpers/tabview/TabContainerView.cpp SRCS += src/helpers/tabview/TabManager.cpp SRCS += src/helpers/tabview/TabView.cpp +SRCS += src/helpers/gtab/GenioTabView.cpp +SRCS += src/helpers/gtab/GTab.cpp SRCS += src/lsp-client/CallTipContext.cpp SRCS += src/lsp-client/LSPEditorWrapper.cpp SRCS += src/lsp-client/LSPProjectWrapper.cpp diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp new file mode 100644 index 00000000..e9726b5d --- /dev/null +++ b/src/helpers/gtab/GTab.cpp @@ -0,0 +1,29 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ + + +#include "GTab.h" + +#include + + + +GTabContainer::GTabContainer(BView* view):BBox(view->Name()),fView(view) +{ + SetBorder(B_NO_BORDER); + SetLayout(new BGroupLayout(B_VERTICAL)); + if (fView) + AddChild(fView); +} + + +GTab::GTab(BView* view):BTab(),fGTabContainer(nullptr) +{ + fGTabContainer = new GTabContainer(view); + SetView(fGTabContainer); +} + + + diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h new file mode 100644 index 00000000..585aa07f --- /dev/null +++ b/src/helpers/gtab/GTab.h @@ -0,0 +1,30 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include + +class GenioTabView; + +class GTabContainer : public BBox { +public: + GTabContainer(BView* view); + BView* ContentView() { return fView;} +private: + BView* fView; +}; + +class GTab : public BTab { +protected: +friend GenioTabView; + GTab(BView* view); +private: + GTabContainer* fGTabContainer; +}; + + diff --git a/src/helpers/gtab/GenioTabView.cpp b/src/helpers/gtab/GenioTabView.cpp new file mode 100644 index 00000000..69565e02 --- /dev/null +++ b/src/helpers/gtab/GenioTabView.cpp @@ -0,0 +1,368 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ + + +#include "GenioTabView.h" + +#include +#include +#include + +class IndexGTab : public GTab { +public: + IndexGTab(BView* view, int32 index):GTab(view), fIndex(index){} + int32 fIndex; +}; + +BTab* +GenioTabView::_TabFromPoint(BPoint where, int32& index) +{ + index = _TabAt(where); + if (index < 0) + return nullptr; + return TabAt(index); +} + + +int32 +GenioTabView::_TabAt(BPoint where) +{ + for (int32 i = 0; i < CountTabs(); i++) { + if (TabFrame(i).Contains(where)) + return i; + } + return -1; +} + +#define TAB_DRAG 'TDRA' +#define ALPHA 230 + +#include +#include + + +bool +GenioTabView::InitiateDrag(BPoint where) +{ + uint32 index = _TabAt(where); + if (index < 0) + return false; + + BRect frame(TabFrame(index)); + BTab* tab = TabAt(index); + if (tab != nullptr) { + BMessage message(TAB_DRAG); + + message.AddPointer("genio_tab_view", this); + message.AddUInt32("tab_drag_affinity", fTabAffinity); + message.AddInt32("index", index); + + BRect updateRect = frame.OffsetToCopy(BPoint(0, 0)); + + BBitmap* dragBitmap = new BBitmap(updateRect, B_RGB32, true); + if (dragBitmap->IsValid()) { + BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); + dragBitmap->AddChild(view); + dragBitmap->Lock(); + tab->DrawTab(view, updateRect, B_TAB_FRONT, true); + + view->Sync(); + uint8* bits = (uint8*)dragBitmap->Bits(); + int32 height = (int32)dragBitmap->Bounds().Height() + 1; + int32 width = (int32)dragBitmap->Bounds().Width() + 1; + int32 bpr = dragBitmap->BytesPerRow(); + for (int32 y = 0; y < height; y++, bits += bpr) { + uint8* line = bits + 3; + for (uint8* end = line + 4 * width; line < end; line += 4) + *line = ALPHA; + } + dragBitmap->Unlock(); + } else { + delete dragBitmap; + dragBitmap = NULL; + } + + if (dragBitmap != NULL) { + DragMessage(&message, dragBitmap, B_OP_ALPHA, + BPoint(where.x - frame.left, where.y - frame.top)); + } else { + DragMessage(&message, frame, this); + } + + return true; + } + return false; +} + + +GenioTabView::GenioTabView(const char* name, tab_drag_affinity affinity): + BTabView(name), + fTabAffinity(affinity) +{ +} + + +void +GenioTabView::MouseDown(BPoint where) +{ + BTabView::MouseDown(where); + OnMouseDown(where); +} + + +void +GenioTabView::MouseUp(BPoint where) +{ + BTabView::MouseUp(where); + OnMouseUp(where); + if (fDropTargetHighlightFrame.IsValid()) { + Invalidate(fDropTargetHighlightFrame); + fDropTargetHighlightFrame = BRect(); + } +} + + +void +GenioTabView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) +{ + bool sameTabView = true; + if (dragMessage && + dragMessage->what == TAB_DRAG && + _ValidDragAndDrop(dragMessage, &sameTabView)) { + switch (transit) { + case B_ENTERED_VIEW: + case B_INSIDE_VIEW: + { + int32 fromIndex = dragMessage->GetInt32("index", -1); + int32 toIndex = _TabAt(where); + if (toIndex >= 0) { + if (fromIndex != toIndex || sameTabView == false) { + BRect highlightFrame = TabFrame(toIndex); + + if (fDropTargetHighlightFrame != highlightFrame) { + Invalidate(fDropTargetHighlightFrame); + fDropTargetHighlightFrame = highlightFrame; + Invalidate(fDropTargetHighlightFrame); + } + return; + } + } else { + float right = 0; + if (CountTabs() > 0) { + right = TabFrame(CountTabs()-1).right; + } + if (where.x < right) + return; + + BRect highlightFrame = Bounds(); + highlightFrame.left = right; + + if (fDropTargetHighlightFrame != highlightFrame) { + Invalidate(fDropTargetHighlightFrame); + fDropTargetHighlightFrame = highlightFrame; + Invalidate(fDropTargetHighlightFrame); + } + return; + } + } break; + default: + if (fDropTargetHighlightFrame.IsValid()) { + Invalidate(fDropTargetHighlightFrame); + fDropTargetHighlightFrame = BRect(); + } + break; + }; + } else { + BTabView::MouseMoved(where, transit, dragMessage); + OnMouseMoved(where); + if (fDropTargetHighlightFrame.IsValid()) { + Invalidate(fDropTargetHighlightFrame); + fDropTargetHighlightFrame = BRect(); + } + } +} + + +void +GenioTabView::MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView) +{ + GTabContainer* fromContainer = dynamic_cast(fromTabView->BTabView::ViewForTab(from)); + if (fromContainer == nullptr) + return; + + BView* fromView = fromContainer->ContentView(); + if (!fromView) + return; + + fromView->RemoveSelf(); + + BTab* fromTab = fromTabView->TabAt(from); + BString label = fromTab->Label(); //TODO copy all the props + fromTabView->RemoveTab(from); + GTab* indexTab = new IndexGTab(fromView, to); + indexTab->SetLabel(label.String()); + AddTab(indexTab); +} + +void +GenioTabView::AddTab(BView* target, BTab* tab) +{ + BTabView::AddTab(target, tab); +} + + +void +BTabView::AddTab(BView* target, BTab* tab) +{ + if (tab == NULL) + tab = new BTab(target); + else + tab->SetView(target); + + IndexGTab *gtab = dynamic_cast(tab); + int32 index = CountTabs(); + if (gtab != nullptr) { + if (gtab->fIndex < CountTabs()) + index = gtab->fIndex; + } +// printf("New Index to: %d\n", index); + if (fContainerView->GetLayout()) + fContainerView->GetLayout()->AddView(index, target); + fTabList->AddItem(tab, index); + + BTab::Private(tab).SetTabView(this); + + // When we haven't had a any tabs before, but are already attached to the + // window, select this one. + if (Window() != NULL) { + if (CountTabs() == 1) + Select(0); + else { + Select(index); + + // make the view visible through the layout if there is one + BCardLayout* layout + = dynamic_cast(fContainerView->GetLayout()); + if (layout != NULL) + layout->SetVisibleItem(index); + } + } +} + +void +GenioTabView::AddTab(BView* target) +{ + AddTab(new GTab(target)); +} + + +BTab* +GenioTabView::TabFromView(BView* view) const +{ + for (int32 i = 0; i < CountTabs(); i++) { + GTabContainer* fromContainer = dynamic_cast(BTabView::ViewForTab(i)); + if (fromContainer != nullptr && fromContainer->ContentView() == view) { + return TabAt(i); + } + } + return nullptr; +} + + +void +GenioTabView::AddTab(GTab* tab) +{ + BTabView::AddTab(tab->View(), tab); +} + + +void +GenioTabView::_OnDrop(BMessage* msg) +{ + int32 dragIndex = msg->GetInt32("index", -1); + if (dragIndex < 0) + return; + + if (!_ValidDragAndDrop(msg)) + return; + + BPoint drop_point; + if (msg->FindPoint("_drop_point_", &drop_point) != B_OK) + return; + + int32 toIndex = _TabAt(ConvertFromScreen(drop_point)); + if (CountTabs() == 0) + toIndex = 0; + + if (toIndex < 0) { + if (drop_point.x < TabFrame(CountTabs()-1).right) + return; + toIndex = CountTabs(); + } + + GenioTabView* fromTabView = (GenioTabView*)msg->GetPointer("genio_tab_view", this); + + MoveTabs(dragIndex, toIndex, fromTabView); + Invalidate(); + if (fromTabView != this) + fromTabView->Invalidate(); +} + + +void +GenioTabView::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case TAB_DRAG: + { + _OnDrop(msg); + } break; + default: + BTabView::MessageReceived(msg); + break; + }; +} +/* +void +GenioTabView::AddTab(BView* target, BTab* tab) +{ + BTabView::AddTab(target, tab); +} +*/ +BRect +GenioTabView::DrawTabs() +{ + BRect rect = BTabView::DrawTabs(); + _DrawTabIndicator(); + return rect; +} + + +void +GenioTabView::_DrawTabIndicator() +{ + if (fDropTargetHighlightFrame.IsValid()) { + rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); + color.alpha = 170; + SetHighColor(color); + SetDrawingMode(B_OP_ALPHA); + FillRect(fDropTargetHighlightFrame); + } +} + +bool +GenioTabView::_ValidDragAndDrop(const BMessage* msg, bool* sameTabView) +{ + if (sameTabView) + *sameTabView = (msg->GetPointer("genio_tab_view", nullptr) == this); + + if (fTabAffinity == 0 && msg->GetPointer("genio_tab_view", nullptr) != this) + return false; + + if (msg->GetUInt32("tab_drag_affinity", 0) != fTabAffinity) + return false; + + return true; +} \ No newline at end of file diff --git a/src/helpers/gtab/GenioTabView.h b/src/helpers/gtab/GenioTabView.h new file mode 100644 index 00000000..4c6d11e2 --- /dev/null +++ b/src/helpers/gtab/GenioTabView.h @@ -0,0 +1,52 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include +#include "GTab.h" + +#include "Draggable.h" + +typedef uint32 tab_drag_affinity; + +class GenioTabView : public BTabView, private Draggable { +public: + GenioTabView(const char* name, tab_drag_affinity affinity); + + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void MessageReceived(BMessage* msg); + + void AddTab(BView* target); + + BTab* TabFromView(BView* view) const; + +private: + + BView* ViewForTab(int32 tabIndex) const = delete; + void AddTab(GTab* tab); + virtual void AddTab(BView* target, BTab* tab); + virtual BRect DrawTabs(); + void MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView); + bool InitiateDrag(BPoint where); + void _OnDrop(BMessage* msg); + + int32 _TabAt(BPoint where); + BTab* _TabFromPoint(BPoint where, int32& index); + void _DrawTabIndicator(); + bool _ValidDragAndDrop(const BMessage* msg, bool* sameTabView = nullptr); + + + BRect fDropTargetHighlightFrame; + tab_drag_affinity fTabAffinity; + +}; + + diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index e9c93550..25916d7f 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -273,7 +273,7 @@ GenioWindow::Show() BWindow::Show(); if (LockLooper()) { - _ShowView(fProjectsTabView, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowView((BView*)fProjectsTabView, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); _ShowView(fRightTabView, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); _ShowView(fOutputTabView, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); _ShowView(fToolBar, gCFG["show_toolbar"], MSG_TOGGLE_TOOLBAR); @@ -3399,7 +3399,7 @@ void GenioWindow::_InitOutputSplit() { // Output - fOutputTabView = new BTabView("OutputTabview"); + fOutputTabView = new GenioTabView("OutputTabview", 'GTAB'); fProblemsPanel = new ProblemsPanel(fOutputTabView); @@ -3420,7 +3420,7 @@ void GenioWindow::_InitLeftSplit() { // Projects View - fProjectsTabView = new BTabView("ProjectsTabview"); + fProjectsTabView = new GenioTabView("ProjectsTabview", 'GTAB'); fProjectsFolderBrowser = new ProjectBrowser(); fProjectsTabView->AddTab(fProjectsFolderBrowser); @@ -3435,7 +3435,7 @@ void GenioWindow::_InitRightSplit() { // Outline view - fRightTabView = new BTabView("OutlineTabview"); + fRightTabView = new GenioTabView("OutlineTabview", 'GTAB'); fFunctionsOutlineView = new FunctionsOutlineView(); fRightTabView->AddTab(fFunctionsOutlineView); } @@ -4159,7 +4159,7 @@ GenioWindow::_RunTarget() {"cmd_type", "build"}, {"banner_claim", claim }}; - fMTermView->MakeFocus(true); + ((BView*)fMTermView)->MakeFocus(true); fMTermView->RunCommand(&message); @@ -4600,4 +4600,4 @@ GenioWindow::_UpdateWindowTitle(const char* filePath) if (gCFG["fullpath_title"] && filePath != nullptr) title << ": " << filePath; SetTitle(title.String()); -} +} \ No newline at end of file diff --git a/src/ui/GenioWindow.h b/src/ui/GenioWindow.h index 7d58a0d9..f59816ca 100644 --- a/src/ui/GenioWindow.h +++ b/src/ui/GenioWindow.h @@ -11,7 +11,7 @@ #include #include "GMessage.h" - +#include "GenioTabView.h" enum { kProblems = 0, @@ -210,9 +210,9 @@ class GenioWindow : public BWindow { // Left panels - BTabView* fProjectsTabView; + GenioTabView* fProjectsTabView; - ProjectBrowser* fProjectsFolderBrowser; + ProjectBrowser* fProjectsFolderBrowser; BScrollView* fProjectsFolderScroll; SourceControlPanel* fSourceControlPanel; @@ -221,7 +221,7 @@ class GenioWindow : public BWindow { ProjectFolder *fActiveProject; // Right panels - BTabView* fRightTabView; + GenioTabView* fRightTabView; FunctionsOutlineView* fFunctionsOutlineView; // Editor group @@ -250,7 +250,7 @@ class GenioWindow : public BWindow { BFilePanel* fImportResourcePanel; // Bottom panels - BTabView* fOutputTabView; + GenioTabView* fOutputTabView; ProblemsPanel* fProblemsPanel; ConsoleIOView* fBuildLogView; MTermView* fMTermView; diff --git a/src/ui/ProblemsPanel.cpp b/src/ui/ProblemsPanel.cpp index a48aa7b3..a29b19ec 100644 --- a/src/ui/ProblemsPanel.cpp +++ b/src/ui/ProblemsPanel.cpp @@ -46,7 +46,7 @@ class RangeRow : public BRow { #define ProblemLabel B_TRANSLATE("Problems") -ProblemsPanel::ProblemsPanel(BTabView* tabView): BColumnListView(ProblemLabel, +ProblemsPanel::ProblemsPanel(GenioTabView* tabView): BColumnListView(ProblemLabel, B_NAVIGABLE, B_FANCY_BORDER, true) , fTabView(tabView) @@ -198,10 +198,7 @@ ProblemsPanel::_UpdateTabLabel() label.Append(")"); } - for (int32 i = 0; i < fTabView->CountTabs(); i++) { - if (fTabView->ViewForTab(i) == this) { - fTabView->TabAt(i)->SetLabel(label.String()); - break; - } - } + BTab* tab = fTabView->TabFromView(this); + if (tab) + tab->SetLabel(label.String()); } diff --git a/src/ui/ProblemsPanel.h b/src/ui/ProblemsPanel.h index e9d7c342..187a4eba 100644 --- a/src/ui/ProblemsPanel.h +++ b/src/ui/ProblemsPanel.h @@ -5,14 +5,14 @@ #pragma once #include - +#include "GenioTabView.h" class BPopUpMenu; class BMenuItem; class BTabView; class Editor; class ProblemsPanel : public BColumnListView { public: - ProblemsPanel(BTabView*); + ProblemsPanel(GenioTabView*); virtual ~ProblemsPanel(); void UpdateProblems(Editor* editor); @@ -24,7 +24,7 @@ class ProblemsPanel : public BColumnListView { private: void _UpdateTabLabel(); - BTabView* fTabView; + GenioTabView* fTabView; BPopUpMenu* fPopUpMenu; BMenuItem* fQuickFixItem; }; diff --git a/src/ui/SearchResultPanel.cpp b/src/ui/SearchResultPanel.cpp index 69a52304..923e4abd 100644 --- a/src/ui/SearchResultPanel.cpp +++ b/src/ui/SearchResultPanel.cpp @@ -67,7 +67,7 @@ class BFontStringColumn : public BStringColumn { #define SearchResultPanelLabel B_TRANSLATE("Search results") -SearchResultPanel::SearchResultPanel(BTabView* tabView) +SearchResultPanel::SearchResultPanel(GenioTabView* tabView) : BColumnListView(SearchResultPanelLabel, B_NAVIGABLE, B_FANCY_BORDER, true), fGrepThread(nullptr), @@ -85,12 +85,9 @@ SearchResultPanel::SetTabLabel(BString label) if (!fTabView) return; - for (int32 i = 0; i < fTabView->CountTabs(); i++) { - if (fTabView->ViewForTab(i) == this->Parent()) { - fTabView->TabAt(i)->SetLabel(label.String()); - break; - } - } + BTab* tab = fTabView->TabFromView(this->Parent()); + if (tab) + tab->SetLabel(label.String()); } diff --git a/src/ui/SearchResultPanel.h b/src/ui/SearchResultPanel.h index b69582e1..ff729742 100644 --- a/src/ui/SearchResultPanel.h +++ b/src/ui/SearchResultPanel.h @@ -7,7 +7,7 @@ #include #include -#include +#include "GenioTabView.h" #include "GrepThread.h" // For now this is specific to manage only the FindInFiles results @@ -15,7 +15,7 @@ class SearchResultPanel : public BColumnListView { public: - SearchResultPanel(BTabView*); + SearchResultPanel(GenioTabView*); void StartSearch(BString command, BString projectPath); @@ -31,7 +31,7 @@ class SearchResultPanel : public BColumnListView { void UpdateSearch(BMessage* msg); GrepThread* fGrepThread; BString fProjectPath; - BTabView* fTabView; + GenioTabView* fTabView; int32 fCountResults; }; diff --git a/src/ui/SearchResultTab.cpp b/src/ui/SearchResultTab.cpp index e89755f9..142baf93 100644 --- a/src/ui/SearchResultTab.cpp +++ b/src/ui/SearchResultTab.cpp @@ -32,7 +32,7 @@ static constexpr auto kFindReplaceMinBytes = 32; static constexpr uint32 kSelectProject ='PRJX'; -SearchResultTab::SearchResultTab(BTabView* tabView) +SearchResultTab::SearchResultTab(GenioTabView* tabView) : BGroupView(B_VERTICAL, 0.0f), fSearchResultPanel(nullptr), diff --git a/src/ui/SearchResultTab.h b/src/ui/SearchResultTab.h index 6031b639..6b65608d 100644 --- a/src/ui/SearchResultTab.h +++ b/src/ui/SearchResultTab.h @@ -6,12 +6,12 @@ #include #include -#include #include #include "OptionList.h" #include "ProjectFolder.h" #include "SearchResultPanel.h" +#include "GenioTabView.h" class ToolBar; @@ -19,7 +19,7 @@ using Genio::UI::OptionList; class SearchResultTab : public BGroupView { public: - SearchResultTab(BTabView*); + SearchResultTab(GenioTabView*); ~SearchResultTab(); void SetAndStartSearch(BString text, bool wholeWord, bool caseSensitive, ProjectFolder* project); void AttachedToWindow(); @@ -32,7 +32,7 @@ class SearchResultTab : public BGroupView { Genio::UI::OptionList* fProjectMenu; SearchResultPanel* fSearchResultPanel; - BTabView* fTabView; + GenioTabView* fTabView; ProjectFolder* fSelectedProject; ToolBar* fFindGroup; BTextControl* fFindTextControl; From 5a5107a62cf06d47f6dad40ede73f604b294dde3 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Tue, 10 Dec 2024 19:12:51 +0100 Subject: [PATCH 02/29] Change the view of a tab according to preferred Group orientation --- src/helpers/gtab/GenioTabView.cpp | 32 +++++++++++++++++++++++++++++-- src/helpers/gtab/GenioTabView.h | 4 +++- src/ui/GenioWindow.cpp | 4 ++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/helpers/gtab/GenioTabView.cpp b/src/helpers/gtab/GenioTabView.cpp index 69565e02..433a851b 100644 --- a/src/helpers/gtab/GenioTabView.cpp +++ b/src/helpers/gtab/GenioTabView.cpp @@ -9,6 +9,7 @@ #include #include #include +#include class IndexGTab : public GTab { public: @@ -97,9 +98,10 @@ GenioTabView::InitiateDrag(BPoint where) } -GenioTabView::GenioTabView(const char* name, tab_drag_affinity affinity): +GenioTabView::GenioTabView(const char* name, tab_drag_affinity affinity, orientation orientation): BTabView(name), - fTabAffinity(affinity) + fTabAffinity(affinity), + fOrientation(orientation) { } @@ -270,10 +272,36 @@ GenioTabView::TabFromView(BView* view) const return nullptr; } +#include +void +GenioTabView::_ChangeGroupViewDirection(GTab* tab) +{ + GTabContainer* fromContainer = dynamic_cast(tab->View()); + if (!fromContainer) + return; + printf("fromContainer\n"); + BGroupView* groupView = dynamic_cast(fromContainer->ContentView()); + if (!groupView) + return; + printf("groupView %s\n", groupView->Name()); + if(!groupView->GroupLayout()) + return; + printf("layout\n"); + if (groupView->GroupLayout()->Orientation() != fOrientation) + { + groupView->GroupLayout()->SetOrientation(fOrientation); + } + + printf("same %d vs %d\n", groupView->GroupLayout()->Orientation(), fOrientation); +} + + void GenioTabView::AddTab(GTab* tab) { + //experimental: let's try to improve the GroupView. + _ChangeGroupViewDirection(tab); BTabView::AddTab(tab->View(), tab); } diff --git a/src/helpers/gtab/GenioTabView.h b/src/helpers/gtab/GenioTabView.h index 4c6d11e2..5309fcc6 100644 --- a/src/helpers/gtab/GenioTabView.h +++ b/src/helpers/gtab/GenioTabView.h @@ -16,7 +16,7 @@ typedef uint32 tab_drag_affinity; class GenioTabView : public BTabView, private Draggable { public: - GenioTabView(const char* name, tab_drag_affinity affinity); + GenioTabView(const char* name, tab_drag_affinity affinity, orientation orientation = B_HORIZONTAL); virtual void MouseDown(BPoint where); virtual void MouseUp(BPoint where); @@ -43,9 +43,11 @@ class GenioTabView : public BTabView, private Draggable { void _DrawTabIndicator(); bool _ValidDragAndDrop(const BMessage* msg, bool* sameTabView = nullptr); + void _ChangeGroupViewDirection(GTab* tab); BRect fDropTargetHighlightFrame; tab_drag_affinity fTabAffinity; + orientation fOrientation; }; diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index 25916d7f..b86d63bb 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -3420,7 +3420,7 @@ void GenioWindow::_InitLeftSplit() { // Projects View - fProjectsTabView = new GenioTabView("ProjectsTabview", 'GTAB'); + fProjectsTabView = new GenioTabView("ProjectsTabview", 'GTAB', B_VERTICAL); fProjectsFolderBrowser = new ProjectBrowser(); fProjectsTabView->AddTab(fProjectsFolderBrowser); @@ -3435,7 +3435,7 @@ void GenioWindow::_InitRightSplit() { // Outline view - fRightTabView = new GenioTabView("OutlineTabview", 'GTAB'); + fRightTabView = new GenioTabView("OutlineTabview", 'GTAB', B_VERTICAL); fFunctionsOutlineView = new FunctionsOutlineView(); fRightTabView->AddTab(fFunctionsOutlineView); } From 395aee9f757614c63af98da3f5f3cabb918b1de6 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Fri, 13 Dec 2024 11:48:00 +0100 Subject: [PATCH 03/29] each tab is referred with a tab_id --- src/config/ConfigManager.cpp | 2 +- src/helpers/gtab/GTab.cpp | 3 +- src/helpers/gtab/GTab.h | 8 ++- src/helpers/gtab/GenioTabView.cpp | 98 ++++++++++++++++++++++++++----- src/helpers/gtab/GenioTabView.h | 26 +++++++- src/ui/GenioWindow.cpp | 67 ++++++++++++++------- src/ui/GenioWindow.h | 10 +--- 7 files changed, 163 insertions(+), 51 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 7bfc2ed1..2d2634ec 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -178,7 +178,7 @@ ConfigManager::~ConfigManager() for (int32 i = 0; i< kStorageTypeCountNb; i++) { delete fPSPList[i]; fPSPList[i] = nullptr; - } + } } diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index e9726b5d..149e38c2 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -19,7 +19,8 @@ GTabContainer::GTabContainer(BView* view):BBox(view->Name()),fView(view) } -GTab::GTab(BView* view):BTab(),fGTabContainer(nullptr) + +GTab::GTab(BView* view, tab_id id):BTab(),fGTabContainer(nullptr),fTabId(id) { fGTabContainer = new GTabContainer(view); SetView(fGTabContainer); diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 585aa07f..928782ab 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -9,11 +9,11 @@ #include #include -class GenioTabView; +#include "GenioTabView.h" class GTabContainer : public BBox { public: - GTabContainer(BView* view); + GTabContainer(BView* view);; BView* ContentView() { return fView;} private: BView* fView; @@ -22,9 +22,11 @@ class GTabContainer : public BBox { class GTab : public BTab { protected: friend GenioTabView; - GTab(BView* view); + GTab(BView* view, tab_id id); + tab_id Id() { return fTabId;} private: GTabContainer* fGTabContainer; + tab_id fTabId; }; diff --git a/src/helpers/gtab/GenioTabView.cpp b/src/helpers/gtab/GenioTabView.cpp index 433a851b..2a4b92df 100644 --- a/src/helpers/gtab/GenioTabView.cpp +++ b/src/helpers/gtab/GenioTabView.cpp @@ -10,10 +10,13 @@ #include #include #include +#include + +#include "GTab.h" class IndexGTab : public GTab { public: - IndexGTab(BView* view, int32 index):GTab(view), fIndex(index){} + IndexGTab(BView* view, int32 index, tab_id id):GTab(view, id), fIndex(index){} int32 fIndex; }; @@ -190,6 +193,10 @@ GenioTabView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessa void GenioTabView::MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView) { + GTab* fromTab = dynamic_cast(fromTabView->TabAt(from)); + if (!fromTab) + return; + GTabContainer* fromContainer = dynamic_cast(fromTabView->BTabView::ViewForTab(from)); if (fromContainer == nullptr) return; @@ -200,12 +207,11 @@ GenioTabView::MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView) fromView->RemoveSelf(); - BTab* fromTab = fromTabView->TabAt(from); BString label = fromTab->Label(); //TODO copy all the props fromTabView->RemoveTab(from); - GTab* indexTab = new IndexGTab(fromView, to); + GTab* indexTab = new IndexGTab(fromView, to, fromTab->Id()); indexTab->SetLabel(label.String()); - AddTab(indexTab); + _AddTab(indexTab); } void @@ -254,9 +260,12 @@ BTabView::AddTab(BView* target, BTab* tab) } void -GenioTabView::AddTab(BView* target) +GenioTabView::AddTab(BView* target, tab_id id) { - AddTab(new GTab(target)); + assert(fTabIdMap.contains(id) == false); + GTab* newTab = new GTab(target, id); + _AddTab(newTab); + } @@ -272,6 +281,30 @@ GenioTabView::TabFromView(BView* view) const return nullptr; } + +void +GenioTabView::SelectTab(tab_id id) +{ + /** DEBUG * + + for(const auto& [k, v] : fTabIdMap) { + printf("TabList: '%.4s' -> %p\n", (char *)&k, v); + }*/ + + if (fTabIdMap.contains(id)) { + BTab* tab = fTabIdMap[id]; + BTabView::Select(BTabView::IndexOf(tab)); + } +} + + +bool +GenioTabView::HasTab(tab_id id) +{ + return fTabIdMap.contains(id); +} + + #include void GenioTabView::_ChangeGroupViewDirection(GTab* tab) @@ -280,29 +313,53 @@ GenioTabView::_ChangeGroupViewDirection(GTab* tab) if (!fromContainer) return; printf("fromContainer\n"); - BGroupView* groupView = dynamic_cast(fromContainer->ContentView()); - if (!groupView) + + BView* view = fromContainer->ContentView(); + if (!view) return; - printf("groupView %s\n", groupView->Name()); - if(!groupView->GroupLayout()) + printf("View\n"); + BLayout* layout = view->GetLayout(); + if (!layout) return; - printf("layout\n"); - if (groupView->GroupLayout()->Orientation() != fOrientation) + printf("Layout\n"); + BGroupLayout* grpLayout = dynamic_cast(layout); + if (!grpLayout) { + return; + } + printf("g layout\n"); + if (grpLayout->Orientation() != fOrientation) { - groupView->GroupLayout()->SetOrientation(fOrientation); + grpLayout->SetOrientation(fOrientation); } - printf("same %d vs %d\n", groupView->GroupLayout()->Orientation(), fOrientation); + printf("same %d vs %d\n", grpLayout->Orientation(), fOrientation); +} + + +BTab* +GenioTabView::RemoveTab(int32 tabIndex) +{ + BTab* tab = BTabView::RemoveTab(tabIndex); + for(const auto& [k, v] : fTabIdMap) { + if (v == tab) { + fTabIdMap.erase(k); + break; + } + } + return tab; } void -GenioTabView::AddTab(GTab* tab) +GenioTabView::_AddTab(GTab* tab) { //experimental: let's try to improve the GroupView. _ChangeGroupViewDirection(tab); + fTabIdMap[tab->Id()] = tab; BTabView::AddTab(tab->View(), tab); + + _PrintMap(); } @@ -393,4 +450,13 @@ GenioTabView::_ValidDragAndDrop(const BMessage* msg, bool* sameTabView) return false; return true; -} \ No newline at end of file +} + + +void +GenioTabView::_PrintMap() +{ + for(const auto& [k, v] : fTabIdMap) { + printf("TabList: '%.4s' -> %p\n", (char *)&k, v); + } +} diff --git a/src/helpers/gtab/GenioTabView.h b/src/helpers/gtab/GenioTabView.h index 5309fcc6..fa8d8795 100644 --- a/src/helpers/gtab/GenioTabView.h +++ b/src/helpers/gtab/GenioTabView.h @@ -8,11 +8,16 @@ #include #include #include -#include "GTab.h" +#include #include "Draggable.h" +class GTab; + typedef uint32 tab_drag_affinity; +typedef uint32 tab_id; + +typedef std::map IdMap; class GenioTabView : public BTabView, private Draggable { public: @@ -24,16 +29,28 @@ class GenioTabView : public BTabView, private Draggable { const BMessage* dragMessage); virtual void MessageReceived(BMessage* msg); - void AddTab(BView* target); + void AddTab(BView* target, tab_id id); BTab* TabFromView(BView* view) const; + void SelectTab(tab_id id); + + bool HasTab(tab_id id); + + private: + using BTabView::TabAt; + using BTabView::Select; + BTab* RemoveTab(int32 tabIndex); + BView* ContainerView() const = delete; BView* ViewForTab(int32 tabIndex) const = delete; - void AddTab(GTab* tab); + + void _AddTab(GTab* tab); + virtual void AddTab(BView* target, BTab* tab); virtual BRect DrawTabs(); + void MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView); bool InitiateDrag(BPoint where); void _OnDrop(BMessage* msg); @@ -45,9 +62,12 @@ class GenioTabView : public BTabView, private Draggable { void _ChangeGroupViewDirection(GTab* tab); + void _PrintMap(); + BRect fDropTargetHighlightFrame; tab_drag_affinity fTabAffinity; orientation fOrientation; + IdMap fTabIdMap; }; diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index b86d63bb..513c0f97 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -99,6 +99,20 @@ static float kDefaultIconSize = 32.0; using Genio::Task::Task; +enum { + kTabProblems = 'Tprb', + kTabBuildLog = 'Tbld', + kTabOutputLog = 'Tter', + kTabSearchResult = 'Tsea', + + kTabProjectBrowser = 'Tprj', + kTabSourceControl = 'Tsrc', + + kTabOutlineView = 'Touv' + +}; + + static bool AcceptsCopyPaste(BView* view) { @@ -1610,7 +1624,7 @@ GenioWindow::_BuildProject() _UpdateProjectActivation(false); fBuildLogView->Clear(); - _ShowLog(kBuildLog); + _ShowOutputTab(kTabBuildLog); LogInfoF("Build started: [%s]", fActiveProject->Name().String()); @@ -1657,7 +1671,7 @@ GenioWindow::_CleanProject() _UpdateProjectActivation(false); fBuildLogView->Clear(); - _ShowLog(kBuildLog); + _ShowOutputTab(kTabBuildLog); LogInfoF("Clean started: [%s]", fActiveProject->Name().String()); @@ -2198,7 +2212,7 @@ GenioWindow::_FindInFiles() fSearchResultTab->SetAndStartSearch(text, (bool)fFindWholeWordCheck->Value(), (bool)fFindCaseSensitiveCheck->Value(), fActiveProject); - _ShowLog(kSearchResult); + _ShowOutputTab(kTabSearchResult); _UpdateFindMenuItems(fFindTextControl->Text()); } @@ -2251,7 +2265,7 @@ GenioWindow::_Git(const BString& git_command) _UpdateProjectActivation(false); //fConsoleIOView->Clear(); - _ShowLog(kOutputLog); + _ShowOutputTab(kTabOutputLog); BString command; command << "git " << git_command; @@ -3409,10 +3423,10 @@ GenioWindow::_InitOutputSplit() fSearchResultTab = new SearchResultTab(fOutputTabView); - fOutputTabView->AddTab(fProblemsPanel); - fOutputTabView->AddTab(fBuildLogView); - fOutputTabView->AddTab(fMTermView); - fOutputTabView->AddTab(fSearchResultTab); + fOutputTabView->AddTab(fProblemsPanel, kTabProblems); + fOutputTabView->AddTab(fBuildLogView, kTabBuildLog); + fOutputTabView->AddTab(fMTermView, kTabOutputLog); + fOutputTabView->AddTab(fSearchResultTab, kTabSearchResult); } @@ -3423,11 +3437,11 @@ GenioWindow::_InitLeftSplit() fProjectsTabView = new GenioTabView("ProjectsTabview", 'GTAB', B_VERTICAL); fProjectsFolderBrowser = new ProjectBrowser(); - fProjectsTabView->AddTab(fProjectsFolderBrowser); + fProjectsTabView->AddTab(fProjectsFolderBrowser, kTabProjectBrowser); // Source Control fSourceControlPanel = new SourceControlPanel(); - fProjectsTabView->AddTab(fSourceControlPanel); + fProjectsTabView->AddTab(fSourceControlPanel, kTabSourceControl); } @@ -3437,7 +3451,7 @@ GenioWindow::_InitRightSplit() // Outline view fRightTabView = new GenioTabView("OutlineTabview", 'GTAB', B_VERTICAL); fFunctionsOutlineView = new FunctionsOutlineView(); - fRightTabView->AddTab(fFunctionsOutlineView); + fRightTabView->AddTab(fFunctionsOutlineView, kTabOutlineView); } @@ -3499,7 +3513,7 @@ GenioWindow::_MakeBindcatalogs() return; fBuildLogView->Clear(); - _ShowLog(kBuildLog); + _ShowOutputTab(kTabBuildLog); // TODO: this only works for makefile_engine based projects BMessage message; @@ -3527,7 +3541,7 @@ GenioWindow::_MakeCatkeys() return; fBuildLogView->Clear(); - _ShowLog(kBuildLog); + _ShowOutputTab(kTabBuildLog); BMessage message; message.AddString("cmd", "make catkeys"); @@ -4098,7 +4112,7 @@ GenioWindow::_RunInConsole(const BString& command) else chdir(fActiveProject->Path()); - _ShowLog(kOutputLog); + _ShowOutputTab(kTabOutputLog); _UpdateRecentCommands(command); @@ -4140,7 +4154,7 @@ GenioWindow::_RunTarget() // Don't do that in graphical mode _UpdateProjectActivation(false); - _ShowLog(kOutputLog); + _ShowOutputTab(kTabOutputLog); BString command; command << fActiveProject->GetTarget(); @@ -4176,14 +4190,27 @@ GenioWindow::_RunTarget() void -GenioWindow::_ShowLog(int32 index) +GenioWindow::_ShowOutputTab(tab_id id) { - if (fOutputTabView->IsHidden()) - fOutputTabView ->Show(); - - fOutputTabView->Select(index); + if (!_ShowTab (id, fOutputTabView)){ + if(!_ShowTab (id, fProjectsTabView)) { + _ShowTab (id, fRightTabView); + } + } } +bool +GenioWindow::_ShowTab(tab_id id, GenioTabView* tabView) +{ + if (tabView->HasTab(id)) { + if (tabView->IsHidden()) + tabView ->Show(); + + tabView->SelectTab(id); + return true; + } + return false; +} void GenioWindow::_UpdateFindMenuItems(const BString& text) diff --git a/src/ui/GenioWindow.h b/src/ui/GenioWindow.h index f59816ca..7226dda0 100644 --- a/src/ui/GenioWindow.h +++ b/src/ui/GenioWindow.h @@ -13,12 +13,6 @@ #include "GMessage.h" #include "GenioTabView.h" -enum { - kProblems = 0, - kBuildLog, - kOutputLog, - kSearchResult -}; enum scree_mode { kDefault = 0, @@ -150,7 +144,9 @@ class GenioWindow : public BWindow { status_t _RunInConsole(const BString& command); void _RunTarget(); - void _ShowLog(int32 index); + void _ShowOutputTab(tab_id id); + bool _ShowTab(tab_id id, GenioTabView* tabView); + void _UpdateFindMenuItems(const BString& text); void _UpdateRecentCommands(const BString& text); status_t _UpdateLabel(int32 index, bool isModified); From eccc6e24336c9168a5445ff2bcb85172a4d43931 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sat, 11 Jan 2025 11:48:49 +0100 Subject: [PATCH 04/29] major update to introduce GTabView --- Makefile | 4 +- src/helpers/gtab/GTab.cpp | 475 ++++++++++++++++++++++++++++- src/helpers/gtab/GTab.h | 299 +++++++++++++++++- src/helpers/gtab/GTabView.cpp | 315 +++++++++++++++++++ src/helpers/gtab/GTabView.h | 82 +++++ src/helpers/gtab/GenioTabView.cpp | 462 ---------------------------- src/helpers/gtab/GenioTabView.h | 74 ----- src/helpers/gtab/TabButtons.h | 156 ++++++++++ src/helpers/gtab/TabsContainer.cpp | 255 ++++++++++++++++ src/helpers/gtab/TabsContainer.h | 59 ++++ src/ui/GenioWindow.cpp | 126 ++++---- src/ui/GenioWindow.h | 17 +- src/ui/PanelTabManager.cpp | 195 ++++++++++++ src/ui/PanelTabManager.h | 44 +++ src/ui/ProblemsPanel.cpp | 10 +- src/ui/ProblemsPanel.h | 8 +- src/ui/SearchResultPanel.cpp | 13 +- src/ui/SearchResultPanel.h | 7 +- src/ui/SearchResultTab.cpp | 5 +- src/ui/SearchResultTab.h | 5 +- 20 files changed, 1955 insertions(+), 656 deletions(-) create mode 100644 src/helpers/gtab/GTabView.cpp create mode 100644 src/helpers/gtab/GTabView.h delete mode 100644 src/helpers/gtab/GenioTabView.cpp delete mode 100644 src/helpers/gtab/GenioTabView.h create mode 100644 src/helpers/gtab/TabButtons.h create mode 100644 src/helpers/gtab/TabsContainer.cpp create mode 100644 src/helpers/gtab/TabsContainer.h create mode 100644 src/ui/PanelTabManager.cpp create mode 100644 src/ui/PanelTabManager.h diff --git a/Makefile b/Makefile index c328c4af..e0c8d067 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,8 @@ SRCS += src/helpers/tabview/CircleColorMenuItem.cpp SRCS += src/helpers/tabview/TabContainerView.cpp SRCS += src/helpers/tabview/TabManager.cpp SRCS += src/helpers/tabview/TabView.cpp -SRCS += src/helpers/gtab/GenioTabView.cpp +SRCS += src/helpers/gtab/GTabView.cpp +SRCS += src/helpers/gtab/TabsContainer.cpp SRCS += src/helpers/gtab/GTab.cpp SRCS += src/lsp-client/CallTipContext.cpp SRCS += src/lsp-client/LSPEditorWrapper.cpp @@ -89,6 +90,7 @@ SRCS += src/ui/SearchResultPanel.cpp SRCS += src/ui/SearchResultTab.cpp SRCS += src/ui/StyledItem.cpp SRCS += src/ui/ToolBar.cpp +SRCS += src/ui/PanelTabManager.cpp SRCS += src/templates/IconMenuItem.cpp SRCS += src/templates/TemplateManager.cpp SRCS += src/templates/TemplatesMenu.cpp diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index 149e38c2..48f4bc2b 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -5,26 +5,483 @@ #include "GTab.h" +#include +#include "TabsContainer.h" +#include -#include +#define TAB_DRAG 'DRAG' +#define ALPHA 200 -GTabContainer::GTabContainer(BView* view):BBox(view->Name()),fView(view) +bool +GTabDropZone::_ValidDragAndDrop(const BMessage* message) { - SetBorder(B_NO_BORDER); - SetLayout(new BGroupLayout(B_VERTICAL)); - if (fView) - AddChild(fView); + GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); + TabsContainer* fromContainer = fromTab->Container(); + + if (fromTab == nullptr || fromContainer == nullptr) + return false; + + if (this == fromTab) + return false; + + if (Container()->GetAffinity() == 0 || fromContainer->GetAffinity() == 0) + return false; + + return Container()->GetAffinity() == fromContainer->GetAffinity(); +} + + +bool +GTabDropZone::DropZoneMouseMoved(BView* view, + BPoint where, + uint32 transit, + const BMessage* dragMessage) +{ + if (dragMessage && + dragMessage->what == TAB_DRAG && + _ValidDragAndDrop(dragMessage)) { + switch (transit) { + case B_ENTERED_VIEW: + case B_INSIDE_VIEW: + { + StartDragging(view); + return true; + } + break; + default: + StopDragging(view); + break; + }; + } else { + + OnMouseMoved(where); + StopDragging(view); + } + return false; +} + + +bool +GTabDropZone::DropZoneMessageReceived(BMessage* message) +{ + if (message->what == TAB_DRAG) { + if(_ValidDragAndDrop(message)) + OnDropMessage(message); + return true; + } + return false; +} + + + +GTab::GTab(const char* label, TabsContainer* container) + : BView("_tabView_", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), + GTabDropZone(container), fIsFront(false), fLabel(label)/*, fTabDragging(false)*/ +{ +} + + +GTab::~GTab() +{ +} + + +BSize +GTab::MinSize() +{ + BSize size(MaxSize()); + size.width = 100.0f; + return size; +} + +BSize +GTab::MaxSize() +{ + float labelWidth = 150.0f; + return BSize(labelWidth, TabViewTools::DefaultTabHeigh()); +} + + +void +GTab::Draw(BRect updateRect) +{ + DrawTab(this, updateRect); + DropZoneDraw(this, Bounds()); +} + +void +GTab::DrawTab(BView* owner, BRect updateRect) +{ + BRect frame(owner->Bounds()); + if (fIsFront) { + frame.left--; + frame.right++; + } + + DrawBackground(owner, frame, updateRect, fIsFront); + + if (fIsFront) { + frame.top += 0.0f; + } else + frame.top += 3.0f; + + float spacing = be_control_look->DefaultLabelSpacing(); + frame.InsetBy(spacing, spacing / 2); + DrawContents(owner, frame, updateRect, fIsFront); } +void +GTab::DrawBackground(BView* owner, BRect frame, const BRect& updateRect, bool isFront) +{ + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 borders = BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER; + + if (isFront) { + be_control_look->DrawActiveTab(owner, frame, updateRect, base, + 0, borders); + } else { + be_control_look->DrawInactiveTab(owner, frame, updateRect, base, + 0, borders); + } +} + + +void +GTab::DrawContents(BView* owner, BRect frame, const BRect& updateRect, bool isFront) +{ + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + be_control_look->DrawLabel(owner, fLabel.String(), frame, updateRect, + base, 0, BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); +} + + +void +GTab::MouseDown(BPoint where) +{ + BMessage* msg = Window()->CurrentMessage(); + if (!msg) + return; + const int32 buttons = msg->GetInt32("buttons", 0); + if (Container()) + Container()->MouseDown(this, where, buttons); + + if(buttons & B_PRIMARY_MOUSE_BUTTON) { + DropZoneMouseDown(where); + } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { + + } +} + + +void +GTab::MouseUp(BPoint where) +{ + DropZoneMouseUp(this, where); +} + + +void +GTab::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) +{ + DropZoneMouseMoved(this, where, transit, dragMessage); +} + + +void +GTab::MessageReceived(BMessage* message) +{ + if (DropZoneMessageReceived(message) == false) + BView::MessageReceived(message); +} + + + +bool +GTab::InitiateDrag(BPoint where) +{ + GTab* tab = this; + if (tab != nullptr) { + BMessage message(TAB_DRAG); + + message.AddPointer("tab", this); + message.AddPointer("tab_container", Container()); + + const BRect& updateRect = tab->Bounds(); + + BBitmap* dragBitmap = new BBitmap(updateRect, B_RGB32, true); + if (dragBitmap->IsValid()) { + BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); + dragBitmap->AddChild(view); + dragBitmap->Lock(); + tab->DrawTab(view, updateRect); + view->Sync(); + uint8* bits = (uint8*)dragBitmap->Bits(); + int32 height = (int32)dragBitmap->Bounds().Height() + 1; + int32 width = (int32)dragBitmap->Bounds().Width() + 1; + int32 bpr = dragBitmap->BytesPerRow(); + for (int32 y = 0; y < height; y++, bits += bpr) { + uint8* line = bits + 3; + for (uint8* end = line + 4 * width; line < end; line += 4) + *line = ALPHA; + } + dragBitmap->Unlock(); + } else { + delete dragBitmap; + dragBitmap = NULL; + } + const BRect& frame = updateRect; + if (dragBitmap != NULL) { + DragMessage(&message, dragBitmap, B_OP_ALPHA, + BPoint(where.x - frame.left, where.y - frame.top)); + } else { + DragMessage(&message, frame, this); + } + + return true; + } + return false; +} + + +void +GTab::SetIsFront(bool isFront) +{ + if (fIsFront == isFront) + return; + + fIsFront = isFront; + Invalidate(); +} -GTab::GTab(BView* view, tab_id id):BTab(),fGTabContainer(nullptr),fTabId(id) +bool +GTab::IsFront() const { - fGTabContainer = new GTabContainer(view); - SetView(fGTabContainer); + return fIsFront; } +void +GTab::OnDropMessage(BMessage* message) +{ + Container()->OnDropTab(this, message); +} + + + +/////////////////////////////////////////////////////////////////////////////// + +//TODO MOve in TabUtils. +#define kCloseButtonWidth 19.0f +const int32 kBrightnessBreakValue = 126; + +static void inline +IncreaseContrastBy(float& tint, const float& value, const int& brightness) +{ + tint *= 1 + ((brightness >= kBrightnessBreakValue) ? +1 : -1) * value; +} + + +GTabCloseButton::GTabCloseButton(const char* label, + TabsContainer* controller, + const BHandler* handler): + GTab(label, controller), + fOverCloseRect(false), + fClicked(false), + fHandler(handler) +{ + +} + +//FIX: we should better understand how to extend the default sizes. +BSize +GTabCloseButton::MinSize() +{ + return GTab::MinSize(); +} + +BSize +GTabCloseButton::MaxSize() +{ + BSize s(GTab::MaxSize()); + //s.width += kCloseButtonWidth; + return s; +} + + +void +GTabCloseButton::DrawContents(BView* owner, BRect frame, + const BRect& updateRect, bool isFront) +{ + BRect labelFrame = frame; + labelFrame.right -= kCloseButtonWidth; + GTab::DrawContents(owner, labelFrame, updateRect, isFront); + frame.left = labelFrame.right; + DrawCloseButton(owner, frame, updateRect, isFront); + return; +} + + +void +GTabCloseButton::MouseDown(BPoint where) +{ + BMessage* msg = Window()->CurrentMessage(); + if (!msg) + return; + const int32 buttons = msg->GetInt32("buttons", 0); + if(buttons & B_PRIMARY_MOUSE_BUTTON) { + BRect closeRect = RectCloseButton(); + bool inside = closeRect.Contains(where); + if (inside != fClicked) { + fClicked = inside; + Invalidate(closeRect); + return; + } + } + GTab::MouseDown(where); +} + +void +GTabCloseButton::MouseUp(BPoint where) +{ + if (fClicked) { + fClicked = false; + Invalidate(); + BRect closeRect = RectCloseButton(); + bool inside = closeRect.Contains(where); + if (inside && Container()) { + CloseButtonClicked(); + } + } + GTab::MouseUp(where); +} + + + +void +GTabCloseButton::MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) +{ + GTab::MouseMoved(where, transit, dragMessage); + if (dragMessage == nullptr) { + BRect closeRect = RectCloseButton(); + bool inside = closeRect.Contains(where); + if (inside != fOverCloseRect) { + fOverCloseRect = inside; + if (inside == false) + fClicked = false; + Invalidate(closeRect); + } + } +} + + +BRect +GTabCloseButton::RectCloseButton() +{ + BRect frame = Bounds(); + frame.right -= be_control_look->DefaultLabelSpacing(); + frame.left = frame.right - kCloseButtonWidth + 3; + frame.bottom -= be_control_look->DefaultLabelSpacing()/2 + TabViewTools::DefaultFontDescent() - 2; + frame.top = frame.bottom - frame.Width(); + return frame; +} + + +void +GTabCloseButton::CloseButtonClicked() +{ + BMessage msg(TabsContainer::kTVCloseTab); + msg.AddPointer("tab", this); + BMessenger(fHandler).SendMessage(&msg); +} + + + +void +GTabCloseButton::DrawCloseButton(BView* owner, BRect buttonRect, const BRect& updateRect, + bool isFront) +{ + BRect closeRect = RectCloseButton(); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + float tint = B_LIGHTEN_1_TINT; + if (base.Brightness() >= kBrightnessBreakValue) { + tint = B_DARKEN_1_TINT *1.2; + } + + if (fOverCloseRect) { + // Draw the button frame + be_control_look->DrawButtonFrame(owner, closeRect, updateRect, + base, base, + BControlLook::B_ACTIVATED | BControlLook::B_BLEND_FRAME); + + rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR); + be_control_look->DrawButtonBackground(owner, closeRect, updateRect, + background, BControlLook::B_ACTIVATED); + } else { + closeRect.top += 4; + closeRect.left += 4; + closeRect.right -= 2; + closeRect.bottom -= 2; + } + + // Draw the × + if (fClicked) + IncreaseContrastBy(tint, .2, base.Brightness()); + + base = tint_color(base, tint); + owner->SetHighColor(base); + owner->SetPenSize(2); + + owner->StrokeLine(closeRect.LeftTop(), closeRect.RightBottom()); + owner->StrokeLine(closeRect.LeftBottom(), closeRect.RightTop()); + owner->SetPenSize(1); +} + +/////////////////////////////////////////////////////////////////////////////// + +Filler::Filler(TabsContainer* tabsContainer) + : BView("_filler_", B_WILL_DRAW), + GTabDropZone(tabsContainer) +{ + +} + +void +Filler::Draw(BRect rect) +{ + BRect bounds(Bounds()); + TabViewTools::DrawTabBackground(this, bounds, rect); + DropZoneDraw(this, bounds); +} + + +void +Filler::MouseUp(BPoint where) +{ + DropZoneMouseUp(this, where); +} + + +void +Filler::MessageReceived(BMessage* message) +{ + if (DropZoneMessageReceived(message) == false) + BView::MessageReceived(message); +} + +void +Filler::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) +{ + DropZoneMouseMoved(this, where, transit, dragMessage); +} + + +void +Filler::OnDropMessage(BMessage* message) +{ + Container()->OnDropTab(nullptr, message); +} diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 928782ab..54fc625a 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -5,28 +5,299 @@ #pragma once +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include "TabButtons.h" +#include "Draggable.h" +#include "TabsContainer.h" -#include "GenioTabView.h" +class GTab; -class GTabContainer : public BBox { +class GTabDropZone : Draggable +{ + public: + + GTabDropZone(TabsContainer* container) : fTabsContainer(container) + { + } + + virtual void DropZoneDraw(BView* view, BRect rect) + { + if (fTabDragging) { + TabViewTools::DrawDroppingZone(view, rect); + } + } + + virtual void DropZoneMouseUp(BView* view, BPoint where) + { + Draggable::OnMouseUp(where); + StopDragging(view); + } + + virtual void DropZoneMouseDown(BPoint where) + { + Draggable::OnMouseDown(where); + } + + virtual bool DropZoneMouseMoved(BView* view, BPoint where, uint32 transit, + const BMessage* dragMessage); + + + virtual bool DropZoneMessageReceived(BMessage* message); + + virtual void OnDropMessage(BMessage* message) = 0; + + TabsContainer* Container() { return fTabsContainer; } + + virtual void StopDragging(BView* view) + { + if (fTabDragging) { + fTabDragging = false; + view->Invalidate(); + } + } + + virtual void StartDragging(BView* view) + { + fTabDragging = true; + view->Invalidate(); + } + + bool _ValidDragAndDrop(const BMessage* message); + + bool fTabDragging = false; + TabsContainer* fTabsContainer; + +}; + +class GTab : public BView , public GTabDropZone { +public: + GTab(const char* label, TabsContainer* container); + virtual ~GTab(); + + virtual BSize MinSize() override; + virtual BSize MaxSize() override; + + void Draw(BRect updateRect) override; + + virtual void DrawTab(BView* owener, BRect updateRect); + virtual void DrawBackground(BView* owner, BRect frame, + const BRect& updateRect, bool isFront); + virtual void DrawContents(BView* owner, BRect frame, + const BRect& updateRect, bool isFront); + + virtual void MouseDown(BPoint where) override; + virtual void MouseUp(BPoint where) override; + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) override; + + virtual void MessageReceived(BMessage* message) override; + + bool InitiateDrag(BPoint where) override; + + void SetIsFront(bool isFront); + bool IsFront() const; + + BLayoutItem* LayoutItem() const { return fLayoutItem; } + void SetLayoutItem(BLayoutItem* layItem) { fLayoutItem = layItem; } + + BString Label() { return fLabel; }; + void SetLabel(const char* label) { fLabel.SetTo(label); } + + virtual void OnDropMessage(BMessage* message); + +protected: + + BLayoutItem* fLayoutItem; + bool fIsFront; + BString fLabel; +}; + +class GTabCloseButton : public GTab { public: - GTabContainer(BView* view);; - BView* ContentView() { return fView;} + + GTabCloseButton(const char* label, + TabsContainer* controller, + const BHandler* handler); + + virtual BSize MinSize() override; + virtual BSize MaxSize() override; + virtual void DrawContents(BView* owner, BRect frame, + const BRect& updateRect, bool isFront) override; + virtual void MouseDown(BPoint where) override; + virtual void MouseUp(BPoint where) override; + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) override; private: - BView* fView; + void DrawCloseButton(BView* owner, BRect butFrame, const BRect& updateRect, + bool isFront); + + BRect RectCloseButton(); + + void CloseButtonClicked(); +private: + + bool fOverCloseRect; + bool fClicked; + const BHandler* fHandler; }; -class GTab : public BTab { -protected: -friend GenioTabView; - GTab(BView* view, tab_id id); - tab_id Id() { return fTabId;} +class Filler : public BView, public GTabDropZone +{ + public: + Filler(TabsContainer* tabsContainer); + + BSize MinSize() override + { + return BSize(0,0); + } + + void Draw(BRect rect) override; + + void MouseUp(BPoint where) override; + + + void MessageReceived(BMessage* message) override; + + + void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) override; + + void OnDropMessage(BMessage* message) override; + + void OnDropObject(); + +}; + + +class TabButtonDropZone : public GTabButton, public GTabDropZone { + + enum { + kRunnerTick = 'RUNN' + }; + +public: + TabButtonDropZone(BMessage* message, TabsContainer* container) + : GTabButton(" ", message), GTabDropZone(container), fRunner(nullptr) + { + } + + virtual void Draw(BRect updateRect) override + { + GTabButton::Draw(updateRect); + if (IsEnabled()) + DropZoneDraw(this, Bounds()); + } + + virtual void MouseUp(BPoint where) override + { + DropZoneMouseUp(this, where); + GTabButton::MouseUp(where); + } + + virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override + { + if (DropZoneMouseMoved(this, where, transit, dragMessage) == false) + GTabButton::MouseMoved(where, transit, dragMessage); + } + + + virtual void OnDropMessage(BMessage* message) override + { + return; + } + + virtual void MessageReceived(BMessage* message) override + { + switch(message->what) { + case kRunnerTick: + if (fRunner != nullptr && IsEnabled()) { + Invoke(); + } else { + if (fRunner != nullptr) { + delete fRunner; + fRunner = nullptr; + } + } + break; + default: + GTabButton::MessageReceived(message); + break; + + }; + } + + virtual void StopDragging(BView* view) override + { + GTabDropZone::StopDragging(view); + if (fRunner != nullptr) { + delete fRunner; + fRunner = nullptr; + } + } + + virtual void StartDragging(BView* view) override + { + GTabDropZone::StartDragging(view); + + // create a message to update the project + if (fRunner == nullptr) { + BMessage message(kRunnerTick); + fRunner = new BMessageRunner(BMessenger(this), &message, 500000); + if (fRunner->InitCheck() != B_OK) { + if (fRunner != nullptr) { + delete fRunner; + fRunner = nullptr; + } + } + } + } + private: - GTabContainer* fGTabContainer; - tab_id fTabId; + bool fTabDragging; + BMessageRunner* fRunner; }; +class GTabScrollLeftButton : public TabButtonDropZone { +public: + GTabScrollLeftButton(BMessage* message, TabsContainer* container) + : TabButtonDropZone(message, container) + { + } + + virtual void DrawSymbol(BRect frame, const BRect& updateRect, + const rgb_color& base) override + { + float tint = IsEnabled() ? B_DARKEN_4_TINT : B_DARKEN_1_TINT; + be_control_look->DrawArrowShape(this, frame, updateRect, + base, BControlLook::B_LEFT_ARROW, 0, tint); + } +}; + + +class GTabScrollRightButton : public TabButtonDropZone { +public: + GTabScrollRightButton(BMessage* message, TabsContainer* container) + : TabButtonDropZone(message, container) + { + } + + virtual void DrawSymbol(BRect frame, const BRect& updateRect, + const rgb_color& base) + { + frame.OffsetBy(1, 0); + float tint = IsEnabled() ? B_DARKEN_4_TINT : B_DARKEN_1_TINT; + be_control_look->DrawArrowShape(this, frame, updateRect, + base, BControlLook::B_RIGHT_ARROW, 0, tint); + } +}; + diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp new file mode 100644 index 00000000..e6accc50 --- /dev/null +++ b/src/helpers/gtab/GTabView.cpp @@ -0,0 +1,315 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ + + +#include "GTabView.h" +#include "TabButtons.h" +#include "GTab.h" +#include "TabsContainer.h" +#include + +enum { + + kLeftTabButton = 'GTlb', + kRightTabButton = 'GTrb', + kMenuTabButton = 'GTmb', + kSelectedTabButton = 'GTse' + +}; + +GTabView::GTabView(const char* name, + tab_affinity affinity, + orientation content_orientation, + bool closeButton, + bool menuButton) : + + BGroupView(name, B_VERTICAL, 0.0f), + fScrollLeftTabButton(nullptr), + fTabsContainer(nullptr), + fScrollRightTabButton(nullptr), + fTabMenuTabButton(nullptr), + fCardView(nullptr), + fCloseButton(closeButton), + fContentOrientation(content_orientation), + fMenuButton(menuButton) +{ + _Init(affinity); +} + +GTab* +GTabView::AddTab(const char* label, BView* view, int32 index) +{ + GTab* tab = CreateTabView(label); + AddTab(tab, view, index); + return tab; +} + +void +GTabView::AddTab(GTab* tab, BView* view, int32 index) +{ + fTabsContainer->AddTab(tab, index); + fCardView->CardLayout()->AddView(index, view); + _FixContentOrientation(view); + OnTabAdded(tab, view); +#if 0 + //debug code: + printf("-------- debug size for %s \n", Name()); + BSize containerSize = fTabsContainer->Bounds().Size(); + printf(" containerSize %f,%f\n", containerSize.Width(), containerSize.Height()); + float accu = 0.0f; + for(int32 i=0;iCountTabs();i++){ + GTab* tab = fTabsContainer->TabAt(i); + accu += tab->Bounds().Width(); + printf("%s w %f accu %f left %f\n", tab->Label().String(), tab->Bounds().Width(), accu, containerSize.Width() - accu); + } +#endif +} + + + +int32 +GTabView::CountTabs() +{ + return fTabsContainer->CountTabs(); +} + + +void +GTabView::DestroyTabAndView(GTab* tab) +{ + //Remove the View from CardView + int32 fromIndex = fTabsContainer->IndexOfTab(tab); + BLayoutItem* fromLayout = fCardView->CardLayout()->ItemAt(fromIndex); + BView* fromView = fromLayout->View(); + if (!fromView) + return; + + fromView->RemoveSelf(); + + fCardView->CardLayout()->RemoveItem(fromLayout); + + GTab* rtab = fTabsContainer->RemoveTab(tab); + + OnTabRemoved(rtab); + + if (rtab) + delete rtab; + + delete fromView; +} + + +void +GTabView::UpdateScrollButtons(bool left, bool right) +{ + fScrollLeftTabButton->SetEnabled(left); + fScrollRightTabButton->SetEnabled(right); + fTabMenuTabButton->SetEnabled(fTabsContainer->CountTabs() > 0); +} + + +void +GTabView::AttachedToWindow() +{ + fScrollLeftTabButton->SetTarget(this); + fScrollRightTabButton->SetTarget(this); + fTabsContainer->SetTarget(this); + fTabMenuTabButton->SetTarget(this); +} + + +void +GTabView::MessageReceived(BMessage* message) +{ + switch(message->what) { + case kLeftTabButton: + fTabsContainer->ShiftTabs(-1); + break; + case kRightTabButton: + fTabsContainer->ShiftTabs(+1); + break; + case kSelectedTabButton: + { + int32 index = message->GetInt32("index", 0); + if (index > -1) + fCardView->CardLayout()->SetVisibleItem(index); + } + break; + case TabsContainer::kTVCloseTab: + { + if (fCloseButton == false) + return; + + GTab* tab = (GTab*)message->GetPointer("tab", nullptr); + if (tab != nullptr) { + DestroyTabAndView(tab); + } + } + break; + case kMenuTabButton: + { + OnMenuTabButton(); + break; + } + default: + BGroupView::MessageReceived(message); + }; +} + + +void +GTabView::OnMenuTabButton() +{ + BPopUpMenu* tabMenu = new BPopUpMenu("tab menu", true, false); + int tabCount = fTabsContainer->CountTabs(); + for (int i = 0; i < tabCount; i++) { + GTab* tab = fTabsContainer->TabAt(i); + + if (tab) { + BMenuItem* item = new BMenuItem(tab->Label(), nullptr); + tabMenu->AddItem(item); + if (tab->IsFront()) + item->SetMarked(true); + } + } + + // Force layout to get the final menu size. InvalidateLayout() + // did not seem to work here. + tabMenu->AttachedToWindow(); + BRect buttonFrame = fTabMenuTabButton->Frame(); + BRect menuFrame = tabMenu->Frame(); + BPoint openPoint = ConvertToScreen(buttonFrame.LeftBottom()); + // Open with the right side of the menu aligned with the right + // side of the button and a little below. + openPoint.x -= menuFrame.Width() - buttonFrame.Width(); + openPoint.y += 2; + + BMenuItem *selected = tabMenu->Go(openPoint, false, false, + ConvertToScreen(buttonFrame)); + if (selected) { + selected->SetMarked(true); + int32 index = tabMenu->IndexOf(selected); + if (index != B_ERROR) + SelectTab(fTabsContainer->TabAt(index)); + } + fTabMenuTabButton->MenuClosed(); + delete tabMenu; + +} + + +void +GTabView::_Init(tab_affinity affinity) +{ + fTabsContainer = new TabsContainer(this, affinity, new BMessage(kSelectedTabButton)); + + fScrollLeftTabButton = new GTabScrollLeftButton(new BMessage(kLeftTabButton), fTabsContainer); + fScrollRightTabButton = new GTabScrollRightButton(new BMessage(kRightTabButton), fTabsContainer); + + + fTabMenuTabButton = new GTabMenuTabButton(new BMessage(kMenuTabButton)); + + fCardView = new BCardView("_cardview_"); + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) + .AddGroup(B_HORIZONTAL, 0.0f) + .Add(fScrollLeftTabButton) + .Add(fTabsContainer) + .AddGroup(B_HORIZONTAL, 0.0f) + .Add(fScrollRightTabButton) + .Add(fTabMenuTabButton) + .SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_CENTER)) + .End() + .SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_VERTICAL_UNSET)) + .End() + .Add(fCardView) + .AddGlue(0); + + if (fMenuButton == false) + fTabMenuTabButton->Hide(); + + UpdateScrollButtons(false, false); +} + + +void +GTabView::_FixContentOrientation(BView* view) +{ + BLayout* layout = view->GetLayout(); + if (!layout) + return; + BGroupLayout* grpLayout = dynamic_cast(layout); + if (!grpLayout) { + return; + } + if (grpLayout->Orientation() != fContentOrientation) + { + grpLayout->SetOrientation(fContentOrientation); + } +} + + +void +GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) +{ + //Remove the View from CardView + int32 fromIndex = fromContainer->IndexOfTab(fromTab); + int32 toIndex = -1 ; + + if (toTab == nullptr) { + toIndex = fTabsContainer->CountTabs(); // last position + if (fTabsContainer == fromContainer ) + toIndex--; //exclude filler? + } else { + toIndex = fTabsContainer->IndexOfTab(toTab); + } + + BLayoutItem* fromLayout = fromContainer->GetGTabView()->CardView()->CardLayout()->ItemAt(fromIndex); + BView* fromView = fromLayout->View(); + if (!fromView) + return; + + fromView->RemoveSelf(); + + fromLayout->RemoveSelf(); + + BString label = fromTab->Label(); //TODO copy all the props + GTab* removedTab = fromContainer->RemoveTab(fromTab); + + fromContainer->GetGTabView()->OnTabRemoved(fromTab); + + GTab* newTab = CreateTabView(removedTab); + + AddTab(newTab, fromView, toIndex); + SelectTab(newTab); + + delete removedTab; +} + +void +GTabView::SelectTab(GTab* tab) +{ + fTabsContainer->SelectTab(tab); +} + + +GTab* +GTabView::CreateTabView(const char* label) +{ + return fCloseButton ? new GTabCloseButton(label, fTabsContainer, this) + : new GTab(label, fTabsContainer); +} + +GTab* +GTabView::CreateTabView(GTab* clone) +{ + return CreateTabView(clone->Label()); +} + + + + + + diff --git a/src/helpers/gtab/GTabView.h b/src/helpers/gtab/GTabView.h new file mode 100644 index 00000000..baafbd89 --- /dev/null +++ b/src/helpers/gtab/GTabView.h @@ -0,0 +1,82 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include +#include +#include + +class GTabScrollLeftButton; +class TabsContainer; +class GTabScrollRightButton; +class GTabMenuTabButton; +class GTabButton; +class GTab; + +typedef uint32 tab_affinity; + +class GTabView : public BGroupView +{ + public: + GTabView(const char* name, + tab_affinity affinity, + orientation orientation = B_HORIZONTAL, + bool closeButton = false, + bool menuButton = false); + + GTab* AddTab(const char* label, BView* view, int32 index = -1); + + int32 CountTabs(); + + void UpdateScrollButtons(bool left, bool right); + + void AttachedToWindow(); + + void MessageReceived(BMessage* message); + + void MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer); + + void SelectTab(GTab* tab); + + virtual void OnMenuTabButton(); + +protected: + void AddTab(GTab* tab, BView* view, int32 index = -1); + virtual void OnTabRemoved(GTab* tab) {}; + virtual void OnTabAdded(GTab* tab, BView* view) {}; + + TabsContainer* Container() { return fTabsContainer; } + + + + private: + + virtual GTab* CreateTabView(const char* label); + virtual GTab* CreateTabView(GTab* clone); + + BCardView* CardView() { return fCardView;} + void DestroyTabAndView(GTab* tab); //Remove and delete a tab and the view. + + + + private: + + void _Init(tab_affinity affinity); + void _FixContentOrientation(BView* view); + + + GTabScrollLeftButton* fScrollLeftTabButton; + TabsContainer* fTabsContainer; + GTabScrollRightButton* fScrollRightTabButton; + GTabMenuTabButton* fTabMenuTabButton; + BCardView* fCardView; + bool fCloseButton; + orientation fContentOrientation; + bool fMenuButton; +}; + diff --git a/src/helpers/gtab/GenioTabView.cpp b/src/helpers/gtab/GenioTabView.cpp deleted file mode 100644 index 2a4b92df..00000000 --- a/src/helpers/gtab/GenioTabView.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright 2024, Andrea Anzani - * All rights reserved. Distributed under the terms of the MIT license. - */ - - -#include "GenioTabView.h" - -#include -#include -#include -#include -#include - -#include "GTab.h" - -class IndexGTab : public GTab { -public: - IndexGTab(BView* view, int32 index, tab_id id):GTab(view, id), fIndex(index){} - int32 fIndex; -}; - -BTab* -GenioTabView::_TabFromPoint(BPoint where, int32& index) -{ - index = _TabAt(where); - if (index < 0) - return nullptr; - return TabAt(index); -} - - -int32 -GenioTabView::_TabAt(BPoint where) -{ - for (int32 i = 0; i < CountTabs(); i++) { - if (TabFrame(i).Contains(where)) - return i; - } - return -1; -} - -#define TAB_DRAG 'TDRA' -#define ALPHA 230 - -#include -#include - - -bool -GenioTabView::InitiateDrag(BPoint where) -{ - uint32 index = _TabAt(where); - if (index < 0) - return false; - - BRect frame(TabFrame(index)); - BTab* tab = TabAt(index); - if (tab != nullptr) { - BMessage message(TAB_DRAG); - - message.AddPointer("genio_tab_view", this); - message.AddUInt32("tab_drag_affinity", fTabAffinity); - message.AddInt32("index", index); - - BRect updateRect = frame.OffsetToCopy(BPoint(0, 0)); - - BBitmap* dragBitmap = new BBitmap(updateRect, B_RGB32, true); - if (dragBitmap->IsValid()) { - BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); - dragBitmap->AddChild(view); - dragBitmap->Lock(); - tab->DrawTab(view, updateRect, B_TAB_FRONT, true); - - view->Sync(); - uint8* bits = (uint8*)dragBitmap->Bits(); - int32 height = (int32)dragBitmap->Bounds().Height() + 1; - int32 width = (int32)dragBitmap->Bounds().Width() + 1; - int32 bpr = dragBitmap->BytesPerRow(); - for (int32 y = 0; y < height; y++, bits += bpr) { - uint8* line = bits + 3; - for (uint8* end = line + 4 * width; line < end; line += 4) - *line = ALPHA; - } - dragBitmap->Unlock(); - } else { - delete dragBitmap; - dragBitmap = NULL; - } - - if (dragBitmap != NULL) { - DragMessage(&message, dragBitmap, B_OP_ALPHA, - BPoint(where.x - frame.left, where.y - frame.top)); - } else { - DragMessage(&message, frame, this); - } - - return true; - } - return false; -} - - -GenioTabView::GenioTabView(const char* name, tab_drag_affinity affinity, orientation orientation): - BTabView(name), - fTabAffinity(affinity), - fOrientation(orientation) -{ -} - - -void -GenioTabView::MouseDown(BPoint where) -{ - BTabView::MouseDown(where); - OnMouseDown(where); -} - - -void -GenioTabView::MouseUp(BPoint where) -{ - BTabView::MouseUp(where); - OnMouseUp(where); - if (fDropTargetHighlightFrame.IsValid()) { - Invalidate(fDropTargetHighlightFrame); - fDropTargetHighlightFrame = BRect(); - } -} - - -void -GenioTabView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) -{ - bool sameTabView = true; - if (dragMessage && - dragMessage->what == TAB_DRAG && - _ValidDragAndDrop(dragMessage, &sameTabView)) { - switch (transit) { - case B_ENTERED_VIEW: - case B_INSIDE_VIEW: - { - int32 fromIndex = dragMessage->GetInt32("index", -1); - int32 toIndex = _TabAt(where); - if (toIndex >= 0) { - if (fromIndex != toIndex || sameTabView == false) { - BRect highlightFrame = TabFrame(toIndex); - - if (fDropTargetHighlightFrame != highlightFrame) { - Invalidate(fDropTargetHighlightFrame); - fDropTargetHighlightFrame = highlightFrame; - Invalidate(fDropTargetHighlightFrame); - } - return; - } - } else { - float right = 0; - if (CountTabs() > 0) { - right = TabFrame(CountTabs()-1).right; - } - if (where.x < right) - return; - - BRect highlightFrame = Bounds(); - highlightFrame.left = right; - - if (fDropTargetHighlightFrame != highlightFrame) { - Invalidate(fDropTargetHighlightFrame); - fDropTargetHighlightFrame = highlightFrame; - Invalidate(fDropTargetHighlightFrame); - } - return; - } - } break; - default: - if (fDropTargetHighlightFrame.IsValid()) { - Invalidate(fDropTargetHighlightFrame); - fDropTargetHighlightFrame = BRect(); - } - break; - }; - } else { - BTabView::MouseMoved(where, transit, dragMessage); - OnMouseMoved(where); - if (fDropTargetHighlightFrame.IsValid()) { - Invalidate(fDropTargetHighlightFrame); - fDropTargetHighlightFrame = BRect(); - } - } -} - - -void -GenioTabView::MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView) -{ - GTab* fromTab = dynamic_cast(fromTabView->TabAt(from)); - if (!fromTab) - return; - - GTabContainer* fromContainer = dynamic_cast(fromTabView->BTabView::ViewForTab(from)); - if (fromContainer == nullptr) - return; - - BView* fromView = fromContainer->ContentView(); - if (!fromView) - return; - - fromView->RemoveSelf(); - - BString label = fromTab->Label(); //TODO copy all the props - fromTabView->RemoveTab(from); - GTab* indexTab = new IndexGTab(fromView, to, fromTab->Id()); - indexTab->SetLabel(label.String()); - _AddTab(indexTab); -} - -void -GenioTabView::AddTab(BView* target, BTab* tab) -{ - BTabView::AddTab(target, tab); -} - - -void -BTabView::AddTab(BView* target, BTab* tab) -{ - if (tab == NULL) - tab = new BTab(target); - else - tab->SetView(target); - - IndexGTab *gtab = dynamic_cast(tab); - int32 index = CountTabs(); - if (gtab != nullptr) { - if (gtab->fIndex < CountTabs()) - index = gtab->fIndex; - } -// printf("New Index to: %d\n", index); - if (fContainerView->GetLayout()) - fContainerView->GetLayout()->AddView(index, target); - fTabList->AddItem(tab, index); - - BTab::Private(tab).SetTabView(this); - - // When we haven't had a any tabs before, but are already attached to the - // window, select this one. - if (Window() != NULL) { - if (CountTabs() == 1) - Select(0); - else { - Select(index); - - // make the view visible through the layout if there is one - BCardLayout* layout - = dynamic_cast(fContainerView->GetLayout()); - if (layout != NULL) - layout->SetVisibleItem(index); - } - } -} - -void -GenioTabView::AddTab(BView* target, tab_id id) -{ - assert(fTabIdMap.contains(id) == false); - GTab* newTab = new GTab(target, id); - _AddTab(newTab); - -} - - -BTab* -GenioTabView::TabFromView(BView* view) const -{ - for (int32 i = 0; i < CountTabs(); i++) { - GTabContainer* fromContainer = dynamic_cast(BTabView::ViewForTab(i)); - if (fromContainer != nullptr && fromContainer->ContentView() == view) { - return TabAt(i); - } - } - return nullptr; -} - - -void -GenioTabView::SelectTab(tab_id id) -{ - /** DEBUG * - - for(const auto& [k, v] : fTabIdMap) { - printf("TabList: '%.4s' -> %p\n", (char *)&k, v); - }*/ - - if (fTabIdMap.contains(id)) { - BTab* tab = fTabIdMap[id]; - BTabView::Select(BTabView::IndexOf(tab)); - } -} - - -bool -GenioTabView::HasTab(tab_id id) -{ - return fTabIdMap.contains(id); -} - - -#include -void -GenioTabView::_ChangeGroupViewDirection(GTab* tab) -{ - GTabContainer* fromContainer = dynamic_cast(tab->View()); - if (!fromContainer) - return; - printf("fromContainer\n"); - - BView* view = fromContainer->ContentView(); - if (!view) - return; - printf("View\n"); - BLayout* layout = view->GetLayout(); - if (!layout) - return; - printf("Layout\n"); - BGroupLayout* grpLayout = dynamic_cast(layout); - if (!grpLayout) { - return; - } - printf("g layout\n"); - if (grpLayout->Orientation() != fOrientation) - { - grpLayout->SetOrientation(fOrientation); - } - - printf("same %d vs %d\n", grpLayout->Orientation(), fOrientation); -} - - -BTab* -GenioTabView::RemoveTab(int32 tabIndex) -{ - BTab* tab = BTabView::RemoveTab(tabIndex); - for(const auto& [k, v] : fTabIdMap) { - if (v == tab) { - fTabIdMap.erase(k); - break; - } - } - return tab; -} - - - -void -GenioTabView::_AddTab(GTab* tab) -{ - //experimental: let's try to improve the GroupView. - _ChangeGroupViewDirection(tab); - fTabIdMap[tab->Id()] = tab; - BTabView::AddTab(tab->View(), tab); - - _PrintMap(); -} - - -void -GenioTabView::_OnDrop(BMessage* msg) -{ - int32 dragIndex = msg->GetInt32("index", -1); - if (dragIndex < 0) - return; - - if (!_ValidDragAndDrop(msg)) - return; - - BPoint drop_point; - if (msg->FindPoint("_drop_point_", &drop_point) != B_OK) - return; - - int32 toIndex = _TabAt(ConvertFromScreen(drop_point)); - if (CountTabs() == 0) - toIndex = 0; - - if (toIndex < 0) { - if (drop_point.x < TabFrame(CountTabs()-1).right) - return; - toIndex = CountTabs(); - } - - GenioTabView* fromTabView = (GenioTabView*)msg->GetPointer("genio_tab_view", this); - - MoveTabs(dragIndex, toIndex, fromTabView); - Invalidate(); - if (fromTabView != this) - fromTabView->Invalidate(); -} - - -void -GenioTabView::MessageReceived(BMessage* msg) -{ - switch (msg->what) { - case TAB_DRAG: - { - _OnDrop(msg); - } break; - default: - BTabView::MessageReceived(msg); - break; - }; -} -/* -void -GenioTabView::AddTab(BView* target, BTab* tab) -{ - BTabView::AddTab(target, tab); -} -*/ -BRect -GenioTabView::DrawTabs() -{ - BRect rect = BTabView::DrawTabs(); - _DrawTabIndicator(); - return rect; -} - - -void -GenioTabView::_DrawTabIndicator() -{ - if (fDropTargetHighlightFrame.IsValid()) { - rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); - color.alpha = 170; - SetHighColor(color); - SetDrawingMode(B_OP_ALPHA); - FillRect(fDropTargetHighlightFrame); - } -} - -bool -GenioTabView::_ValidDragAndDrop(const BMessage* msg, bool* sameTabView) -{ - if (sameTabView) - *sameTabView = (msg->GetPointer("genio_tab_view", nullptr) == this); - - if (fTabAffinity == 0 && msg->GetPointer("genio_tab_view", nullptr) != this) - return false; - - if (msg->GetUInt32("tab_drag_affinity", 0) != fTabAffinity) - return false; - - return true; -} - - -void -GenioTabView::_PrintMap() -{ - for(const auto& [k, v] : fTabIdMap) { - printf("TabList: '%.4s' -> %p\n", (char *)&k, v); - } -} diff --git a/src/helpers/gtab/GenioTabView.h b/src/helpers/gtab/GenioTabView.h deleted file mode 100644 index fa8d8795..00000000 --- a/src/helpers/gtab/GenioTabView.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2024, Andrea Anzani - * All rights reserved. Distributed under the terms of the MIT license. - */ -#pragma once - - -#include -#include -#include -#include - -#include "Draggable.h" - -class GTab; - -typedef uint32 tab_drag_affinity; -typedef uint32 tab_id; - -typedef std::map IdMap; - -class GenioTabView : public BTabView, private Draggable { -public: - GenioTabView(const char* name, tab_drag_affinity affinity, orientation orientation = B_HORIZONTAL); - - virtual void MouseDown(BPoint where); - virtual void MouseUp(BPoint where); - virtual void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage); - virtual void MessageReceived(BMessage* msg); - - void AddTab(BView* target, tab_id id); - - BTab* TabFromView(BView* view) const; - - void SelectTab(tab_id id); - - bool HasTab(tab_id id); - - -private: - using BTabView::TabAt; - using BTabView::Select; - - BTab* RemoveTab(int32 tabIndex); - BView* ContainerView() const = delete; - BView* ViewForTab(int32 tabIndex) const = delete; - - void _AddTab(GTab* tab); - - virtual void AddTab(BView* target, BTab* tab); - virtual BRect DrawTabs(); - - void MoveTabs(uint32 from, uint32 to, GenioTabView* fromTabView); - bool InitiateDrag(BPoint where); - void _OnDrop(BMessage* msg); - - int32 _TabAt(BPoint where); - BTab* _TabFromPoint(BPoint where, int32& index); - void _DrawTabIndicator(); - bool _ValidDragAndDrop(const BMessage* msg, bool* sameTabView = nullptr); - - void _ChangeGroupViewDirection(GTab* tab); - - void _PrintMap(); - - BRect fDropTargetHighlightFrame; - tab_drag_affinity fTabAffinity; - orientation fOrientation; - IdMap fTabIdMap; - -}; - - diff --git a/src/helpers/gtab/TabButtons.h b/src/helpers/gtab/TabButtons.h new file mode 100644 index 00000000..607d9570 --- /dev/null +++ b/src/helpers/gtab/TabButtons.h @@ -0,0 +1,156 @@ +/* + * Copyright 2025, Andrea Anzani + * Original source code by: + * Copyright (C) 2010 Rene Gollent + * Copyright (C) 2010 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include +#include + + +class TabViewTools { + public: + static float DefaultTabHeigh() { + static float _heigh = -1.0; + if (_heigh == -1) { + font_height fh; + be_plain_font->GetHeight(&fh); + _heigh = ceilf(fh.ascent + fh.descent + fh.leading + + (be_control_look->DefaultLabelSpacing() * 1.3f)); + } + return _heigh; + } + + static float DefaultFontDescent() { + static float _desc = -1.0; + if (_desc == -1) { + font_height fh; + be_plain_font->GetHeight(&fh); + _desc = fh.descent; + } + return _desc; + } + + static void DrawTabBackground(BView* view, BRect& bounds, BRect& updateRect) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 borders = BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER; + be_control_look->DrawInactiveTab(view, bounds, updateRect, base, 0, borders); + } + static void DrawDroppingZone(BView* view, BRect rect) + { + rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); + color.alpha = 170; + view->SetHighColor(color); + view->SetDrawingMode(B_OP_ALPHA); + view->FillRect(rect); + } +}; + +class GTabButton : public BButton { +public: + GTabButton(const char* label = nullptr, BMessage* message = nullptr) + : BButton(label, message) + { + SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); + SetExplicitMaxSize(BSize(50, B_SIZE_UNSET)); + SetExplicitMinSize(BSize(50, B_SIZE_UNSET)); + SetExplicitPreferredSize(BSize(50, B_SIZE_UNSET)); + } + + virtual BSize MinSize() + { + return BSize(20, TabViewTools::DefaultTabHeigh()); + } + + virtual BSize MaxSize() + { + return MinSize(); + } + + virtual BSize PreferredSize() + { + return MinSize(); + } + + virtual void Draw(BRect updateRect) + { + BRect bounds(Bounds()); + TabViewTools::DrawTabBackground(this, bounds, updateRect); + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + if (IsEnabled()) { + uint32 flags = be_control_look->Flags(this); + rgb_color button = tint_color(base, 1.07); + be_control_look->DrawButtonBackground(this, bounds, updateRect, + button, flags, 0); + } + bounds.left = (bounds.left + bounds.right) / 2 - 6; + bounds.top = (bounds.top + bounds.bottom) / 2 - 6; + bounds.right = bounds.left + 12; + bounds.bottom = bounds.top + 12; + DrawSymbol(bounds, updateRect, base); + } + + virtual void DrawSymbol(BRect frame, const BRect& updateRect, + const rgb_color& base) + { + } + +}; + +class GTabMenuTabButton : public GTabButton { +public: + GTabMenuTabButton(BMessage* message) + : GTabButton(" ", message) + , fCloseTime(0) + { + } + + virtual void DrawSymbol(BRect frame, const BRect& updateRect, + const rgb_color& base) + { + float tint = IsEnabled() ? B_DARKEN_4_TINT : B_DARKEN_1_TINT; + be_control_look->DrawArrowShape(this, frame, updateRect, + base, BControlLook::B_DOWN_ARROW, 0, tint); + } + + virtual void MouseDown(BPoint point) + { + // Don't reopen the menu if it's already open or freshly closed. + bigtime_t clickSpeed = 2000000; + get_click_speed(&clickSpeed); + bigtime_t clickTime = Window()->CurrentMessage()->FindInt64("when"); + if (!IsEnabled() || (Value() == B_CONTROL_ON) + || clickTime < fCloseTime + clickSpeed) { + return; + } + + // Invoke must be called before setting B_CONTROL_ON + // for the button to stay "down" + Invoke(); + SetValue(B_CONTROL_ON); + } + + virtual void MouseUp(BPoint point) + { + // Do nothing + } + + void MenuClosed() + { + fCloseTime = system_time(); + SetValue(B_CONTROL_OFF); + } + +private: + bigtime_t fCloseTime; +}; + + + diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp new file mode 100644 index 00000000..9e731d4d --- /dev/null +++ b/src/helpers/gtab/TabsContainer.cpp @@ -0,0 +1,255 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ + + +#include "TabsContainer.h" +#include "GTab.h" +#include "GTabView.h" +#include + +#define FILLER_WEIGHT 0.2 + +TabsContainer::TabsContainer(GTabView* tabView, + tab_affinity affinity, + BMessage* message): + BGroupView(B_HORIZONTAL, 0.0f), + BInvoker(message, nullptr, nullptr), + fSelectedTab(nullptr), + fGTabView(tabView), + fTabShift(0), + fAffinity(affinity) +{ + SetFlags(Flags()|B_FRAME_EVENTS); + GroupLayout()->AddView(0, new Filler(this)); + GroupLayout()->SetItemWeight(0, FILLER_WEIGHT); + SetExplicitMinSize(BSize(50, TabViewTools::DefaultTabHeigh())); + SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); +} + + +void +TabsContainer::AddTab(GTab* tab, int32 index) +{ + if (index == -1) + index = CountTabs(); + + BLayoutItem* item = GroupLayout()->AddView(index, tab); + tab->SetLayoutItem (item); + + if (CountTabs() == 1) { + SelectTab(tab); + } + + ShiftTabs(0); +} + +int32 +TabsContainer::CountTabs() +{ + return GroupLayout()->CountItems() - 1; //exclude the Filler. +} + +GTab* +TabsContainer::TabAt(int32 index) +{ + if (index < 0 || index >= CountTabs()) + return nullptr; + + return dynamic_cast(GroupLayout()->ItemAt(index)->View()); +} + + +int32 +TabsContainer::IndexOfTab(GTab* tab) +{ + if (fSelectedTab == nullptr) + return -1; + return GroupLayout()->IndexOfItem(tab->LayoutItem()); +} + + +GTab* +TabsContainer::RemoveTab(GTab* tab) +{ + int32 selectedIndex = IndexOfTab(tab); + tab->LayoutItem()->RemoveSelf(); + tab->RemoveSelf(); + + if (CountTabs() == 0) { + SelectTab(nullptr); + } else if (selectedIndex >= CountTabs()) { + SelectTab(TabAt(CountTabs() - 1)); + } else { + SelectTab(TabAt(selectedIndex)); + } + + delete tab->LayoutItem(); + tab->SetLayoutItem(nullptr); + + //fix tab visibility + // TODO: this could be further improved by shifting according to the free + // available space. + int shift = 0; + if (fTabShift > 0 && fTabShift >= CountTabs()) { + shift -= 1; + } + ShiftTabs(shift); + + return tab; +} + + +GTab* +TabsContainer::SelectedTab() +{ + return fSelectedTab; +} + + +void +TabsContainer::SelectTab(GTab* tab, bool invoke) +{ + if (tab != fSelectedTab) { + if (fSelectedTab) + fSelectedTab->SetIsFront(false); + + fSelectedTab = tab; + + if (fSelectedTab) + fSelectedTab->SetIsFront(true); + + int32 index = IndexOfTab(fSelectedTab); + if (invoke && Message() && Target()) { + BMessage msg = *Message(); + msg.AddPointer("tab", fSelectedTab); + msg.AddInt32("index", IndexOfTab(fSelectedTab)); + Invoke(&msg); + } + + if (fTabShift >= index) { + ShiftTabs(index - fTabShift); + } else { + // let's ensure at least the tab's "middle point" + // is visible. + float middle = fSelectedTab->Frame().right - (fSelectedTab->Frame().Width()/2.0f); + if (middle > Bounds().right) { + int32 shift = 0; + for (int32 i = fTabShift; i< CountTabs();i++) { + GTab* nextTab = TabAt(i); + middle -= nextTab->Bounds().Width(); + shift++; + if (middle < Bounds().right) { + break; + } + } + ShiftTabs(shift); + } + } + } +} + + + +void +TabsContainer::ShiftTabs(int32 delta) +{ + int32 newShift = fTabShift + delta; + if (newShift < 0) + newShift = 0; + + int32 max = std::max(newShift, fTabShift); + + for (int32 i=0;iIsHidden() == false) + tab->Hide(); + } else { + if (tab->IsHidden() == true) + tab->Show(); + } + } + fTabShift = newShift; + _UpdateScrolls(); +} + + + +void +TabsContainer::MouseDown(GTab* tab, BPoint where, const int32 buttons) +{ + if(buttons & B_PRIMARY_MOUSE_BUTTON) { + SelectTab(tab); + } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { + if (Target()) { + BMessage msg(kTVCloseTab); + msg.AddPointer("tab", tab); + Invoke(&msg); + } + } +} + + + +void +TabsContainer::FrameResized(float w, float h) +{ + //Auto-scroll: + if (fTabShift > 0) { + int32 tox = 0; + GTab* last = TabAt(CountTabs()-1); + float right = last->Frame().right; + for (int32 i=fTabShift - 1;i>=0;i--){ + GTab* tab = TabAt(i); + right = right + tab->Frame().Width(); + if (right < w) + tox--; + else + break; + } + if (tox != 0) + ShiftTabs(tox); + } + //end + _UpdateScrolls(); + BGroupView::FrameResized(w,h); +} + +void +TabsContainer::OnDropTab(GTab* toTab, BMessage* message) +{ + GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); + TabsContainer* fromContainer = fromTab->Container(); + + if (fromTab == nullptr || fromContainer == nullptr || toTab == fromTab) + return; + + fGTabView->MoveTabs(fromTab, toTab, fromContainer); +} + + +void +TabsContainer::_PrintToStream() +{ + for (int32 i=0;iCountItems();i++) { + printf("%d) %s\n", i, GroupLayout()->ItemAt(i)->View()->Name()); + } +} + + + +void +TabsContainer::_UpdateScrolls() +{ + if (CountTabs() > 0) { + GroupLayout()->Relayout(true); + GTab* last = TabAt(CountTabs() - 1); + if(fGTabView != nullptr && last != nullptr) + fGTabView->UpdateScrollButtons(fTabShift != 0, last->Frame().right > Bounds().right); + } else { + fGTabView->UpdateScrollButtons(false, false); + } +} + diff --git a/src/helpers/gtab/TabsContainer.h b/src/helpers/gtab/TabsContainer.h new file mode 100644 index 00000000..ad58e3a9 --- /dev/null +++ b/src/helpers/gtab/TabsContainer.h @@ -0,0 +1,59 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include +#include "Draggable.h" +#include "GTabView.h" + +class GTab; + +class TabsContainer : public BGroupView, public BInvoker { +public: + + enum { kTVCloseTab = 'TVCt' }; + + TabsContainer(GTabView* tabView, + tab_affinity affinity = 0, + BMessage* message = nullptr); + + void AddTab(GTab* tab, int32 index = -1); + + int32 CountTabs(); + + GTab* TabAt(int32 index); + + GTab* RemoveTab(GTab* tab); //just remove, not delete. + + int32 IndexOfTab(GTab* tab); + + void ShiftTabs(int32 delta); // 0 to refresh the current state + + void MouseDown(GTab* tab, BPoint where, const int32 buttons); + + void FrameResized(float w, float h) override; + + void OnDropTab(GTab* toTab, BMessage* message); + + GTab* SelectedTab(); + + void SelectTab(GTab* tab, bool invoke = true); + + GTabView* GetGTabView() { return fGTabView; } + + tab_affinity GetAffinity() { return fAffinity; } + +private: + void _PrintToStream(); + void _UpdateScrolls(); + + GTab* fSelectedTab; + GTabView* fGTabView; + int32 fTabShift; + tab_affinity fAffinity; +}; diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index 513c0f97..b98da7d8 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -72,7 +72,8 @@ #include "TextUtils.h" #include "ToolsMenu.h" #include "Utils.h" - +#include "TabButtons.h" +#include "PanelTabManager.h" #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "GenioWindow" @@ -160,7 +161,6 @@ GenioWindow::GenioWindow(BRect frame) , fToolBar(nullptr) , fRootLayout(nullptr) , fEditorTabsGroup(nullptr) - , fProjectsTabView(nullptr) , fProjectsFolderBrowser(nullptr) , fProjectsFolderScroll(nullptr) , fActiveProject(nullptr) @@ -184,7 +184,6 @@ GenioWindow::GenioWindow(BRect frame) , fOpenProjectPanel(nullptr) , fOpenProjectFolderPanel(nullptr) , fImportResourcePanel(nullptr) - , fOutputTabView(nullptr) , fProblemsPanel(nullptr) , fBuildLogView(nullptr) , fMTermView(nullptr) @@ -192,9 +191,12 @@ GenioWindow::GenioWindow(BRect frame) , fSearchResultTab(nullptr) , fScreenMode(kDefault) , fDisableProjectNotifications(false) + , fPanelTabManager(nullptr) { gMainWindow = this; + fPanelTabManager = new PanelTabManager(); + #ifdef GDEBUG fTitlePrefix = ReadFileContent("revision.txt", 16); #endif @@ -287,9 +289,11 @@ GenioWindow::Show() BWindow::Show(); if (LockLooper()) { - _ShowView((BView*)fProjectsTabView, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); - _ShowView(fRightTabView, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); - _ShowView(fOutputTabView, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView("left_panels", gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView("right_panels", gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView("bottom_panels", gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + + _ShowView(fToolBar, gCFG["show_toolbar"], MSG_TOGGLE_TOOLBAR); _ShowView(fStatusView, gCFG["show_statusbar"], MSG_TOGGLE_STATUSBAR); @@ -314,6 +318,7 @@ GenioWindow::~GenioWindow() delete fSavePanel; delete fOpenProjectFolderPanel; delete fImportResourcePanel; + delete fPanelTabManager; gMainWindow = nullptr; } @@ -1317,10 +1322,10 @@ GenioWindow::_ToogleScreenMode(int32 action) fScreenModeSettings.MakeEmpty(); fScreenModeSettings["saved_frame"] = Frame(); fScreenModeSettings["saved_look"] = (int32)Look(); - fScreenModeSettings["show_projects"] = !fProjectsTabView->IsHidden(); - fScreenModeSettings["show_output"] = !fOutputTabView->IsHidden(); + fScreenModeSettings["show_projects"] = fPanelTabManager->IsPanelTabViewVisible("left_panels");//!fProjectsTabView->IsHidden(); + fScreenModeSettings["show_output"] = fPanelTabManager->IsPanelTabViewVisible("bottom_panels");//!fOutputTabView->IsHidden(); fScreenModeSettings["show_toolbar"] = !fToolBar->IsHidden(); - fScreenModeSettings["show_outline"] = !fRightTabView->IsHidden(); + fScreenModeSettings["show_outline"] = fPanelTabManager->IsPanelTabViewVisible("right_panels"); //!fRightTabView->IsHidden(); BScreen screen(this); fMenuBar->Hide(); @@ -1338,9 +1343,9 @@ GenioWindow::_ToogleScreenMode(int32 action) fScreenMode = kFullscreen; } else if (action == MSG_FOCUS_MODE) { _ShowView(fToolBar, false, MSG_TOGGLE_TOOLBAR); - _ShowView(fProjectsTabView, false, MSG_SHOW_HIDE_PROJECTS); - _ShowView(fRightTabView, false, MSG_SHOW_HIDE_OUTLINE); - _ShowView(fOutputTabView, false, MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView("left_panels", false, MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView("right_panels", false, MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView("bottom_panels", false, MSG_SHOW_HIDE_OUTPUT); fScreenMode = kFocus; } } else { // exit fullscreen @@ -1359,9 +1364,10 @@ GenioWindow::_ToogleScreenMode(int32 action) ActionManager::SetEnabled(MSG_SHOW_HIDE_OUTPUT, true); _ShowView(fToolBar, fScreenModeSettings["show_toolbar"], MSG_TOGGLE_TOOLBAR); - _ShowView(fProjectsTabView, fScreenModeSettings["show_projects"] , MSG_SHOW_HIDE_PROJECTS); - _ShowView(fRightTabView, fScreenModeSettings["show_outline"] , MSG_SHOW_HIDE_OUTLINE); - _ShowView(fOutputTabView, fScreenModeSettings["show_output"], MSG_SHOW_HIDE_OUTPUT); + + _ShowPanelTabView("left_panels", fScreenModeSettings["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView("right_panels", fScreenModeSettings["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView("bottom_panels", fScreenModeSettings["show_output"], MSG_SHOW_HIDE_OUTPUT); fScreenMode = kDefault; } @@ -1507,8 +1513,8 @@ GenioWindow::QuitRequested() if (fScreenMode != kDefault) _ToogleScreenMode(-1); - gCFG["show_projects"] = !fProjectsTabView->IsHidden(); - gCFG["show_output"] = !fOutputTabView->IsHidden(); + gCFG["show_projects"] = fPanelTabManager->IsPanelTabViewVisible("left_panels"); + gCFG["show_output"] = fPanelTabManager->IsPanelTabViewVisible("bottom_panels"); gCFG["show_toolbar"] = !fToolBar->IsHidden(); // Files to reopen @@ -2687,8 +2693,8 @@ GenioWindow::_InitCentralSplit() fTabManager = new EditorTabManager(BMessenger(this)); fTabManager->SetColorIndicatorAvailable(true); - fTabManager->GetTabContainerView()->SetExplicitMaxSize(BSize(B_SIZE_UNSET, fProjectsTabView->TabHeight())); - fTabManager->GetTabContainerView()->SetExplicitMinSize(BSize(B_SIZE_UNSET, fProjectsTabView->TabHeight())); + fTabManager->GetTabContainerView()->SetExplicitMaxSize(BSize(B_SIZE_UNSET, TabViewTools::DefaultTabHeigh())); + fTabManager->GetTabContainerView()->SetExplicitMinSize(BSize(B_SIZE_UNSET, TabViewTools::DefaultTabHeigh())); dirtyFrameHack = fTabManager->TabGroup()->Frame(); @@ -2718,6 +2724,14 @@ GenioWindow::_ShowView(BView* view, bool show, int32 msgWhat) ActionManager::SetPressed(msgWhat, !view->IsHidden()); } +void +GenioWindow::_ShowPanelTabView(const char* tabview_name, bool show, int32 msgWhat) +{ + fPanelTabManager->ShowPanelTabView(tabview_name, show); + if (msgWhat > -1) + ActionManager::SetPressed(msgWhat, fPanelTabManager->IsPanelTabViewVisible(tabview_name)); +} + void GenioWindow::_InitActions() @@ -3409,49 +3423,54 @@ GenioWindow::_InitToolbar() } -void +BView* GenioWindow::_InitOutputSplit() { // Output - fOutputTabView = new GenioTabView("OutputTabview", 'GTAB'); + BView* out = fPanelTabManager->CreatePanelTabView("bottom_panels", B_HORIZONTAL); - fProblemsPanel = new ProblemsPanel(fOutputTabView); + fProblemsPanel = new ProblemsPanel(fPanelTabManager, kTabProblems); fBuildLogView = new ConsoleIOView(B_TRANSLATE("Build log"), BMessenger(this)); fMTermView = new MTermView(B_TRANSLATE("Console I/O"), BMessenger(this)); - fSearchResultTab = new SearchResultTab(fOutputTabView); + fSearchResultTab = new SearchResultTab(fPanelTabManager, kTabSearchResult); + + fPanelTabManager->AddPanel("bottom_panels", fProblemsPanel, kTabProblems); + fPanelTabManager->AddPanel("bottom_panels", fBuildLogView, kTabBuildLog); + fPanelTabManager->AddPanel("bottom_panels", fMTermView, kTabOutputLog); + fPanelTabManager->AddPanel("bottom_panels", fSearchResultTab, kTabSearchResult); - fOutputTabView->AddTab(fProblemsPanel, kTabProblems); - fOutputTabView->AddTab(fBuildLogView, kTabBuildLog); - fOutputTabView->AddTab(fMTermView, kTabOutputLog); - fOutputTabView->AddTab(fSearchResultTab, kTabSearchResult); + return out; } -void +BView* GenioWindow::_InitLeftSplit() { // Projects View - fProjectsTabView = new GenioTabView("ProjectsTabview", 'GTAB', B_VERTICAL); + BView* out = fPanelTabManager->CreatePanelTabView("left_panels", B_VERTICAL); fProjectsFolderBrowser = new ProjectBrowser(); - fProjectsTabView->AddTab(fProjectsFolderBrowser, kTabProjectBrowser); - - // Source Control fSourceControlPanel = new SourceControlPanel(); - fProjectsTabView->AddTab(fSourceControlPanel, kTabSourceControl); + fPanelTabManager->AddPanel("left_panels", fProjectsFolderBrowser, kTabProjectBrowser); + fPanelTabManager->AddPanel("left_panels", fSourceControlPanel, kTabSourceControl); + + return out; } -void +BView* GenioWindow::_InitRightSplit() { // Outline view - fRightTabView = new GenioTabView("OutlineTabview", 'GTAB', B_VERTICAL); + BView* out = fPanelTabManager->CreatePanelTabView("right_panels", B_VERTICAL); + fFunctionsOutlineView = new FunctionsOutlineView(); - fRightTabView->AddTab(fFunctionsOutlineView, kTabOutlineView); + fPanelTabManager->AddPanel("right_panels", fFunctionsOutlineView, kTabOutlineView); + + return out; } @@ -3459,10 +3478,10 @@ void GenioWindow::_InitWindow() { _InitToolbar(); - _InitLeftSplit(); + BView* projectsTabView = _InitLeftSplit(); _InitCentralSplit(); - _InitRightSplit(); - _InitOutputSplit(); + BView* rightTabView = _InitRightSplit(); + BView* outputTabView = _InitOutputSplit(); // Layout fRootLayout = BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) @@ -3472,11 +3491,11 @@ GenioWindow::_InitWindow() .AddSplit(B_VERTICAL, 0.0f) // output split .SetInsets(-2.0f, 0.0f, -2.0f, -2.0f) .AddSplit(B_HORIZONTAL, 0.0f) // sidebar split - .Add(fProjectsTabView, kProjectsWeight) + .Add(projectsTabView, kProjectsWeight) .Add(fEditorTabsGroup, kEditorWeight) // Editor - .Add(fRightTabView, 1) + .Add(rightTabView, 1) .End() // sidebar split - .Add(fOutputTabView, kOutputWeight) + .Add(outputTabView, kOutputWeight) .End() // output split .Add(fStatusView = new GlobalStatusView()) ; @@ -4192,25 +4211,10 @@ GenioWindow::_RunTarget() void GenioWindow::_ShowOutputTab(tab_id id) { - if (!_ShowTab (id, fOutputTabView)){ - if(!_ShowTab (id, fProjectsTabView)) { - _ShowTab (id, fRightTabView); - } - } + fPanelTabManager->ShowTab(id); } -bool -GenioWindow::_ShowTab(tab_id id, GenioTabView* tabView) -{ - if (tabView->HasTab(id)) { - if (tabView->IsHidden()) - tabView ->Show(); - tabView->SelectTab(id); - return true; - } - return false; -} void GenioWindow::_UpdateFindMenuItems(const BString& text) @@ -4547,11 +4551,11 @@ GenioWindow::_HandleConfigurationChanged(BMessage* message) bool same = ((bool)gCFG["show_white_space"] && (bool)gCFG["show_line_endings"]); ActionManager::SetPressed(MSG_TOGGLE_SPACES_ENDINGS, same); } else if (key.Compare("show_projects") == 0) { - _ShowView(fProjectsTabView, bool(gCFG["show_projects"]), MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView("left_panels", gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); } else if (key.Compare("show_outline") == 0) { - _ShowView(fRightTabView, bool(gCFG["show_outline"]), MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView("right_panels", gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); } else if (key.Compare("show_output") == 0) { - _ShowView(fOutputTabView, bool(gCFG["show_output"]), MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView("bottom_panels", gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); } else if (key.Compare("show_toolbar") == 0) { _ShowView(fToolBar, bool(gCFG["show_toolbar"]), MSG_TOGGLE_TOOLBAR); } else if (key.Compare("show_statusbar") == 0) { diff --git a/src/ui/GenioWindow.h b/src/ui/GenioWindow.h index 7226dda0..e6831b20 100644 --- a/src/ui/GenioWindow.h +++ b/src/ui/GenioWindow.h @@ -11,7 +11,7 @@ #include #include "GMessage.h" -#include "GenioTabView.h" +#include "PanelTabManager.h" enum scree_mode { @@ -42,6 +42,7 @@ class SourceControlPanel; class TemplatesMenu; class ToolBar; class MTermView; +class PanelTabManager; class GenioWindow : public BWindow { public: @@ -109,9 +110,9 @@ class GenioWindow : public BWindow { void _InitCentralSplit(); void _InitCommandRunToolbar(); void _InitMenu(); - void _InitOutputSplit(); - void _InitLeftSplit(); - void _InitRightSplit(); + BView* _InitOutputSplit(); + BView* _InitLeftSplit(); + BView* _InitRightSplit(); void _InitToolbar(); void _InitWindow(); @@ -145,7 +146,6 @@ class GenioWindow : public BWindow { void _RunTarget(); void _ShowOutputTab(tab_id id); - bool _ShowTab(tab_id id, GenioTabView* tabView); void _UpdateFindMenuItems(const BString& text); void _UpdateRecentCommands(const BString& text); @@ -156,6 +156,7 @@ class GenioWindow : public BWindow { void _UpdateTabChange(Editor*, const BString& caller = ""); void _InitActions(); void _ShowView(BView*, bool show, int32 msgWhat = -1); + void _ShowPanelTabView(const char* name, bool show, int32 msgWhat = -1); status_t _AlertInvalidBuildConfig(BString text); void _CloseMultipleTabs(BMessage* msg); void _HandleConfigurationChanged(BMessage* msg); @@ -205,9 +206,6 @@ class GenioWindow : public BWindow { BGroupLayout* fEditorTabsGroup; - // Left panels - GenioTabView* fProjectsTabView; - ProjectBrowser* fProjectsFolderBrowser; BScrollView* fProjectsFolderScroll; @@ -217,7 +215,6 @@ class GenioWindow : public BWindow { ProjectFolder *fActiveProject; // Right panels - GenioTabView* fRightTabView; FunctionsOutlineView* fFunctionsOutlineView; // Editor group @@ -246,7 +243,6 @@ class GenioWindow : public BWindow { BFilePanel* fImportResourcePanel; // Bottom panels - GenioTabView* fOutputTabView; ProblemsPanel* fProblemsPanel; ConsoleIOView* fBuildLogView; MTermView* fMTermView; @@ -260,6 +256,7 @@ class GenioWindow : public BWindow { #ifdef GDEBUG BString fTitlePrefix; #endif + PanelTabManager* fPanelTabManager; }; diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp new file mode 100644 index 00000000..cd47e468 --- /dev/null +++ b/src/ui/PanelTabManager.cpp @@ -0,0 +1,195 @@ +/* + * Copyright 2024, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ + + +#include "PanelTabManager.h" +#include "GTabView.h" +#include "GTab.h" +#include + + + +class GTabID : public GTab { + public: + GTabID(tab_id id, const char* label, TabsContainer* container): + GTab(label, container), fId(id) + { + } + tab_id GetID() { return fId; } + private: + tab_id fId; +}; + +struct tab_info { + GTabID* tab; + BView* view; +}; +typedef std::map TabIdMap; + + +class PanelTabView : public GTabView { +public: + PanelTabView(PanelTabManager* manager, const char* name, tab_affinity affinity, orientation orientation): + GTabView(name, affinity, orientation) + { + } + + void AddTab(BView* panel, tab_id id) + { + GTabID* tab = new GTabID(id, panel->Name(), Container()); + GTabView::AddTab(tab, panel); + } + + bool HasTab(tab_id id) { + return fIdMap.contains(id); + } + + void SelectTab(tab_id id) { + assert(fIdMap.contains(id) == true); + GTabView::SelectTab(fIdMap[id].tab); + } + + void SetLabelForTab(tab_id id, const char* label) { + assert(fIdMap.contains(id) == true); + fIdMap[id].tab->SetLabel(label); + fIdMap[id].tab->Invalidate(); + } + + + +protected: + virtual void OnTabRemoved(GTab* _tab) override + { + GTabID* tab = dynamic_cast(_tab); +/* + if (fIdMap.contains(tab->GetID()) == false) + { + for(const auto& info:fIdMap) { + printf("R %s: %d [%s] (vs %d)\n", Name(), info.first, info.second.view->Name(), tab->GetID()); + } + } +*/ + assert(tab != nullptr && fIdMap.contains(tab->GetID()) == true); + fIdMap.erase(tab->GetID()); + } + virtual void OnTabAdded(GTab* _tab, BView* panel) override + { + GTabID* tab = dynamic_cast(_tab); +/* + if (fIdMap.contains(tab->GetID()) == true) + { + for(const auto& info:fIdMap) { + printf("A %s: %d [%s] (vs %d)\n", Name(), info.first, info.second.view->Name(), tab->GetID()); + } + } +*/ + assert(tab != nullptr && fIdMap.contains(tab->GetID()) == false); + fIdMap[tab->GetID()] = { tab, panel }; + } + + GTab* CreateTabView(GTab* clone) override + { + GTabID* tab = dynamic_cast(clone); + return new GTabID(tab->GetID(), tab->Label().String(), Container());; + } + +private: + TabIdMap fIdMap; +}; + +PanelTabManager::PanelTabManager() +{ +} + +BView* +PanelTabManager::CreatePanelTabView(const char* tabview_name, orientation orientation) +{ + PanelTabView* tabView = new PanelTabView(this, tabview_name, 'GPAF', orientation); + fTVList[tabview_name] = { tabView }; +/* + for (const auto& info:fTVList) { + printf("CreatePanel %s %p\n", info.second->Name(), tabView ); + } +*/ + return tabView; +} + + +void +PanelTabManager::AddPanel(const char* tabview_name, BView* panel, tab_id id) +{ + PanelTabView* tabview = GetPanelTabView(tabview_name); + assert (tabview != nullptr); + + tabview->AddTab(panel, id); + +} + + +void +PanelTabManager::SelectTab(tab_id id) +{ + for (const auto panel:fTVList) { + if (panel.second->HasTab(id)) { + panel.second->SelectTab(id); + return; + } + } +} + + +void +PanelTabManager::ShowTab(tab_id id) +{ + for (const auto panel:fTVList) { + if (panel.second->HasTab(id)) { + if (panel.second->IsHidden()) + panel.second->Show(); + panel.second->SelectTab(id); + return; + } + } +} + + +void +PanelTabManager::SetLabelForTab(tab_id id, const char* label) +{ + for (const auto panel:fTVList) { + if (panel.second->HasTab(id)) { + panel.second->SetLabelForTab(id, label); + return; + } + } +} + + +void +PanelTabManager::ShowPanelTabView(const char* tabview_name, bool show) +{ + PanelTabView* tabview = GetPanelTabView(tabview_name); + + if (show == true && tabview->IsHidden()) + tabview->Show(); + if (show == false && !tabview->IsHidden()) + tabview->Hide(); +} + + + +bool +PanelTabManager::IsPanelTabViewVisible(const char* tabview_name) +{ + return !GetPanelTabView(tabview_name)->IsHidden(); +} + + + +PanelTabView* +PanelTabManager::GetPanelTabView(const char* sname) +{ + assert(fTVList.contains(sname) == true); + return fTVList[sname]; +} diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h new file mode 100644 index 00000000..b20ec2cf --- /dev/null +++ b/src/ui/PanelTabManager.h @@ -0,0 +1,44 @@ +/* + * Copyright 2025, Andrea Anzani + * All rights reserved. Distributed under the terms of the MIT license. + */ +#pragma once + + +#include +#include +#include +#include + +class GTabID; +class BView; +class PanelTabView; + +typedef uint32 tab_id; + +typedef std::map TabViewList; + + +class PanelTabManager { +public: + PanelTabManager(); + + BView* CreatePanelTabView(const char* tabview_name, orientation orientation); + + void AddPanel(const char* tabview_name, BView* panel, tab_id id); + + void SelectTab(tab_id id); + void ShowTab(tab_id id); + + void SetLabelForTab(tab_id id, const char* label); + + void ShowPanelTabView(const char* tabview_name, bool visible); + bool IsPanelTabViewVisible(const char* tabview_name); + + +private: + PanelTabView* GetPanelTabView(const char* name); + TabViewList fTVList; +}; + + diff --git a/src/ui/ProblemsPanel.cpp b/src/ui/ProblemsPanel.cpp index a29b19ec..60b71364 100644 --- a/src/ui/ProblemsPanel.cpp +++ b/src/ui/ProblemsPanel.cpp @@ -46,9 +46,9 @@ class RangeRow : public BRow { #define ProblemLabel B_TRANSLATE("Problems") -ProblemsPanel::ProblemsPanel(GenioTabView* tabView): BColumnListView(ProblemLabel, +ProblemsPanel::ProblemsPanel(PanelTabManager* panelTabManager, tab_id id): BColumnListView(ProblemLabel, B_NAVIGABLE, B_FANCY_BORDER, true) - , fTabView(tabView) + , fPanelTabManager(panelTabManager), fTabId(id) { AddColumn(new BStringColumn( B_TRANSLATE("Category"), @@ -188,7 +188,7 @@ ProblemsPanel::ClearProblems() void ProblemsPanel::_UpdateTabLabel() { - if (!fTabView) + if (!fPanelTabManager) return; BString label = ProblemLabel; @@ -198,7 +198,5 @@ ProblemsPanel::_UpdateTabLabel() label.Append(")"); } - BTab* tab = fTabView->TabFromView(this); - if (tab) - tab->SetLabel(label.String()); + fPanelTabManager->SetLabelForTab(fTabId, label.String()); } diff --git a/src/ui/ProblemsPanel.h b/src/ui/ProblemsPanel.h index 187a4eba..fd747a24 100644 --- a/src/ui/ProblemsPanel.h +++ b/src/ui/ProblemsPanel.h @@ -5,14 +5,15 @@ #pragma once #include -#include "GenioTabView.h" +#include "PanelTabManager.h" + class BPopUpMenu; class BMenuItem; class BTabView; class Editor; class ProblemsPanel : public BColumnListView { public: - ProblemsPanel(GenioTabView*); + ProblemsPanel(PanelTabManager*, tab_id id); virtual ~ProblemsPanel(); void UpdateProblems(Editor* editor); @@ -24,7 +25,8 @@ class ProblemsPanel : public BColumnListView { private: void _UpdateTabLabel(); - GenioTabView* fTabView; + PanelTabManager* fPanelTabManager; BPopUpMenu* fPopUpMenu; BMenuItem* fQuickFixItem; + tab_id fTabId; }; diff --git a/src/ui/SearchResultPanel.cpp b/src/ui/SearchResultPanel.cpp index 923e4abd..91b12889 100644 --- a/src/ui/SearchResultPanel.cpp +++ b/src/ui/SearchResultPanel.cpp @@ -67,12 +67,13 @@ class BFontStringColumn : public BStringColumn { #define SearchResultPanelLabel B_TRANSLATE("Search results") -SearchResultPanel::SearchResultPanel(GenioTabView* tabView) +SearchResultPanel::SearchResultPanel(PanelTabManager* panelTabManager, tab_id id) : BColumnListView(SearchResultPanelLabel, B_NAVIGABLE, B_FANCY_BORDER, true), fGrepThread(nullptr), - fTabView(tabView), - fCountResults(0) + fPanelTabManager(panelTabManager), + fCountResults(0), + fTabId(id) { AddColumn(new BFontStringColumn(B_TRANSLATE("Location"), 1000.0, 20.0, 2000.0, 0), kLocationColumn); @@ -82,12 +83,10 @@ SearchResultPanel::SearchResultPanel(GenioTabView* tabView) void SearchResultPanel::SetTabLabel(BString label) { - if (!fTabView) + if (!fPanelTabManager) return; - BTab* tab = fTabView->TabFromView(this->Parent()); - if (tab) - tab->SetLabel(label.String()); + fPanelTabManager->SetLabelForTab(fTabId, label); } diff --git a/src/ui/SearchResultPanel.h b/src/ui/SearchResultPanel.h index ff729742..3ee3c5b6 100644 --- a/src/ui/SearchResultPanel.h +++ b/src/ui/SearchResultPanel.h @@ -7,15 +7,15 @@ #include #include -#include "GenioTabView.h" #include "GrepThread.h" +#include "PanelTabManager.h" // For now this is specific to manage only the FindInFiles results // Can be extended to handle more generic 'search' results (find references) class SearchResultPanel : public BColumnListView { public: - SearchResultPanel(GenioTabView*); + SearchResultPanel(PanelTabManager*, tab_id id); void StartSearch(BString command, BString projectPath); @@ -31,8 +31,9 @@ class SearchResultPanel : public BColumnListView { void UpdateSearch(BMessage* msg); GrepThread* fGrepThread; BString fProjectPath; - GenioTabView* fTabView; + PanelTabManager* fPanelTabManager; int32 fCountResults; + tab_id fTabId; }; diff --git a/src/ui/SearchResultTab.cpp b/src/ui/SearchResultTab.cpp index 142baf93..e8930d8e 100644 --- a/src/ui/SearchResultTab.cpp +++ b/src/ui/SearchResultTab.cpp @@ -32,11 +32,10 @@ static constexpr auto kFindReplaceMinBytes = 32; static constexpr uint32 kSelectProject ='PRJX'; -SearchResultTab::SearchResultTab(GenioTabView* tabView) +SearchResultTab::SearchResultTab(PanelTabManager* panelTabManager, tab_id id) : BGroupView(B_VERTICAL, 0.0f), fSearchResultPanel(nullptr), - fTabView(tabView), fSelectedProject(nullptr) { fProjectMenu = new OptionList("ProjectMenu", @@ -60,7 +59,7 @@ SearchResultTab::SearchResultTab(GenioTabView* tabView) fFindWholeWordCheck = new BCheckBox(B_TRANSLATE_COMMENT("Whole word", "Short as possible."), nullptr); - fSearchResultPanel = new SearchResultPanel(fTabView); + fSearchResultPanel = new SearchResultPanel(panelTabManager, id); BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0.0f) .Add(fSearchResultPanel, 3.0f) .AddGroup(B_VERTICAL, 0.0f) diff --git a/src/ui/SearchResultTab.h b/src/ui/SearchResultTab.h index 6b65608d..3e3fb640 100644 --- a/src/ui/SearchResultTab.h +++ b/src/ui/SearchResultTab.h @@ -11,7 +11,7 @@ #include "OptionList.h" #include "ProjectFolder.h" #include "SearchResultPanel.h" -#include "GenioTabView.h" +#include "PanelTabManager.h" class ToolBar; @@ -19,7 +19,7 @@ using Genio::UI::OptionList; class SearchResultTab : public BGroupView { public: - SearchResultTab(GenioTabView*); + SearchResultTab(PanelTabManager* panelTabManager, tab_id id); ~SearchResultTab(); void SetAndStartSearch(BString text, bool wholeWord, bool caseSensitive, ProjectFolder* project); void AttachedToWindow(); @@ -32,7 +32,6 @@ class SearchResultTab : public BGroupView { Genio::UI::OptionList* fProjectMenu; SearchResultPanel* fSearchResultPanel; - GenioTabView* fTabView; ProjectFolder* fSelectedProject; ToolBar* fFindGroup; BTextControl* fFindTextControl; From 459757f513b63032154db31a7751d4ad80d091a6 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sat, 11 Jan 2025 12:05:39 +0100 Subject: [PATCH 05/29] using constand to address tabviews --- src/ui/GenioWindow.cpp | 57 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index 6fc83cdc..e8c7292a 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -113,6 +113,9 @@ enum { }; +static constexpr const char* kTabViewLeft = "left_panels"; +static constexpr const char* kTabViewRight = "right_panels"; +static constexpr const char* kTabViewBottom = "bottom_panels"; static bool AcceptsCopyPaste(BView* view) @@ -289,9 +292,9 @@ GenioWindow::Show() BWindow::Show(); if (LockLooper()) { - _ShowPanelTabView("left_panels", gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView("right_panels", gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView("bottom_panels", gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); _ShowView(fToolBar, gCFG["show_toolbar"], MSG_TOGGLE_TOOLBAR); @@ -1322,10 +1325,10 @@ GenioWindow::_ToogleScreenMode(int32 action) fScreenModeSettings.MakeEmpty(); fScreenModeSettings["saved_frame"] = Frame(); fScreenModeSettings["saved_look"] = (int32)Look(); - fScreenModeSettings["show_projects"] = fPanelTabManager->IsPanelTabViewVisible("left_panels");//!fProjectsTabView->IsHidden(); - fScreenModeSettings["show_output"] = fPanelTabManager->IsPanelTabViewVisible("bottom_panels");//!fOutputTabView->IsHidden(); + fScreenModeSettings["show_projects"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewLeft);//!fProjectsTabView->IsHidden(); + fScreenModeSettings["show_output"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewBottom);//!fOutputTabView->IsHidden(); fScreenModeSettings["show_toolbar"] = !fToolBar->IsHidden(); - fScreenModeSettings["show_outline"] = fPanelTabManager->IsPanelTabViewVisible("right_panels"); //!fRightTabView->IsHidden(); + fScreenModeSettings["show_outline"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewRight); //!fRightTabView->IsHidden(); BScreen screen(this); fMenuBar->Hide(); @@ -1343,9 +1346,9 @@ GenioWindow::_ToogleScreenMode(int32 action) fScreenMode = kFullscreen; } else if (action == MSG_FOCUS_MODE) { _ShowView(fToolBar, false, MSG_TOGGLE_TOOLBAR); - _ShowPanelTabView("left_panels", false, MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView("right_panels", false, MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView("bottom_panels", false, MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, false, MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView(kTabViewRight, false, MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView(kTabViewBottom, false, MSG_SHOW_HIDE_OUTPUT); fScreenMode = kFocus; } } else { // exit fullscreen @@ -1365,9 +1368,9 @@ GenioWindow::_ToogleScreenMode(int32 action) _ShowView(fToolBar, fScreenModeSettings["show_toolbar"], MSG_TOGGLE_TOOLBAR); - _ShowPanelTabView("left_panels", fScreenModeSettings["show_projects"], MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView("right_panels", fScreenModeSettings["show_outline"], MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView("bottom_panels", fScreenModeSettings["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, fScreenModeSettings["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView(kTabViewRight, fScreenModeSettings["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView(kTabViewBottom, fScreenModeSettings["show_output"], MSG_SHOW_HIDE_OUTPUT); fScreenMode = kDefault; } @@ -1513,8 +1516,8 @@ GenioWindow::QuitRequested() if (fScreenMode != kDefault) _ToogleScreenMode(-1); - gCFG["show_projects"] = fPanelTabManager->IsPanelTabViewVisible("left_panels"); - gCFG["show_output"] = fPanelTabManager->IsPanelTabViewVisible("bottom_panels"); + gCFG["show_projects"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewLeft); + gCFG["show_output"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewBottom); gCFG["show_toolbar"] = !fToolBar->IsHidden(); // Files to reopen @@ -3427,7 +3430,7 @@ BView* GenioWindow::_InitOutputSplit() { // Output - BView* out = fPanelTabManager->CreatePanelTabView("bottom_panels", B_HORIZONTAL); + BView* out = fPanelTabManager->CreatePanelTabView(kTabViewBottom, B_HORIZONTAL); fProblemsPanel = new ProblemsPanel(fPanelTabManager, kTabProblems); @@ -3437,10 +3440,10 @@ GenioWindow::_InitOutputSplit() fSearchResultTab = new SearchResultTab(fPanelTabManager, kTabSearchResult); - fPanelTabManager->AddPanel("bottom_panels", fProblemsPanel, kTabProblems); - fPanelTabManager->AddPanel("bottom_panels", fBuildLogView, kTabBuildLog); - fPanelTabManager->AddPanel("bottom_panels", fMTermView, kTabOutputLog); - fPanelTabManager->AddPanel("bottom_panels", fSearchResultTab, kTabSearchResult); + fPanelTabManager->AddPanel(kTabViewBottom, fProblemsPanel, kTabProblems); + fPanelTabManager->AddPanel(kTabViewBottom, fBuildLogView, kTabBuildLog); + fPanelTabManager->AddPanel(kTabViewBottom, fMTermView, kTabOutputLog); + fPanelTabManager->AddPanel(kTabViewBottom, fSearchResultTab, kTabSearchResult); return out; } @@ -3450,12 +3453,12 @@ BView* GenioWindow::_InitLeftSplit() { // Projects View - BView* out = fPanelTabManager->CreatePanelTabView("left_panels", B_VERTICAL); + BView* out = fPanelTabManager->CreatePanelTabView(kTabViewLeft, B_VERTICAL); fProjectsFolderBrowser = new ProjectBrowser(); fSourceControlPanel = new SourceControlPanel(); - fPanelTabManager->AddPanel("left_panels", fProjectsFolderBrowser, kTabProjectBrowser); - fPanelTabManager->AddPanel("left_panels", fSourceControlPanel, kTabSourceControl); + fPanelTabManager->AddPanel(kTabViewLeft, fProjectsFolderBrowser, kTabProjectBrowser); + fPanelTabManager->AddPanel(kTabViewLeft, fSourceControlPanel, kTabSourceControl); return out; } @@ -3465,10 +3468,10 @@ BView* GenioWindow::_InitRightSplit() { // Outline view - BView* out = fPanelTabManager->CreatePanelTabView("right_panels", B_VERTICAL); + BView* out = fPanelTabManager->CreatePanelTabView(kTabViewRight, B_VERTICAL); fFunctionsOutlineView = new FunctionsOutlineView(); - fPanelTabManager->AddPanel("right_panels", fFunctionsOutlineView, kTabOutlineView); + fPanelTabManager->AddPanel(kTabViewRight, fFunctionsOutlineView, kTabOutlineView); return out; } @@ -4554,11 +4557,11 @@ GenioWindow::_HandleConfigurationChanged(BMessage* message) bool same = ((bool)gCFG["show_white_space"] && (bool)gCFG["show_line_endings"]); ActionManager::SetPressed(MSG_TOGGLE_SPACES_ENDINGS, same); } else if (key.Compare("show_projects") == 0) { - _ShowPanelTabView("left_panels", gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); } else if (key.Compare("show_outline") == 0) { - _ShowPanelTabView("right_panels", gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); } else if (key.Compare("show_output") == 0) { - _ShowPanelTabView("bottom_panels", gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); } else if (key.Compare("show_toolbar") == 0) { _ShowView(fToolBar, bool(gCFG["show_toolbar"]), MSG_TOGGLE_TOOLBAR); } else if (key.Compare("show_statusbar") == 0) { From b2f24edbf0afd7e6d1cf8eecca0833fac63f543c Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Sat, 11 Jan 2025 12:19:27 +0100 Subject: [PATCH 06/29] GTab: center labels --- src/helpers/gtab/GTab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index 48f4bc2b..d0bf87de 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -153,7 +153,7 @@ GTab::DrawContents(BView* owner, BRect frame, const BRect& updateRect, bool isFr { rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); be_control_look->DrawLabel(owner, fLabel.String(), frame, updateRect, - base, 0, BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); + base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE)); } From 14a8eebc0c623aff98752686f8ca311dcbebedd7 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sat, 11 Jan 2025 12:19:56 +0100 Subject: [PATCH 07/29] removed useless boolean --- src/helpers/gtab/GTab.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 54fc625a..69b5d2f3 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -262,7 +262,6 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { } private: - bool fTabDragging; BMessageRunner* fRunner; }; From b71c486154523d901d4006f00250f46141588779 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Sat, 11 Jan 2025 12:32:14 +0100 Subject: [PATCH 08/29] Small style fixes (not completed) Also removed reduntant "virtual" (override is enough) --- src/helpers/gtab/GTab.cpp | 61 +++++++++++++++++------------- src/helpers/gtab/GTab.h | 78 ++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 68 deletions(-) diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index d0bf87de..47322da4 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -5,19 +5,21 @@ #include "GTab.h" + +#include #include + #include "TabsContainer.h" -#include + #define TAB_DRAG 'DRAG' #define ALPHA 200 - bool GTabDropZone::_ValidDragAndDrop(const BMessage* message) { - GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); + GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); TabsContainer* fromContainer = fromTab->Container(); if (fromTab == nullptr || fromContainer == nullptr) @@ -49,13 +51,11 @@ GTabDropZone::DropZoneMouseMoved(BView* view, StartDragging(view); return true; } - break; default: StopDragging(view); - break; - }; + break; + } } else { - OnMouseMoved(where); StopDragging(view); } @@ -76,9 +76,13 @@ GTabDropZone::DropZoneMessageReceived(BMessage* message) +// GTab GTab::GTab(const char* label, TabsContainer* container) - : BView("_tabView_", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), - GTabDropZone(container), fIsFront(false), fLabel(label)/*, fTabDragging(false)*/ + : + BView("_tabView_", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), + GTabDropZone(container), + fIsFront(false), + fLabel(label)/*, fTabDragging(false)*/ { } @@ -96,6 +100,7 @@ GTab::MinSize() return size; } + BSize GTab::MaxSize() { @@ -111,6 +116,7 @@ GTab::Draw(BRect updateRect) DropZoneDraw(this, Bounds()); } + void GTab::DrawTab(BView* owner, BRect updateRect) { @@ -132,6 +138,7 @@ GTab::DrawTab(BView* owner, BRect updateRect) DrawContents(owner, frame, updateRect, fIsFront); } + void GTab::DrawBackground(BView* owner, BRect frame, const BRect& updateRect, bool isFront) { @@ -161,8 +168,9 @@ void GTab::MouseDown(BPoint where) { BMessage* msg = Window()->CurrentMessage(); - if (!msg) + if (msg == nullptr) return; + const int32 buttons = msg->GetInt32("buttons", 0); if (Container()) @@ -198,7 +206,6 @@ GTab::MessageReceived(BMessage* message) } - bool GTab::InitiateDrag(BPoint where) { @@ -230,10 +237,10 @@ GTab::InitiateDrag(BPoint where) dragBitmap->Unlock(); } else { delete dragBitmap; - dragBitmap = NULL; + dragBitmap = nullptr; } const BRect& frame = updateRect; - if (dragBitmap != NULL) { + if (dragBitmap != nullptr) { DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(where.x - frame.left, where.y - frame.top)); } else { @@ -256,12 +263,14 @@ GTab::SetIsFront(bool isFront) Invalidate(); } + bool GTab::IsFront() const { return fIsFront; } + void GTab::OnDropMessage(BMessage* message) { @@ -283,6 +292,7 @@ IncreaseContrastBy(float& tint, const float& value, const int& brightness) } +// GTabCloseButton GTabCloseButton::GTabCloseButton(const char* label, TabsContainer* controller, const BHandler* handler): @@ -291,16 +301,17 @@ GTabCloseButton::GTabCloseButton(const char* label, fClicked(false), fHandler(handler) { - } -//FIX: we should better understand how to extend the default sizes. + +// TODO: we should better understand how to extend the default sizes. BSize GTabCloseButton::MinSize() { return GTab::MinSize(); } + BSize GTabCloseButton::MaxSize() { @@ -319,7 +330,6 @@ GTabCloseButton::DrawContents(BView* owner, BRect frame, GTab::DrawContents(owner, labelFrame, updateRect, isFront); frame.left = labelFrame.right; DrawCloseButton(owner, frame, updateRect, isFront); - return; } @@ -327,10 +337,11 @@ void GTabCloseButton::MouseDown(BPoint where) { BMessage* msg = Window()->CurrentMessage(); - if (!msg) + if (msg == nullptr) return; + const int32 buttons = msg->GetInt32("buttons", 0); - if(buttons & B_PRIMARY_MOUSE_BUTTON) { + if (buttons & B_PRIMARY_MOUSE_BUTTON) { BRect closeRect = RectCloseButton(); bool inside = closeRect.Contains(where); if (inside != fClicked) { @@ -342,6 +353,7 @@ GTabCloseButton::MouseDown(BPoint where) GTab::MouseDown(where); } + void GTabCloseButton::MouseUp(BPoint where) { @@ -358,7 +370,6 @@ GTabCloseButton::MouseUp(BPoint where) } - void GTabCloseButton::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) @@ -439,15 +450,16 @@ GTabCloseButton::DrawCloseButton(BView* owner, BRect buttonRect, const BRect& up owner->SetPenSize(1); } -/////////////////////////////////////////////////////////////////////////////// +// Filler Filler::Filler(TabsContainer* tabsContainer) - : BView("_filler_", B_WILL_DRAW), - GTabDropZone(tabsContainer) + : + BView("_filler_", B_WILL_DRAW), + GTabDropZone(tabsContainer) { - } + void Filler::Draw(BRect rect) { @@ -471,6 +483,7 @@ Filler::MessageReceived(BMessage* message) BView::MessageReceived(message); } + void Filler::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) { @@ -483,5 +496,3 @@ Filler::OnDropMessage(BMessage* message) { Container()->OnDropTab(nullptr, message); } - - diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 69b5d2f3..28067822 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -8,23 +8,22 @@ #include #include #include +#include #include #include -#include #include + #include #include -#include -#include "TabButtons.h" + #include "Draggable.h" +#include "TabButtons.h" #include "TabsContainer.h" -class GTab; -class GTabDropZone : Draggable -{ +class GTab; +class GTabDropZone : Draggable { public: - GTabDropZone(TabsContainer* container) : fTabsContainer(container) { } @@ -55,7 +54,7 @@ class GTabDropZone : Draggable virtual void OnDropMessage(BMessage* message) = 0; - TabsContainer* Container() { return fTabsContainer; } + TabsContainer* Container() { return fTabsContainer; } virtual void StopDragging(BView* view) { @@ -83,8 +82,8 @@ class GTab : public BView , public GTabDropZone { GTab(const char* label, TabsContainer* container); virtual ~GTab(); - virtual BSize MinSize() override; - virtual BSize MaxSize() override; + BSize MinSize() override; + BSize MaxSize() override; void Draw(BRect updateRect) override; @@ -94,12 +93,12 @@ class GTab : public BView , public GTabDropZone { virtual void DrawContents(BView* owner, BRect frame, const BRect& updateRect, bool isFront); - virtual void MouseDown(BPoint where) override; - virtual void MouseUp(BPoint where) override; - virtual void MouseMoved(BPoint where, uint32 transit, + void MouseDown(BPoint where) override; + void MouseUp(BPoint where) override; + void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override; - virtual void MessageReceived(BMessage* message) override; + void MessageReceived(BMessage* message) override; bool InitiateDrag(BPoint where) override; @@ -115,12 +114,12 @@ class GTab : public BView , public GTabDropZone { virtual void OnDropMessage(BMessage* message); protected: - BLayoutItem* fLayoutItem; bool fIsFront; BString fLabel; }; + class GTabCloseButton : public GTab { public: @@ -128,13 +127,13 @@ class GTabCloseButton : public GTab { TabsContainer* controller, const BHandler* handler); - virtual BSize MinSize() override; - virtual BSize MaxSize() override; - virtual void DrawContents(BView* owner, BRect frame, + BSize MinSize() override; + BSize MaxSize() override; + void DrawContents(BView* owner, BRect frame, const BRect& updateRect, bool isFront) override; - virtual void MouseDown(BPoint where) override; - virtual void MouseUp(BPoint where) override; - virtual void MouseMoved(BPoint where, uint32 transit, + void MouseDown(BPoint where) override; + void MouseUp(BPoint where) override; + void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override; private: void DrawCloseButton(BView* owner, BRect butFrame, const BRect& updateRect, @@ -150,6 +149,7 @@ class GTabCloseButton : public GTab { const BHandler* fHandler; }; + class Filler : public BView, public GTabDropZone { public: @@ -163,18 +163,13 @@ class Filler : public BView, public GTabDropZone void Draw(BRect rect) override; void MouseUp(BPoint where) override; - - - void MessageReceived(BMessage* message) override; - - void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage) override; - + const BMessage* dragMessage) override; + void MessageReceived(BMessage* message) override; + void OnDropMessage(BMessage* message) override; void OnDropObject(); - }; @@ -190,32 +185,31 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { { } - virtual void Draw(BRect updateRect) override + void Draw(BRect updateRect) override { GTabButton::Draw(updateRect); if (IsEnabled()) DropZoneDraw(this, Bounds()); } - virtual void MouseUp(BPoint where) override + void MouseUp(BPoint where) override { DropZoneMouseUp(this, where); GTabButton::MouseUp(where); } - virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override + void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override { if (DropZoneMouseMoved(this, where, transit, dragMessage) == false) GTabButton::MouseMoved(where, transit, dragMessage); } - - virtual void OnDropMessage(BMessage* message) override + void OnDropMessage(BMessage* message) override { return; } - virtual void MessageReceived(BMessage* message) override + void MessageReceived(BMessage* message) override { switch(message->what) { case kRunnerTick: @@ -227,15 +221,14 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { fRunner = nullptr; } } - break; + break; default: GTabButton::MessageReceived(message); - break; - - }; + break; + } } - virtual void StopDragging(BView* view) override + void StopDragging(BView* view) override { GTabDropZone::StopDragging(view); if (fRunner != nullptr) { @@ -244,7 +237,7 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { } } - virtual void StartDragging(BView* view) override + void StartDragging(BView* view) override { GTabDropZone::StartDragging(view); @@ -273,7 +266,7 @@ class GTabScrollLeftButton : public TabButtonDropZone { { } - virtual void DrawSymbol(BRect frame, const BRect& updateRect, + void DrawSymbol(BRect frame, const BRect& updateRect, const rgb_color& base) override { float tint = IsEnabled() ? B_DARKEN_4_TINT : B_DARKEN_1_TINT; @@ -299,4 +292,3 @@ class GTabScrollRightButton : public TabButtonDropZone { base, BControlLook::B_RIGHT_ARROW, 0, tint); } }; - From 65975b742bdbafc8a85ca052d55332b8e0894731 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sat, 11 Jan 2025 13:01:12 +0100 Subject: [PATCH 09/29] added missing override keyword --- src/helpers/gtab/GTab.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 28067822..0d3c28fd 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -111,7 +111,7 @@ class GTab : public BView , public GTabDropZone { BString Label() { return fLabel; }; void SetLabel(const char* label) { fLabel.SetTo(label); } - virtual void OnDropMessage(BMessage* message); + virtual void OnDropMessage(BMessage* message) override; protected: BLayoutItem* fLayoutItem; @@ -166,7 +166,7 @@ class Filler : public BView, public GTabDropZone void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override; void MessageReceived(BMessage* message) override; - + void OnDropMessage(BMessage* message) override; void OnDropObject(); From 2a7b690ff6f3639872bee00140c79d0ae6ab7ad1 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sat, 11 Jan 2025 13:21:52 +0100 Subject: [PATCH 10/29] minor cleanups --- src/ui/PanelTabManager.cpp | 7 ++++--- src/ui/PanelTabManager.h | 4 ---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index cd47e468..384cafde 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -13,11 +13,12 @@ class GTabID : public GTab { public: + GTabID(tab_id id, const char* label, TabsContainer* container): - GTab(label, container), fId(id) - { - } + GTab(label, container), fId(id){ } + tab_id GetID() { return fId; } + private: tab_id fId; }; diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h index b20ec2cf..a1ec765b 100644 --- a/src/ui/PanelTabManager.h +++ b/src/ui/PanelTabManager.h @@ -4,18 +4,14 @@ */ #pragma once - #include #include -#include #include -class GTabID; class BView; class PanelTabView; typedef uint32 tab_id; - typedef std::map TabViewList; From a92a52913cf677462f8dfb738f1054f6b4e78977 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sun, 12 Jan 2025 11:25:38 +0100 Subject: [PATCH 11/29] fixed clang error --- src/helpers/gtab/GTab.cpp | 2 +- src/helpers/gtab/TabsContainer.cpp | 2 +- src/helpers/gtab/TabsContainer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index 47322da4..12ec269f 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -174,7 +174,7 @@ GTab::MouseDown(BPoint where) const int32 buttons = msg->GetInt32("buttons", 0); if (Container()) - Container()->MouseDown(this, where, buttons); + Container()->MouseDownOnTab(this, where, buttons); if(buttons & B_PRIMARY_MOUSE_BUTTON) { DropZoneMouseDown(where); diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 9e731d4d..9372afee 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -178,7 +178,7 @@ TabsContainer::ShiftTabs(int32 delta) void -TabsContainer::MouseDown(GTab* tab, BPoint where, const int32 buttons) +TabsContainer::MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons) { if(buttons & B_PRIMARY_MOUSE_BUTTON) { SelectTab(tab); diff --git a/src/helpers/gtab/TabsContainer.h b/src/helpers/gtab/TabsContainer.h index ad58e3a9..ac6fd3b2 100644 --- a/src/helpers/gtab/TabsContainer.h +++ b/src/helpers/gtab/TabsContainer.h @@ -34,7 +34,7 @@ class TabsContainer : public BGroupView, public BInvoker { void ShiftTabs(int32 delta); // 0 to refresh the current state - void MouseDown(GTab* tab, BPoint where, const int32 buttons); + void MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons); void FrameResized(float w, float h) override; From f82dab9650bb6bdf4d887f5897914789418e2466 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Sun, 12 Jan 2025 11:54:37 +0100 Subject: [PATCH 12/29] minor refactor to cleanup the GTab class --- src/helpers/gtab/GTab.cpp | 19 ++++++++----------- src/helpers/gtab/GTab.h | 14 ++++++++------ src/helpers/gtab/GTabView.cpp | 6 +++--- src/helpers/gtab/TabsContainer.cpp | 8 +++----- src/helpers/gtab/TabsContainer.h | 2 -- src/ui/PanelTabManager.cpp | 24 ++++-------------------- 6 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/helpers/gtab/GTab.cpp b/src/helpers/gtab/GTab.cpp index 12ec269f..3ebb16ae 100644 --- a/src/helpers/gtab/GTab.cpp +++ b/src/helpers/gtab/GTab.cpp @@ -77,12 +77,11 @@ GTabDropZone::DropZoneMessageReceived(BMessage* message) // GTab -GTab::GTab(const char* label, TabsContainer* container) +GTab::GTab(const char* label) : BView("_tabView_", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), - GTabDropZone(container), fIsFront(false), - fLabel(label)/*, fTabDragging(false)*/ + fLabel(label) { } @@ -178,8 +177,6 @@ GTab::MouseDown(BPoint where) if(buttons & B_PRIMARY_MOUSE_BUTTON) { DropZoneMouseDown(where); - } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { - } } @@ -294,9 +291,8 @@ IncreaseContrastBy(float& tint, const float& value, const int& brightness) // GTabCloseButton GTabCloseButton::GTabCloseButton(const char* label, - TabsContainer* controller, const BHandler* handler): - GTab(label, controller), + GTab(label), fOverCloseRect(false), fClicked(false), fHandler(handler) @@ -349,6 +345,8 @@ GTabCloseButton::MouseDown(BPoint where) Invalidate(closeRect); return; } + } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { + CloseButtonClicked(); } GTab::MouseDown(where); } @@ -403,7 +401,7 @@ GTabCloseButton::RectCloseButton() void GTabCloseButton::CloseButtonClicked() { - BMessage msg(TabsContainer::kTVCloseTab); + BMessage msg(kTVCloseTab); msg.AddPointer("tab", this); BMessenger(fHandler).SendMessage(&msg); } @@ -453,10 +451,9 @@ GTabCloseButton::DrawCloseButton(BView* owner, BRect buttonRect, const BRect& up // Filler Filler::Filler(TabsContainer* tabsContainer) - : - BView("_filler_", B_WILL_DRAW), - GTabDropZone(tabsContainer) + : BView("_filler_", B_WILL_DRAW) { + SetContainer(tabsContainer); } diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 0d3c28fd..cbe065a5 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -24,7 +24,7 @@ class GTab; class GTabDropZone : Draggable { public: - GTabDropZone(TabsContainer* container) : fTabsContainer(container) + GTabDropZone() : fTabsContainer(nullptr) { } @@ -56,6 +56,8 @@ class GTabDropZone : Draggable { TabsContainer* Container() { return fTabsContainer; } + void SetContainer(TabsContainer* container) { fTabsContainer = container; } + virtual void StopDragging(BView* view) { if (fTabDragging) { @@ -79,7 +81,7 @@ class GTabDropZone : Draggable { class GTab : public BView , public GTabDropZone { public: - GTab(const char* label, TabsContainer* container); + GTab(const char* label); virtual ~GTab(); BSize MinSize() override; @@ -122,10 +124,9 @@ class GTab : public BView , public GTabDropZone { class GTabCloseButton : public GTab { public: + enum { kTVCloseTab = 'TVCt' }; - GTabCloseButton(const char* label, - TabsContainer* controller, - const BHandler* handler); + GTabCloseButton(const char* label, const BHandler* handler); BSize MinSize() override; BSize MaxSize() override; @@ -181,8 +182,9 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { public: TabButtonDropZone(BMessage* message, TabsContainer* container) - : GTabButton(" ", message), GTabDropZone(container), fRunner(nullptr) + : GTabButton(" ", message), fRunner(nullptr) { + SetContainer(container); } void Draw(BRect updateRect) override diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index e6accc50..e1e72525 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -137,7 +137,7 @@ GTabView::MessageReceived(BMessage* message) fCardView->CardLayout()->SetVisibleItem(index); } break; - case TabsContainer::kTVCloseTab: + case GTabCloseButton::kTVCloseTab: { if (fCloseButton == false) return; @@ -298,8 +298,8 @@ GTabView::SelectTab(GTab* tab) GTab* GTabView::CreateTabView(const char* label) { - return fCloseButton ? new GTabCloseButton(label, fTabsContainer, this) - : new GTab(label, fTabsContainer); + return fCloseButton ? new GTabCloseButton(label, this) + : new GTab(label); } GTab* diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 9372afee..0d6e7847 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -38,6 +38,8 @@ TabsContainer::AddTab(GTab* tab, int32 index) BLayoutItem* item = GroupLayout()->AddView(index, tab); tab->SetLayoutItem (item); + tab->SetContainer(this); + if (CountTabs() == 1) { SelectTab(tab); } @@ -183,11 +185,7 @@ TabsContainer::MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons) if(buttons & B_PRIMARY_MOUSE_BUTTON) { SelectTab(tab); } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { - if (Target()) { - BMessage msg(kTVCloseTab); - msg.AddPointer("tab", tab); - Invoke(&msg); - } + } } diff --git a/src/helpers/gtab/TabsContainer.h b/src/helpers/gtab/TabsContainer.h index ac6fd3b2..62a8bee3 100644 --- a/src/helpers/gtab/TabsContainer.h +++ b/src/helpers/gtab/TabsContainer.h @@ -16,8 +16,6 @@ class GTab; class TabsContainer : public BGroupView, public BInvoker { public: - enum { kTVCloseTab = 'TVCt' }; - TabsContainer(GTabView* tabView, tab_affinity affinity = 0, BMessage* message = nullptr); diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index 384cafde..00068fce 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -14,8 +14,8 @@ class GTabID : public GTab { public: - GTabID(tab_id id, const char* label, TabsContainer* container): - GTab(label, container), fId(id){ } + GTabID(tab_id id, const char* label): + GTab(label), fId(id){ } tab_id GetID() { return fId; } @@ -39,7 +39,7 @@ class PanelTabView : public GTabView { void AddTab(BView* panel, tab_id id) { - GTabID* tab = new GTabID(id, panel->Name(), Container()); + GTabID* tab = new GTabID(id, panel->Name()); GTabView::AddTab(tab, panel); } @@ -64,28 +64,12 @@ class PanelTabView : public GTabView { virtual void OnTabRemoved(GTab* _tab) override { GTabID* tab = dynamic_cast(_tab); -/* - if (fIdMap.contains(tab->GetID()) == false) - { - for(const auto& info:fIdMap) { - printf("R %s: %d [%s] (vs %d)\n", Name(), info.first, info.second.view->Name(), tab->GetID()); - } - } -*/ assert(tab != nullptr && fIdMap.contains(tab->GetID()) == true); fIdMap.erase(tab->GetID()); } virtual void OnTabAdded(GTab* _tab, BView* panel) override { GTabID* tab = dynamic_cast(_tab); -/* - if (fIdMap.contains(tab->GetID()) == true) - { - for(const auto& info:fIdMap) { - printf("A %s: %d [%s] (vs %d)\n", Name(), info.first, info.second.view->Name(), tab->GetID()); - } - } -*/ assert(tab != nullptr && fIdMap.contains(tab->GetID()) == false); fIdMap[tab->GetID()] = { tab, panel }; } @@ -93,7 +77,7 @@ class PanelTabView : public GTabView { GTab* CreateTabView(GTab* clone) override { GTabID* tab = dynamic_cast(clone); - return new GTabID(tab->GetID(), tab->Label().String(), Container());; + return new GTabID(tab->GetID(), tab->Label().String());; } private: From 0913823cf33a01f0b667490a3b55e6a62e640268 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 11:19:11 +0100 Subject: [PATCH 13/29] Removed reduntant "virtual". Fixes codefactor warnings --- src/helpers/gtab/GTab.h | 7 +++---- src/ui/PanelTabManager.cpp | 29 ++++++++++++++++++----------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index cbe065a5..4b193a12 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -111,9 +111,9 @@ class GTab : public BView , public GTabDropZone { void SetLayoutItem(BLayoutItem* layItem) { fLayoutItem = layItem; } BString Label() { return fLabel; }; - void SetLabel(const char* label) { fLabel.SetTo(label); } + void SetLabel(const char* label) { fLabel.SetTo(label); } - virtual void OnDropMessage(BMessage* message) override; + void OnDropMessage(BMessage* message) override; protected: BLayoutItem* fLayoutItem; @@ -151,8 +151,7 @@ class GTabCloseButton : public GTab { }; -class Filler : public BView, public GTabDropZone -{ +class Filler : public BView, public GTabDropZone { public: Filler(TabsContainer* tabsContainer); diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index 00068fce..81e12f7e 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -5,10 +5,11 @@ #include "PanelTabManager.h" -#include "GTabView.h" -#include "GTab.h" + #include +#include "GTab.h" +#include "GTabView.h" class GTabID : public GTab { @@ -27,12 +28,14 @@ struct tab_info { GTabID* tab; BView* view; }; + typedef std::map TabIdMap; class PanelTabView : public GTabView { public: - PanelTabView(PanelTabManager* manager, const char* name, tab_affinity affinity, orientation orientation): + PanelTabView(PanelTabManager* manager, const char* name, tab_affinity affinity, orientation orientation) + : GTabView(name, affinity, orientation) { } @@ -43,38 +46,39 @@ class PanelTabView : public GTabView { GTabView::AddTab(tab, panel); } - bool HasTab(tab_id id) { + bool HasTab(tab_id id) + { return fIdMap.contains(id); } - void SelectTab(tab_id id) { + void SelectTab(tab_id id) + { assert(fIdMap.contains(id) == true); GTabView::SelectTab(fIdMap[id].tab); } - void SetLabelForTab(tab_id id, const char* label) { + void SetLabelForTab(tab_id id, const char* label) + { assert(fIdMap.contains(id) == true); fIdMap[id].tab->SetLabel(label); fIdMap[id].tab->Invalidate(); } - - protected: - virtual void OnTabRemoved(GTab* _tab) override + void OnTabRemoved(GTab* _tab) override { GTabID* tab = dynamic_cast(_tab); assert(tab != nullptr && fIdMap.contains(tab->GetID()) == true); fIdMap.erase(tab->GetID()); } - virtual void OnTabAdded(GTab* _tab, BView* panel) override + void OnTabAdded(GTab* _tab, BView* panel) override { GTabID* tab = dynamic_cast(_tab); assert(tab != nullptr && fIdMap.contains(tab->GetID()) == false); fIdMap[tab->GetID()] = { tab, panel }; } - GTab* CreateTabView(GTab* clone) override + GTab* CreateTabView(GTab* clone) override { GTabID* tab = dynamic_cast(clone); return new GTabID(tab->GetID(), tab->Label().String());; @@ -84,10 +88,13 @@ class PanelTabView : public GTabView { TabIdMap fIdMap; }; + +// PanelTabManager PanelTabManager::PanelTabManager() { } + BView* PanelTabManager::CreatePanelTabView(const char* tabview_name, orientation orientation) { From 8f08afda3991e2017c8362e1ce7e7c169f8525a2 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 10:44:02 +0100 Subject: [PATCH 14/29] removed used variable --- src/helpers/gtab/GTabView.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index e1e72525..cb2db260 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -275,7 +275,6 @@ GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) fromLayout->RemoveSelf(); - BString label = fromTab->Label(); //TODO copy all the props GTab* removedTab = fromContainer->RemoveTab(fromTab); fromContainer->GetGTabView()->OnTabRemoved(fromTab); From 33577215fb73ae455d4e4b5a9eb3de2e5b9ffe9c Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 11:26:44 +0100 Subject: [PATCH 15/29] improvements in the avoid distruptive tab moves --- src/helpers/gtab/GTabView.cpp | 10 +++++++++- src/helpers/gtab/GTabView.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index cb2db260..e976cc2a 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -50,7 +50,7 @@ void GTabView::AddTab(GTab* tab, BView* view, int32 index) { fTabsContainer->AddTab(tab, index); - fCardView->CardLayout()->AddView(index, view); + _AddViewToCard(view, index); _FixContentOrientation(view); OnTabAdded(tab, view); #if 0 @@ -251,6 +251,14 @@ GTabView::_FixContentOrientation(BView* view) } +void +GTabView::_AddViewToCard(BView* view, int32 index) +{ + view->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + fCardView->CardLayout()->AddView(index, view); +} + + void GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) { diff --git a/src/helpers/gtab/GTabView.h b/src/helpers/gtab/GTabView.h index baafbd89..0c8398d2 100644 --- a/src/helpers/gtab/GTabView.h +++ b/src/helpers/gtab/GTabView.h @@ -68,6 +68,7 @@ class GTabView : public BGroupView void _Init(tab_affinity affinity); void _FixContentOrientation(BView* view); + void _AddViewToCard(BView* view, int32 index); GTabScrollLeftButton* fScrollLeftTabButton; From ccfcd276d5509cabde39fea786ba5a7d554276aa Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 11:54:14 +0100 Subject: [PATCH 16/29] Outline view and ConsoleIO view more friendly with tab movements --- src/helpers/mterm/KeyTextViewScintilla.cpp | 7 +++++++ src/helpers/mterm/KeyTextViewScintilla.h | 2 ++ src/ui/FunctionsOutlineView.cpp | 8 +++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/helpers/mterm/KeyTextViewScintilla.cpp b/src/helpers/mterm/KeyTextViewScintilla.cpp index 43a0938c..bab38d8e 100755 --- a/src/helpers/mterm/KeyTextViewScintilla.cpp +++ b/src/helpers/mterm/KeyTextViewScintilla.cpp @@ -42,12 +42,15 @@ KeyTextViewScintilla::KeyTextViewScintilla(const char *name, const BMessenger &m EnableInput(false); } + void KeyTextViewScintilla::AttachedToWindow() { if (FindView("ScintillaHaikuView")) FindView("ScintillaHaikuView")->AddFilter(new ScintillaHaikuAllMessageFilter()); } + + void KeyTextViewScintilla::ClearAll() { @@ -57,6 +60,7 @@ KeyTextViewScintilla::ClearAll() if (isRO) SendMessage(SCI_SETREADONLY, true); } + void KeyTextViewScintilla::EnableInput(bool enable) { @@ -67,6 +71,7 @@ KeyTextViewScintilla::EnableInput(bool enable) SendMessage(SCI_GRABFOCUS); } + void KeyTextViewScintilla::Append(const BString& text) { @@ -78,6 +83,7 @@ KeyTextViewScintilla::Append(const BString& text) if (isRO) SendMessage(SCI_SETREADONLY, true); } + filter_result KeyTextViewScintilla::BeforeMessageReceived(BMessage* msg, BView* scintillaView) { @@ -94,6 +100,7 @@ KeyTextViewScintilla::BeforeMessageReceived(BMessage* msg, BView* scintillaView) }; } + filter_result KeyTextViewScintilla::BeforeKeyDown(BMessage* msg, BView* scintillaView) { diff --git a/src/helpers/mterm/KeyTextViewScintilla.h b/src/helpers/mterm/KeyTextViewScintilla.h index 51df5c0e..39f8aced 100755 --- a/src/helpers/mterm/KeyTextViewScintilla.h +++ b/src/helpers/mterm/KeyTextViewScintilla.h @@ -27,6 +27,8 @@ class KeyTextViewScintilla : public BScintillaView { void ClearAll(); void Append(const BString& text); + BSize MinSize() { return BSize(0, 0); } + filter_result BeforeMessageReceived(BMessage* msg, BView* scintillaView); private: diff --git a/src/ui/FunctionsOutlineView.cpp b/src/ui/FunctionsOutlineView.cpp index 82ca3720..1c4a0f17 100755 --- a/src/ui/FunctionsOutlineView.cpp +++ b/src/ui/FunctionsOutlineView.cpp @@ -343,10 +343,12 @@ FunctionsOutlineView::FunctionsOutlineView() fToolBar->SetExplicitMinSize(BSize(250, B_SIZE_UNSET)); fToolBar->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .Add(fToolBar) .AddGroup(B_VERTICAL, 0) - .SetInsets(-2, -2, -2, -2) - .Add(fScrollView) + .Add(fToolBar) + .AddGroup(B_VERTICAL, 0) + .SetInsets(-2, -2, -2, -2) + .Add(fScrollView) + .End() .End(); } From f95a162cb14110eb154d3fee97557ac2b8d65f6e Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 16:07:30 +0100 Subject: [PATCH 17/29] Storing and Loading the tabs location. Still missing the right order. --- src/GenioApp.cpp | 33 +++++++++++++ src/helpers/gtab/GTabView.cpp | 8 ---- src/helpers/gtab/GTabView.h | 29 +++++------- src/ui/GenioWindow.cpp | 83 +++++++++++--------------------- src/ui/GenioWindow.h | 4 +- src/ui/PanelTabManager.cpp | 89 ++++++++++++++++++++++++++++++----- src/ui/PanelTabManager.h | 30 +++++++++++- 7 files changed, 178 insertions(+), 98 deletions(-) diff --git a/src/GenioApp.cpp b/src/GenioApp.cpp index bed50843..90030740 100644 --- a/src/GenioApp.cpp +++ b/src/GenioApp.cpp @@ -503,6 +503,39 @@ GenioApp::_PrepareConfig(ConfigManager& cfg) cfg.AddConfig("Hidden", "run_without_buffering", "run_without_buffering", true); GMessage log_limits = { {"min", 1024}, {"max", 4096} }; cfg.AddConfig("Hidden", "log_size", B_TRANSLATE("Log size:"), 1024, &log_limits); + + + BMessage tabConfig; + GMessage tab('TAB '); + tab.AddInt32("id", kTabProblems); + tab.AddString("panel_group", "bottom_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabBuildLog); + tab.ReplaceString("panel_group", "bottom_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabOutputLog); + tab.ReplaceString("panel_group", "bottom_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabSearchResult); + tab.ReplaceString("panel_group", "bottom_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabProjectBrowser); + tab.ReplaceString("panel_group", "left_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabSourceControl); + tab.ReplaceString("panel_group", "left_panels"); + tabConfig.AddMessage("tab", &tab); + + tab.ReplaceInt32("id", kTabOutlineView); + tab.ReplaceString("panel_group", "right_panels"); + tabConfig.AddMessage("tab", &tab); + + cfg.AddConfig("Hidden", "tabviews", "tabviews", tabConfig); } diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index e976cc2a..42e875cc 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -68,14 +68,6 @@ GTabView::AddTab(GTab* tab, BView* view, int32 index) } - -int32 -GTabView::CountTabs() -{ - return fTabsContainer->CountTabs(); -} - - void GTabView::DestroyTabAndView(GTab* tab) { diff --git a/src/helpers/gtab/GTabView.h b/src/helpers/gtab/GTabView.h index 0c8398d2..75d8c7d4 100644 --- a/src/helpers/gtab/GTabView.h +++ b/src/helpers/gtab/GTabView.h @@ -23,37 +23,34 @@ typedef uint32 tab_affinity; class GTabView : public BGroupView { public: - GTabView(const char* name, - tab_affinity affinity, - orientation orientation = B_HORIZONTAL, - bool closeButton = false, - bool menuButton = false); + GTabView(const char* name, + tab_affinity affinity, + orientation orientation = B_HORIZONTAL, + bool closeButton = false, + bool menuButton = false); - GTab* AddTab(const char* label, BView* view, int32 index = -1); + GTab* AddTab(const char* label, BView* view, int32 index = -1); - int32 CountTabs(); + void UpdateScrollButtons(bool left, bool right); - void UpdateScrollButtons(bool left, bool right); + void AttachedToWindow(); - void AttachedToWindow(); + void MessageReceived(BMessage* message); - void MessageReceived(BMessage* message); + void MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer); - void MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer); + void SelectTab(GTab* tab); - void SelectTab(GTab* tab); + virtual void OnMenuTabButton(); - virtual void OnMenuTabButton(); + protected: -protected: void AddTab(GTab* tab, BView* view, int32 index = -1); virtual void OnTabRemoved(GTab* tab) {}; virtual void OnTabAdded(GTab* tab, BView* view) {}; TabsContainer* Container() { return fTabsContainer; } - - private: virtual GTab* CreateTabView(const char* label); diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index e8c7292a..cdcac2cf 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -100,22 +100,6 @@ static float kDefaultIconSize = 32.0; using Genio::Task::Task; -enum { - kTabProblems = 'Tprb', - kTabBuildLog = 'Tbld', - kTabOutputLog = 'Tter', - kTabSearchResult = 'Tsea', - - kTabProjectBrowser = 'Tprj', - kTabSourceControl = 'Tsrc', - - kTabOutlineView = 'Touv' - -}; - -static constexpr const char* kTabViewLeft = "left_panels"; -static constexpr const char* kTabViewRight = "right_panels"; -static constexpr const char* kTabViewBottom = "bottom_panels"; static bool AcceptsCopyPaste(BView* view) @@ -1520,6 +1504,10 @@ GenioWindow::QuitRequested() gCFG["show_output"] = fPanelTabManager->IsPanelTabViewVisible(kTabViewBottom); gCFG["show_toolbar"] = !fToolBar->IsHidden(); + BMessage tabview_config; + fPanelTabManager->SaveConfiguration(tabview_config); + gCFG["tabviews"] = tabview_config; + // Files to reopen if (gCFG["reopen_files"]) { GSettings files(GenioNames::kSettingsFilesToReopen, 'FIRE'); @@ -3426,65 +3414,48 @@ GenioWindow::_InitToolbar() } -BView* -GenioWindow::_InitOutputSplit() +void +GenioWindow::_InitTabViews() { - // Output - BView* out = fPanelTabManager->CreatePanelTabView(kTabViewBottom, B_HORIZONTAL); + BMessage cfg = gCFG["tabviews"]; + fPanelTabManager->LoadConfiguration(cfg); + fPanelTabManager->CreatePanelTabView(kTabViewBottom, B_HORIZONTAL); + fPanelTabManager->CreatePanelTabView(kTabViewLeft, B_VERTICAL); + fPanelTabManager->CreatePanelTabView(kTabViewRight, B_VERTICAL); + //Bottom fProblemsPanel = new ProblemsPanel(fPanelTabManager, kTabProblems); - fBuildLogView = new ConsoleIOView(B_TRANSLATE("Build log"), BMessenger(this)); - fMTermView = new MTermView(B_TRANSLATE("Console I/O"), BMessenger(this)); - fSearchResultTab = new SearchResultTab(fPanelTabManager, kTabSearchResult); - fPanelTabManager->AddPanel(kTabViewBottom, fProblemsPanel, kTabProblems); - fPanelTabManager->AddPanel(kTabViewBottom, fBuildLogView, kTabBuildLog); - fPanelTabManager->AddPanel(kTabViewBottom, fMTermView, kTabOutputLog); - fPanelTabManager->AddPanel(kTabViewBottom, fSearchResultTab, kTabSearchResult); - - return out; -} - + fPanelTabManager->AddPanelByConfig(fProblemsPanel, kTabProblems); + fPanelTabManager->AddPanelByConfig(fBuildLogView, kTabBuildLog); + fPanelTabManager->AddPanelByConfig(fMTermView, kTabOutputLog); + fPanelTabManager->AddPanelByConfig(fSearchResultTab, kTabSearchResult); -BView* -GenioWindow::_InitLeftSplit() -{ - // Projects View - BView* out = fPanelTabManager->CreatePanelTabView(kTabViewLeft, B_VERTICAL); + //LEFT fProjectsFolderBrowser = new ProjectBrowser(); fSourceControlPanel = new SourceControlPanel(); - fPanelTabManager->AddPanel(kTabViewLeft, fProjectsFolderBrowser, kTabProjectBrowser); - fPanelTabManager->AddPanel(kTabViewLeft, fSourceControlPanel, kTabSourceControl); - - return out; -} + fPanelTabManager->AddPanelByConfig(fProjectsFolderBrowser, kTabProjectBrowser); + fPanelTabManager->AddPanelByConfig(fSourceControlPanel, kTabSourceControl); -BView* -GenioWindow::_InitRightSplit() -{ - // Outline view - BView* out = fPanelTabManager->CreatePanelTabView(kTabViewRight, B_VERTICAL); - + //RIGHT fFunctionsOutlineView = new FunctionsOutlineView(); - fPanelTabManager->AddPanel(kTabViewRight, fFunctionsOutlineView, kTabOutlineView); - - return out; + fPanelTabManager->AddPanelByConfig(fFunctionsOutlineView, kTabOutlineView); } + + void GenioWindow::_InitWindow() { _InitToolbar(); - BView* projectsTabView = _InitLeftSplit(); + _InitTabViews(); _InitCentralSplit(); - BView* rightTabView = _InitRightSplit(); - BView* outputTabView = _InitOutputSplit(); // Layout fRootLayout = BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) @@ -3494,11 +3465,11 @@ GenioWindow::_InitWindow() .AddSplit(B_VERTICAL, 0.0f) // output split .SetInsets(-2.0f, 0.0f, -2.0f, -2.0f) .AddSplit(B_HORIZONTAL, 0.0f) // sidebar split - .Add(projectsTabView, kProjectsWeight) + .Add(fPanelTabManager->GetPanelTabView(kTabViewLeft), kProjectsWeight) .Add(fEditorTabsGroup, kEditorWeight) // Editor - .Add(rightTabView, 1) + .Add(fPanelTabManager->GetPanelTabView(kTabViewRight), 1) .End() // sidebar split - .Add(outputTabView, kOutputWeight) + .Add(fPanelTabManager->GetPanelTabView(kTabViewBottom), kOutputWeight) .End() // output split .Add(fStatusView = new GlobalStatusView()) ; diff --git a/src/ui/GenioWindow.h b/src/ui/GenioWindow.h index e6831b20..76da4fe0 100644 --- a/src/ui/GenioWindow.h +++ b/src/ui/GenioWindow.h @@ -110,9 +110,7 @@ class GenioWindow : public BWindow { void _InitCentralSplit(); void _InitCommandRunToolbar(); void _InitMenu(); - BView* _InitOutputSplit(); - BView* _InitLeftSplit(); - BView* _InitRightSplit(); + void _InitTabViews(); void _InitToolbar(); void _InitWindow(); diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index 81e12f7e..20d7d792 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -64,6 +64,23 @@ class PanelTabView : public GTabView { fIdMap[id].tab->Invalidate(); } + void SaveTabsConfiguration(BMessage& config) + { + //To maintain the right order, let's use + // the index interface (usually discouraged) + for (int32 i=0;iCountTabs();i++) { + GTabID* tabid = dynamic_cast(Container()->TabAt(i)); + if (tabid) { + BMessage tab('TAB '); + tab.AddInt32("id", tabid->GetID()); + tab.AddString("panel_group", Name()); + config.AddMessage("tab", &tab); + //tab_id id = tabid->GetID(); + //printf("%s -> %d ('%.4s')\n", Name(), id, ((char*)&id)); + } + } + } + protected: void OnTabRemoved(GTab* _tab) override { @@ -95,24 +112,70 @@ PanelTabManager::PanelTabManager() } +void +PanelTabManager::LoadConfiguration(const BMessage& config) +{ + fConfig = config; +} + + +void +PanelTabManager::SaveConfiguration(BMessage& config) +{ + for (const auto& info:fTVList) { + PanelTabView* tabview = info.second; + tabview->SaveTabsConfiguration(config); + } +} + + BView* PanelTabManager::CreatePanelTabView(const char* tabview_name, orientation orientation) { + assert(fTVList.contains(tabview_name) == false); + PanelTabView* tabView = new PanelTabView(this, tabview_name, 'GPAF', orientation); - fTVList[tabview_name] = { tabView }; -/* - for (const auto& info:fTVList) { - printf("CreatePanel %s %p\n", info.second->Name(), tabView ); - } -*/ + fTVList[tabview_name] = tabView; + + //for (const auto& info:fTVList) { + //printf("CreatePanel %s %p\n", tabview_name, tabView ); + //} + return tabView; } +BView* +PanelTabManager::GetPanelTabView(const char* name) +{ + return _GetPanelTabView(name); +} + + + +void +PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) +{ + BMessage tab; + int i = 0; + while(fConfig.FindMessage("tab", i++, &tab) == B_OK) + { + tab_id tabid = tab.GetInt32("id", 0); + if (tabid == id) { + const char* panelName = tab.GetString("panel_group", ""); + AddPanel(panelName, panel, id); + return; + } + } + + debugger("Cant! add a panel tab!"); +} + + void PanelTabManager::AddPanel(const char* tabview_name, BView* panel, tab_id id) { - PanelTabView* tabview = GetPanelTabView(tabview_name); + PanelTabView* tabview = _GetPanelTabView(tabview_name); assert (tabview != nullptr); tabview->AddTab(panel, id); @@ -123,7 +186,7 @@ PanelTabManager::AddPanel(const char* tabview_name, BView* panel, tab_id id) void PanelTabManager::SelectTab(tab_id id) { - for (const auto panel:fTVList) { + for (const auto& panel:fTVList) { if (panel.second->HasTab(id)) { panel.second->SelectTab(id); return; @@ -135,7 +198,7 @@ PanelTabManager::SelectTab(tab_id id) void PanelTabManager::ShowTab(tab_id id) { - for (const auto panel:fTVList) { + for (const auto& panel:fTVList) { if (panel.second->HasTab(id)) { if (panel.second->IsHidden()) panel.second->Show(); @@ -149,7 +212,7 @@ PanelTabManager::ShowTab(tab_id id) void PanelTabManager::SetLabelForTab(tab_id id, const char* label) { - for (const auto panel:fTVList) { + for (const auto& panel:fTVList) { if (panel.second->HasTab(id)) { panel.second->SetLabelForTab(id, label); return; @@ -161,7 +224,7 @@ PanelTabManager::SetLabelForTab(tab_id id, const char* label) void PanelTabManager::ShowPanelTabView(const char* tabview_name, bool show) { - PanelTabView* tabview = GetPanelTabView(tabview_name); + PanelTabView* tabview = _GetPanelTabView(tabview_name); if (show == true && tabview->IsHidden()) tabview->Show(); @@ -174,13 +237,13 @@ PanelTabManager::ShowPanelTabView(const char* tabview_name, bool show) bool PanelTabManager::IsPanelTabViewVisible(const char* tabview_name) { - return !GetPanelTabView(tabview_name)->IsHidden(); + return !_GetPanelTabView(tabview_name)->IsHidden(); } PanelTabView* -PanelTabManager::GetPanelTabView(const char* sname) +PanelTabManager::_GetPanelTabView(const char* sname) { assert(fTVList.contains(sname) == true); return fTVList[sname]; diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h index a1ec765b..7300bac4 100644 --- a/src/ui/PanelTabManager.h +++ b/src/ui/PanelTabManager.h @@ -7,20 +7,45 @@ #include #include #include +#include +#include class BView; class PanelTabView; + +#define kTabViewLeft "left_panels" +#define kTabViewRight "right_panels" +#define kTabViewBottom "bottom_panels" + +enum { + kTabProblems = 'Tprb', + kTabBuildLog = 'Tbld', + kTabOutputLog = 'Tter', + kTabSearchResult = 'Tsea', + + kTabProjectBrowser = 'Tprj', + kTabSourceControl = 'Tsrc', + + kTabOutlineView = 'Touv' + +}; + typedef uint32 tab_id; -typedef std::map TabViewList; +typedef std::map TabViewList; class PanelTabManager { public: PanelTabManager(); + void LoadConfiguration(const BMessage& config); + void SaveConfiguration(BMessage& config); + BView* CreatePanelTabView(const char* tabview_name, orientation orientation); + BView* GetPanelTabView(const char* name); + void AddPanelByConfig(BView* panel, tab_id id); void AddPanel(const char* tabview_name, BView* panel, tab_id id); void SelectTab(tab_id id); @@ -33,8 +58,9 @@ class PanelTabManager { private: - PanelTabView* GetPanelTabView(const char* name); + PanelTabView* _GetPanelTabView(const char* name); TabViewList fTVList; + BMessage fConfig; }; From 02d22de1598127d3d37826f48b2d7c3888cb5561 Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 16:39:14 +0100 Subject: [PATCH 18/29] store order of tabs --- src/helpers/gtab/GTabView.cpp | 3 +++ src/helpers/gtab/TabsContainer.cpp | 2 +- src/ui/PanelTabManager.cpp | 11 ++++++----- src/ui/PanelTabManager.h | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index 42e875cc..a93003a8 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -49,6 +49,9 @@ GTabView::AddTab(const char* label, BView* view, int32 index) void GTabView::AddTab(GTab* tab, BView* view, int32 index) { + if (index > Container()->CountTabs()) + index = Container()->CountTabs(); + fTabsContainer->AddTab(tab, index); _AddViewToCard(view, index); _FixContentOrientation(view); diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 0d6e7847..33ef809e 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -32,7 +32,7 @@ TabsContainer::TabsContainer(GTabView* tabView, void TabsContainer::AddTab(GTab* tab, int32 index) { - if (index == -1) + if (index == -1 && index > CountTabs()) index = CountTabs(); BLayoutItem* item = GroupLayout()->AddView(index, tab); diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index 20d7d792..f10f3e93 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -40,10 +40,10 @@ class PanelTabView : public GTabView { { } - void AddTab(BView* panel, tab_id id) + void AddTab(BView* panel, tab_id id, int32 index=-1) { GTabID* tab = new GTabID(id, panel->Name()); - GTabView::AddTab(tab, panel); + GTabView::AddTab(tab, panel, index); } bool HasTab(tab_id id) @@ -74,6 +74,7 @@ class PanelTabView : public GTabView { BMessage tab('TAB '); tab.AddInt32("id", tabid->GetID()); tab.AddString("panel_group", Name()); + tab.AddInt32("index", i); config.AddMessage("tab", &tab); //tab_id id = tabid->GetID(); //printf("%s -> %d ('%.4s')\n", Name(), id, ((char*)&id)); @@ -163,7 +164,7 @@ PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) tab_id tabid = tab.GetInt32("id", 0); if (tabid == id) { const char* panelName = tab.GetString("panel_group", ""); - AddPanel(panelName, panel, id); + _AddPanel(panelName, panel, id, tab.GetInt32("index", -1)); return; } } @@ -173,12 +174,12 @@ PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) void -PanelTabManager::AddPanel(const char* tabview_name, BView* panel, tab_id id) +PanelTabManager::_AddPanel(const char* tabview_name, BView* panel, tab_id id, int32 index) { PanelTabView* tabview = _GetPanelTabView(tabview_name); assert (tabview != nullptr); - tabview->AddTab(panel, id); + tabview->AddTab(panel, id, index); } diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h index 7300bac4..be4403a1 100644 --- a/src/ui/PanelTabManager.h +++ b/src/ui/PanelTabManager.h @@ -46,7 +46,6 @@ class PanelTabManager { BView* GetPanelTabView(const char* name); void AddPanelByConfig(BView* panel, tab_id id); - void AddPanel(const char* tabview_name, BView* panel, tab_id id); void SelectTab(tab_id id); void ShowTab(tab_id id); @@ -58,6 +57,7 @@ class PanelTabManager { private: + void _AddPanel(const char* tabview_name, BView* panel, tab_id id, int32 index=-1); PanelTabView* _GetPanelTabView(const char* name); TabViewList fTVList; BMessage fConfig; From dd0dd06597f6138ce4e1443b75b9618ca72c67ca Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 17:49:37 +0100 Subject: [PATCH 19/29] Removed debug code --- src/helpers/gtab/GTabView.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index a93003a8..bb051231 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -56,18 +56,6 @@ GTabView::AddTab(GTab* tab, BView* view, int32 index) _AddViewToCard(view, index); _FixContentOrientation(view); OnTabAdded(tab, view); -#if 0 - //debug code: - printf("-------- debug size for %s \n", Name()); - BSize containerSize = fTabsContainer->Bounds().Size(); - printf(" containerSize %f,%f\n", containerSize.Width(), containerSize.Height()); - float accu = 0.0f; - for(int32 i=0;iCountTabs();i++){ - GTab* tab = fTabsContainer->TabAt(i); - accu += tab->Bounds().Width(); - printf("%s w %f accu %f left %f\n", tab->Label().String(), tab->Bounds().Width(), accu, containerSize.Width() - accu); - } -#endif } From 08dae68aa7c53a98124235f56733e3b67db2718d Mon Sep 17 00:00:00 2001 From: Freaxed Date: Mon, 13 Jan 2025 17:52:49 +0100 Subject: [PATCH 20/29] fixed bug in tab index --- src/helpers/gtab/GTabView.cpp | 2 +- src/helpers/gtab/TabsContainer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index bb051231..c171ca76 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -49,7 +49,7 @@ GTabView::AddTab(const char* label, BView* view, int32 index) void GTabView::AddTab(GTab* tab, BView* view, int32 index) { - if (index > Container()->CountTabs()) + if (index == -1 || index > Container()->CountTabs()) index = Container()->CountTabs(); fTabsContainer->AddTab(tab, index); diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 33ef809e..4fa55959 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -32,7 +32,7 @@ TabsContainer::TabsContainer(GTabView* tabView, void TabsContainer::AddTab(GTab* tab, int32 index) { - if (index == -1 && index > CountTabs()) + if (index == -1 || index > CountTabs()) index = CountTabs(); BLayoutItem* item = GroupLayout()->AddView(index, tab); From 899d86a9beaede2922c175325a31969a21cd2080 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 20:12:34 +0100 Subject: [PATCH 21/29] Style. Made some method const. --- src/helpers/gtab/TabsContainer.cpp | 32 ++++++++++++++++-------------- src/helpers/gtab/TabsContainer.h | 21 ++++++++++---------- src/ui/PanelTabManager.cpp | 22 +++++++++++--------- src/ui/PanelTabManager.h | 4 ++-- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 4fa55959..69bc1138 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -5,15 +5,18 @@ #include "TabsContainer.h" + +#include + #include "GTab.h" #include "GTabView.h" -#include #define FILLER_WEIGHT 0.2 TabsContainer::TabsContainer(GTabView* tabView, tab_affinity affinity, - BMessage* message): + BMessage* message) + : BGroupView(B_HORIZONTAL, 0.0f), BInvoker(message, nullptr, nullptr), fSelectedTab(nullptr), @@ -47,12 +50,14 @@ TabsContainer::AddTab(GTab* tab, int32 index) ShiftTabs(0); } + int32 -TabsContainer::CountTabs() +TabsContainer::CountTabs() const { return GroupLayout()->CountItems() - 1; //exclude the Filler. } + GTab* TabsContainer::TabAt(int32 index) { @@ -68,6 +73,7 @@ TabsContainer::IndexOfTab(GTab* tab) { if (fSelectedTab == nullptr) return -1; + return GroupLayout()->IndexOfItem(tab->LayoutItem()); } @@ -93,7 +99,7 @@ TabsContainer::RemoveTab(GTab* tab) //fix tab visibility // TODO: this could be further improved by shifting according to the free // available space. - int shift = 0; + int32 shift = 0; if (fTabShift > 0 && fTabShift >= CountTabs()) { shift -= 1; } @@ -104,7 +110,7 @@ TabsContainer::RemoveTab(GTab* tab) GTab* -TabsContainer::SelectedTab() +TabsContainer::SelectedTab() const { return fSelectedTab; } @@ -138,7 +144,7 @@ TabsContainer::SelectTab(GTab* tab, bool invoke) float middle = fSelectedTab->Frame().right - (fSelectedTab->Frame().Width()/2.0f); if (middle > Bounds().right) { int32 shift = 0; - for (int32 i = fTabShift; i< CountTabs();i++) { + for (int32 i = fTabShift; i < CountTabs();i++) { GTab* nextTab = TabAt(i); middle -= nextTab->Bounds().Width(); shift++; @@ -162,8 +168,7 @@ TabsContainer::ShiftTabs(int32 delta) newShift = 0; int32 max = std::max(newShift, fTabShift); - - for (int32 i=0;iIsHidden() == false) @@ -178,7 +183,6 @@ TabsContainer::ShiftTabs(int32 delta) } - void TabsContainer::MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons) { @@ -199,7 +203,7 @@ TabsContainer::FrameResized(float w, float h) int32 tox = 0; GTab* last = TabAt(CountTabs()-1); float right = last->Frame().right; - for (int32 i=fTabShift - 1;i>=0;i--){ + for (int32 i = fTabShift - 1; i >= 0; i--){ GTab* tab = TabAt(i); right = right + tab->Frame().Width(); if (right < w) @@ -215,12 +219,12 @@ TabsContainer::FrameResized(float w, float h) BGroupView::FrameResized(w,h); } + void TabsContainer::OnDropTab(GTab* toTab, BMessage* message) { - GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); + GTab* fromTab = (GTab*)message->GetPointer("tab", nullptr); TabsContainer* fromContainer = fromTab->Container(); - if (fromTab == nullptr || fromContainer == nullptr || toTab == fromTab) return; @@ -237,17 +241,15 @@ TabsContainer::_PrintToStream() } - void TabsContainer::_UpdateScrolls() { if (CountTabs() > 0) { GroupLayout()->Relayout(true); GTab* last = TabAt(CountTabs() - 1); - if(fGTabView != nullptr && last != nullptr) + if (fGTabView != nullptr && last != nullptr) fGTabView->UpdateScrollButtons(fTabShift != 0, last->Frame().right > Bounds().right); } else { fGTabView->UpdateScrollButtons(false, false); } } - diff --git a/src/helpers/gtab/TabsContainer.h b/src/helpers/gtab/TabsContainer.h index 62a8bee3..bf0512ef 100644 --- a/src/helpers/gtab/TabsContainer.h +++ b/src/helpers/gtab/TabsContainer.h @@ -7,12 +7,11 @@ #include #include -#include + #include "Draggable.h" #include "GTabView.h" class GTab; - class TabsContainer : public BGroupView, public BInvoker { public: @@ -22,29 +21,29 @@ class TabsContainer : public BGroupView, public BInvoker { void AddTab(GTab* tab, int32 index = -1); - int32 CountTabs(); + int32 CountTabs() const; - GTab* TabAt(int32 index); + GTab* TabAt(int32 index); - GTab* RemoveTab(GTab* tab); //just remove, not delete. + GTab* RemoveTab(GTab* tab); //just remove, not delete. int32 IndexOfTab(GTab* tab); void ShiftTabs(int32 delta); // 0 to refresh the current state - void MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons); + void MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons); - void FrameResized(float w, float h) override; + void FrameResized(float w, float h) override; - void OnDropTab(GTab* toTab, BMessage* message); + void OnDropTab(GTab* toTab, BMessage* message); - GTab* SelectedTab(); + GTab* SelectedTab() const; void SelectTab(GTab* tab, bool invoke = true); - GTabView* GetGTabView() { return fGTabView; } + GTabView* GetGTabView() const { return fGTabView; } - tab_affinity GetAffinity() { return fAffinity; } + tab_affinity GetAffinity() const { return fAffinity; } private: void _PrintToStream(); diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index f10f3e93..f830f34e 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -15,10 +15,14 @@ class GTabID : public GTab { public: - GTabID(tab_id id, const char* label): - GTab(label), fId(id){ } + GTabID(tab_id id, const char* label) + : + GTab(label), + fId(id) + { + } - tab_id GetID() { return fId; } + tab_id GetID() const { return fId; } private: tab_id fId; @@ -34,7 +38,8 @@ typedef std::map TabIdMap; class PanelTabView : public GTabView { public: - PanelTabView(PanelTabManager* manager, const char* name, tab_affinity affinity, orientation orientation) + PanelTabView(PanelTabManager* manager, const char* name, + tab_affinity affinity, orientation orientation) : GTabView(name, affinity, orientation) { @@ -64,7 +69,7 @@ class PanelTabView : public GTabView { fIdMap[id].tab->Invalidate(); } - void SaveTabsConfiguration(BMessage& config) + void SaveTabsConfiguration(BMessage& config) { //To maintain the right order, let's use // the index interface (usually discouraged) @@ -89,6 +94,7 @@ class PanelTabView : public GTabView { assert(tab != nullptr && fIdMap.contains(tab->GetID()) == true); fIdMap.erase(tab->GetID()); } + void OnTabAdded(GTab* _tab, BView* panel) override { GTabID* tab = dynamic_cast(_tab); @@ -158,9 +164,8 @@ void PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) { BMessage tab; - int i = 0; - while(fConfig.FindMessage("tab", i++, &tab) == B_OK) - { + int32 i = 0; + while(fConfig.FindMessage("tab", i++, &tab) == B_OK) { tab_id tabid = tab.GetInt32("id", 0); if (tabid == id) { const char* panelName = tab.GetString("panel_group", ""); @@ -180,7 +185,6 @@ PanelTabManager::_AddPanel(const char* tabview_name, BView* panel, tab_id id, in assert (tabview != nullptr); tabview->AddTab(panel, id, index); - } diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h index be4403a1..de731c7a 100644 --- a/src/ui/PanelTabManager.h +++ b/src/ui/PanelTabManager.h @@ -4,10 +4,10 @@ */ #pragma once -#include #include -#include #include + +#include #include class BView; From ba4d02001db1fb8fbe15e78e930b6c072b0ce85f Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 20:22:35 +0100 Subject: [PATCH 22/29] Small style fixes --- src/helpers/gtab/TabButtons.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/helpers/gtab/TabButtons.h b/src/helpers/gtab/TabButtons.h index 607d9570..2c447d92 100644 --- a/src/helpers/gtab/TabButtons.h +++ b/src/helpers/gtab/TabButtons.h @@ -8,9 +8,8 @@ #pragma once -#include -#include #include +#include #include @@ -42,6 +41,7 @@ class TabViewTools { uint32 borders = BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER; be_control_look->DrawInactiveTab(view, bounds, updateRect, base, 0, borders); } + static void DrawDroppingZone(BView* view, BRect rect) { rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); @@ -52,6 +52,7 @@ class TabViewTools { } }; + class GTabButton : public BButton { public: GTabButton(const char* label = nullptr, BMessage* message = nullptr) @@ -101,14 +102,15 @@ class GTabButton : public BButton { const rgb_color& base) { } - }; + class GTabMenuTabButton : public GTabButton { public: GTabMenuTabButton(BMessage* message) - : GTabButton(" ", message) - , fCloseTime(0) + : + GTabButton(" ", message), + fCloseTime(0) { } @@ -151,6 +153,3 @@ class GTabMenuTabButton : public GTabButton { private: bigtime_t fCloseTime; }; - - - From 7d91a4d8caf3be0a3c5fdc3a366dbbdd3b491758 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 20:29:02 +0100 Subject: [PATCH 23/29] Small style fixes --- src/helpers/gtab/GTabView.cpp | 82 +++++++++++++++++------------------ src/helpers/gtab/GTabView.h | 28 +++++------- 2 files changed, 52 insertions(+), 58 deletions(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index c171ca76..ea281506 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -5,10 +5,12 @@ #include "GTabView.h" -#include "TabButtons.h" + +#include + #include "GTab.h" +#include "TabButtons.h" #include "TabsContainer.h" -#include enum { @@ -23,21 +25,22 @@ GTabView::GTabView(const char* name, tab_affinity affinity, orientation content_orientation, bool closeButton, - bool menuButton) : - - BGroupView(name, B_VERTICAL, 0.0f), - fScrollLeftTabButton(nullptr), - fTabsContainer(nullptr), - fScrollRightTabButton(nullptr), - fTabMenuTabButton(nullptr), - fCardView(nullptr), - fCloseButton(closeButton), - fContentOrientation(content_orientation), - fMenuButton(menuButton) + bool menuButton) + : + BGroupView(name, B_VERTICAL, 0.0f), + fScrollLeftTabButton(nullptr), + fTabsContainer(nullptr), + fScrollRightTabButton(nullptr), + fTabMenuTabButton(nullptr), + fCardView(nullptr), + fCloseButton(closeButton), + fContentOrientation(content_orientation), + fMenuButton(menuButton) { _Init(affinity); } + GTab* GTabView::AddTab(const char* label, BView* view, int32 index) { @@ -46,6 +49,7 @@ GTabView::AddTab(const char* label, BView* view, int32 index) return tab; } + void GTabView::AddTab(GTab* tab, BView* view, int32 index) { @@ -62,11 +66,11 @@ GTabView::AddTab(GTab* tab, BView* view, int32 index) void GTabView::DestroyTabAndView(GTab* tab) { - //Remove the View from CardView + // Remove the View from CardView int32 fromIndex = fTabsContainer->IndexOfTab(tab); BLayoutItem* fromLayout = fCardView->CardLayout()->ItemAt(fromIndex); - BView* fromView = fromLayout->View(); - if (!fromView) + BView* fromView = fromLayout->View(); + if (fromView == nullptr) return; fromView->RemoveSelf(); @@ -77,7 +81,7 @@ GTabView::DestroyTabAndView(GTab* tab) OnTabRemoved(rtab); - if (rtab) + if (rtab != nullptr) delete rtab; delete fromView; @@ -109,28 +113,28 @@ GTabView::MessageReceived(BMessage* message) switch(message->what) { case kLeftTabButton: fTabsContainer->ShiftTabs(-1); - break; + break; case kRightTabButton: fTabsContainer->ShiftTabs(+1); - break; + break; case kSelectedTabButton: { int32 index = message->GetInt32("index", 0); if (index > -1) fCardView->CardLayout()->SetVisibleItem(index); + break; } - break; case GTabCloseButton::kTVCloseTab: { - if (fCloseButton == false) + if (!fCloseButton) return; GTab* tab = (GTab*)message->GetPointer("tab", nullptr); if (tab != nullptr) { DestroyTabAndView(tab); } + break; } - break; case kMenuTabButton: { OnMenuTabButton(); @@ -138,7 +142,8 @@ GTabView::MessageReceived(BMessage* message) } default: BGroupView::MessageReceived(message); - }; + break; + } } @@ -146,11 +151,10 @@ void GTabView::OnMenuTabButton() { BPopUpMenu* tabMenu = new BPopUpMenu("tab menu", true, false); - int tabCount = fTabsContainer->CountTabs(); - for (int i = 0; i < tabCount; i++) { + int32 tabCount = fTabsContainer->CountTabs(); + for (int32 i = 0; i < tabCount; i++) { GTab* tab = fTabsContainer->TabAt(i); - - if (tab) { + if (tab != nullptr) { BMenuItem* item = new BMenuItem(tab->Label(), nullptr); tabMenu->AddItem(item); if (tab->IsFront()) @@ -171,7 +175,7 @@ GTabView::OnMenuTabButton() BMenuItem *selected = tabMenu->Go(openPoint, false, false, ConvertToScreen(buttonFrame)); - if (selected) { + if (selected != nullptr) { selected->SetMarked(true); int32 index = tabMenu->IndexOf(selected); if (index != B_ERROR) @@ -179,7 +183,6 @@ GTabView::OnMenuTabButton() } fTabMenuTabButton->MenuClosed(); delete tabMenu; - } @@ -191,7 +194,6 @@ GTabView::_Init(tab_affinity affinity) fScrollLeftTabButton = new GTabScrollLeftButton(new BMessage(kLeftTabButton), fTabsContainer); fScrollRightTabButton = new GTabScrollRightButton(new BMessage(kRightTabButton), fTabsContainer); - fTabMenuTabButton = new GTabMenuTabButton(new BMessage(kMenuTabButton)); fCardView = new BCardView("_cardview_"); @@ -221,14 +223,15 @@ void GTabView::_FixContentOrientation(BView* view) { BLayout* layout = view->GetLayout(); - if (!layout) + if (layout == nullptr) return; + BGroupLayout* grpLayout = dynamic_cast(layout); - if (!grpLayout) { + if (grpLayout == nullptr) { return; } - if (grpLayout->Orientation() != fContentOrientation) - { + + if (grpLayout->Orientation() != fContentOrientation) { grpLayout->SetOrientation(fContentOrientation); } } @@ -245,7 +248,7 @@ GTabView::_AddViewToCard(BView* view, int32 index) void GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) { - //Remove the View from CardView + // Remove the View from CardView int32 fromIndex = fromContainer->IndexOfTab(fromTab); int32 toIndex = -1 ; @@ -259,7 +262,7 @@ GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) BLayoutItem* fromLayout = fromContainer->GetGTabView()->CardView()->CardLayout()->ItemAt(fromIndex); BView* fromView = fromLayout->View(); - if (!fromView) + if (fromView == nullptr) return; fromView->RemoveSelf(); @@ -278,6 +281,7 @@ GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) delete removedTab; } + void GTabView::SelectTab(GTab* tab) { @@ -297,9 +301,3 @@ GTabView::CreateTabView(GTab* clone) { return CreateTabView(clone->Label()); } - - - - - - diff --git a/src/helpers/gtab/GTabView.h b/src/helpers/gtab/GTabView.h index 75d8c7d4..28263a12 100644 --- a/src/helpers/gtab/GTabView.h +++ b/src/helpers/gtab/GTabView.h @@ -5,11 +5,11 @@ #pragma once +#include #include #include #include -#include -#include + class GTabScrollLeftButton; class TabsContainer; @@ -20,8 +20,7 @@ class GTab; typedef uint32 tab_affinity; -class GTabView : public BGroupView -{ +class GTabView : public BGroupView { public: GTabView(const char* name, tab_affinity affinity, @@ -41,25 +40,23 @@ class GTabView : public BGroupView void SelectTab(GTab* tab); - virtual void OnMenuTabButton(); + virtual void OnMenuTabButton(); protected: - void AddTab(GTab* tab, BView* view, int32 index = -1); - virtual void OnTabRemoved(GTab* tab) {}; - virtual void OnTabAdded(GTab* tab, BView* view) {}; + void AddTab(GTab* tab, BView* view, int32 index = -1); + virtual void OnTabRemoved(GTab* tab) {}; + virtual void OnTabAdded(GTab* tab, BView* view) {}; - TabsContainer* Container() { return fTabsContainer; } + TabsContainer* Container() const { return fTabsContainer; } private: - virtual GTab* CreateTabView(const char* label); - virtual GTab* CreateTabView(GTab* clone); - - BCardView* CardView() { return fCardView;} - void DestroyTabAndView(GTab* tab); //Remove and delete a tab and the view. - + virtual GTab* CreateTabView(const char* label); + virtual GTab* CreateTabView(GTab* clone); + BCardView* CardView() const { return fCardView;} + void DestroyTabAndView(GTab* tab); //Remove and delete a tab and the view. private: @@ -77,4 +74,3 @@ class GTabView : public BGroupView orientation fContentOrientation; bool fMenuButton; }; - From 245c540410233ae86c6897ea47f168455b8509ab Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 22:37:19 +0100 Subject: [PATCH 24/29] Further style fixes. Added some more const --- src/helpers/gtab/GTab.h | 60 +++++++++++++++--------------- src/helpers/gtab/TabsContainer.cpp | 22 +++++------ src/helpers/gtab/TabsContainer.h | 10 ++--- 3 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/helpers/gtab/GTab.h b/src/helpers/gtab/GTab.h index 4b193a12..0243fbfd 100644 --- a/src/helpers/gtab/GTab.h +++ b/src/helpers/gtab/GTab.h @@ -9,9 +9,7 @@ #include #include #include -#include #include -#include #include #include @@ -49,14 +47,13 @@ class GTabDropZone : Draggable { virtual bool DropZoneMouseMoved(BView* view, BPoint where, uint32 transit, const BMessage* dragMessage); - virtual bool DropZoneMessageReceived(BMessage* message); virtual void OnDropMessage(BMessage* message) = 0; - TabsContainer* Container() { return fTabsContainer; } + TabsContainer* Container() const { return fTabsContainer; } - void SetContainer(TabsContainer* container) { fTabsContainer = container; } + void SetContainer(TabsContainer* container) { fTabsContainer = container; } virtual void StopDragging(BView* view) { @@ -79,7 +76,8 @@ class GTabDropZone : Draggable { }; -class GTab : public BView , public GTabDropZone { + +class GTab : public BView, public GTabDropZone { public: GTab(const char* label); virtual ~GTab(); @@ -110,7 +108,7 @@ class GTab : public BView , public GTabDropZone { BLayoutItem* LayoutItem() const { return fLayoutItem; } void SetLayoutItem(BLayoutItem* layItem) { fLayoutItem = layItem; } - BString Label() { return fLabel; }; + BString Label() const { return fLabel; }; void SetLabel(const char* label) { fLabel.SetTo(label); } void OnDropMessage(BMessage* message) override; @@ -124,30 +122,29 @@ class GTab : public BView , public GTabDropZone { class GTabCloseButton : public GTab { public: - enum { kTVCloseTab = 'TVCt' }; - - GTabCloseButton(const char* label, const BHandler* handler); - - BSize MinSize() override; - BSize MaxSize() override; - void DrawContents(BView* owner, BRect frame, - const BRect& updateRect, bool isFront) override; - void MouseDown(BPoint where) override; - void MouseUp(BPoint where) override; - void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage) override; -private: - void DrawCloseButton(BView* owner, BRect butFrame, const BRect& updateRect, - bool isFront); + enum { kTVCloseTab = 'TVCt' }; - BRect RectCloseButton(); + GTabCloseButton(const char* label, const BHandler* handler); - void CloseButtonClicked(); + BSize MinSize() override; + BSize MaxSize() override; + void DrawContents(BView* owner, BRect frame, + const BRect& updateRect, bool isFront) override; + void MouseDown(BPoint where) override; + void MouseUp(BPoint where) override; + void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) override; private: + void DrawCloseButton(BView* owner, BRect butFrame, const BRect& updateRect, + bool isFront); + + BRect RectCloseButton(); - bool fOverCloseRect; - bool fClicked; - const BHandler* fHandler; + void CloseButtonClicked(); +private: + bool fOverCloseRect; + bool fClicked; + const BHandler* fHandler; }; @@ -181,7 +178,9 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { public: TabButtonDropZone(BMessage* message, TabsContainer* container) - : GTabButton(" ", message), fRunner(nullptr) + : + GTabButton(" ", message), + fRunner(nullptr) { SetContainer(container); } @@ -201,18 +200,17 @@ class TabButtonDropZone : public GTabButton, public GTabDropZone { void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) override { - if (DropZoneMouseMoved(this, where, transit, dragMessage) == false) + if (!DropZoneMouseMoved(this, where, transit, dragMessage)) GTabButton::MouseMoved(where, transit, dragMessage); } void OnDropMessage(BMessage* message) override { - return; } void MessageReceived(BMessage* message) override { - switch(message->what) { + switch (message->what) { case kRunnerTick: if (fRunner != nullptr && IsEnabled()) { Invoke(); diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 69bc1138..5398efc4 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -39,7 +39,7 @@ TabsContainer::AddTab(GTab* tab, int32 index) index = CountTabs(); BLayoutItem* item = GroupLayout()->AddView(index, tab); - tab->SetLayoutItem (item); + tab->SetLayoutItem(item); tab->SetContainer(this); @@ -59,7 +59,7 @@ TabsContainer::CountTabs() const GTab* -TabsContainer::TabAt(int32 index) +TabsContainer::TabAt(int32 index) const { if (index < 0 || index >= CountTabs()) return nullptr; @@ -69,7 +69,7 @@ TabsContainer::TabAt(int32 index) int32 -TabsContainer::IndexOfTab(GTab* tab) +TabsContainer::IndexOfTab(GTab* tab) const { if (fSelectedTab == nullptr) return -1; @@ -96,7 +96,7 @@ TabsContainer::RemoveTab(GTab* tab) delete tab->LayoutItem(); tab->SetLayoutItem(nullptr); - //fix tab visibility + // fix tab visibility // TODO: this could be further improved by shifting according to the free // available space. int32 shift = 0; @@ -129,7 +129,7 @@ TabsContainer::SelectTab(GTab* tab, bool invoke) fSelectedTab->SetIsFront(true); int32 index = IndexOfTab(fSelectedTab); - if (invoke && Message() && Target()) { + if (invoke && Message() != nullptr && Target() != nullptr) { BMessage msg = *Message(); msg.AddPointer("tab", fSelectedTab); msg.AddInt32("index", IndexOfTab(fSelectedTab)); @@ -141,10 +141,10 @@ TabsContainer::SelectTab(GTab* tab, bool invoke) } else { // let's ensure at least the tab's "middle point" // is visible. - float middle = fSelectedTab->Frame().right - (fSelectedTab->Frame().Width()/2.0f); + float middle = fSelectedTab->Frame().right - (fSelectedTab->Frame().Width() / 2.0f); if (middle > Bounds().right) { int32 shift = 0; - for (int32 i = fTabShift; i < CountTabs();i++) { + for (int32 i = fTabShift; i < CountTabs(); i++) { GTab* nextTab = TabAt(i); middle -= nextTab->Bounds().Width(); shift++; @@ -189,7 +189,7 @@ TabsContainer::MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons) if(buttons & B_PRIMARY_MOUSE_BUTTON) { SelectTab(tab); } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { - + // Nothing } } @@ -198,7 +198,7 @@ TabsContainer::MouseDownOnTab(GTab* tab, BPoint where, const int32 buttons) void TabsContainer::FrameResized(float w, float h) { - //Auto-scroll: + // Auto-scroll: if (fTabShift > 0) { int32 tox = 0; GTab* last = TabAt(CountTabs()-1); @@ -214,7 +214,7 @@ TabsContainer::FrameResized(float w, float h) if (tox != 0) ShiftTabs(tox); } - //end + // end _UpdateScrolls(); BGroupView::FrameResized(w,h); } @@ -235,7 +235,7 @@ TabsContainer::OnDropTab(GTab* toTab, BMessage* message) void TabsContainer::_PrintToStream() { - for (int32 i=0;iCountItems();i++) { + for (int32 i = 0; i < GroupLayout()->CountItems(); i++) { printf("%d) %s\n", i, GroupLayout()->ItemAt(i)->View()->Name()); } } diff --git a/src/helpers/gtab/TabsContainer.h b/src/helpers/gtab/TabsContainer.h index bf0512ef..8586767a 100644 --- a/src/helpers/gtab/TabsContainer.h +++ b/src/helpers/gtab/TabsContainer.h @@ -20,14 +20,11 @@ class TabsContainer : public BGroupView, public BInvoker { BMessage* message = nullptr); void AddTab(GTab* tab, int32 index = -1); - - int32 CountTabs() const; - - GTab* TabAt(int32 index); - GTab* RemoveTab(GTab* tab); //just remove, not delete. + int32 CountTabs() const; - int32 IndexOfTab(GTab* tab); + GTab* TabAt(int32 index) const; + int32 IndexOfTab(GTab* tab) const; void ShiftTabs(int32 delta); // 0 to refresh the current state @@ -38,7 +35,6 @@ class TabsContainer : public BGroupView, public BInvoker { void OnDropTab(GTab* toTab, BMessage* message); GTab* SelectedTab() const; - void SelectTab(GTab* tab, bool invoke = true); GTabView* GetGTabView() const { return fGTabView; } From 8bcb652120c1ea38ecdf875b8514494355501bc7 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Mon, 13 Jan 2025 22:43:06 +0100 Subject: [PATCH 25/29] More style fixes --- src/ui/PanelTabManager.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index f830f34e..2144960d 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -51,7 +51,7 @@ class PanelTabView : public GTabView { GTabView::AddTab(tab, panel, index); } - bool HasTab(tab_id id) + bool HasTab(tab_id id) const { return fIdMap.contains(id); } @@ -71,11 +71,11 @@ class PanelTabView : public GTabView { void SaveTabsConfiguration(BMessage& config) { - //To maintain the right order, let's use + // To maintain the right order, let's use // the index interface (usually discouraged) - for (int32 i=0;iCountTabs();i++) { + for (int32 i = 0;i < Container()->CountTabs(); i++) { GTabID* tabid = dynamic_cast(Container()->TabAt(i)); - if (tabid) { + if (tabid != nullptr) { BMessage tab('TAB '); tab.AddInt32("id", tabid->GetID()); tab.AddString("panel_group", Name()); @@ -109,7 +109,7 @@ class PanelTabView : public GTabView { } private: - TabIdMap fIdMap; + TabIdMap fIdMap; }; @@ -141,7 +141,7 @@ PanelTabManager::CreatePanelTabView(const char* tabview_name, orientation orient { assert(fTVList.contains(tabview_name) == false); - PanelTabView* tabView = new PanelTabView(this, tabview_name, 'GPAF', orientation); + PanelTabView* tabView = new PanelTabView(this, tabview_name, 'GPAF', orientation); fTVList[tabview_name] = tabView; //for (const auto& info:fTVList) { @@ -165,7 +165,7 @@ PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) { BMessage tab; int32 i = 0; - while(fConfig.FindMessage("tab", i++, &tab) == B_OK) { + while (fConfig.FindMessage("tab", i++, &tab) == B_OK) { tab_id tabid = tab.GetInt32("id", 0); if (tabid == id) { const char* panelName = tab.GetString("panel_group", ""); @@ -231,9 +231,9 @@ PanelTabManager::ShowPanelTabView(const char* tabview_name, bool show) { PanelTabView* tabview = _GetPanelTabView(tabview_name); - if (show == true && tabview->IsHidden()) + if (show && tabview->IsHidden()) tabview->Show(); - if (show == false && !tabview->IsHidden()) + if (!show && !tabview->IsHidden()) tabview->Hide(); } From f4dd4b7ceea7ec6ecc718e6d6d45f1e0ca01118c Mon Sep 17 00:00:00 2001 From: Freaxed Date: Wed, 15 Jan 2025 08:51:07 +0100 Subject: [PATCH 26/29] TabManger: restore selected tab from config --- src/ui/PanelTabManager.cpp | 13 +++++++------ src/ui/PanelTabManager.h | 7 ++++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index 2144960d..b2c69c9d 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -45,10 +45,12 @@ class PanelTabView : public GTabView { { } - void AddTab(BView* panel, tab_id id, int32 index=-1) + void AddTab(BView* panel, tab_id id, int32 index=-1, bool select = false) { GTabID* tab = new GTabID(id, panel->Name()); GTabView::AddTab(tab, panel, index); + if (select) + GTabView::SelectTab(tab); } bool HasTab(tab_id id) const @@ -80,9 +82,8 @@ class PanelTabView : public GTabView { tab.AddInt32("id", tabid->GetID()); tab.AddString("panel_group", Name()); tab.AddInt32("index", i); + tab.AddBool("selected", tabid->IsFront()); config.AddMessage("tab", &tab); - //tab_id id = tabid->GetID(); - //printf("%s -> %d ('%.4s')\n", Name(), id, ((char*)&id)); } } } @@ -169,7 +170,7 @@ PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) tab_id tabid = tab.GetInt32("id", 0); if (tabid == id) { const char* panelName = tab.GetString("panel_group", ""); - _AddPanel(panelName, panel, id, tab.GetInt32("index", -1)); + _AddPanel(panelName, panel, id, tab.GetInt32("index", -1), tab.GetBool("selected", false)); return; } } @@ -179,12 +180,12 @@ PanelTabManager::AddPanelByConfig(BView* panel, tab_id id) void -PanelTabManager::_AddPanel(const char* tabview_name, BView* panel, tab_id id, int32 index) +PanelTabManager::_AddPanel(const char* tabview_name, BView* panel, tab_id id, int32 index, bool select) { PanelTabView* tabview = _GetPanelTabView(tabview_name); assert (tabview != nullptr); - tabview->AddTab(panel, id, index); + tabview->AddTab(panel, id, index, select); } diff --git a/src/ui/PanelTabManager.h b/src/ui/PanelTabManager.h index de731c7a..8785b9c7 100644 --- a/src/ui/PanelTabManager.h +++ b/src/ui/PanelTabManager.h @@ -57,7 +57,12 @@ class PanelTabManager { private: - void _AddPanel(const char* tabview_name, BView* panel, tab_id id, int32 index=-1); + void _AddPanel(const char* tabview_name, + BView* panel, + tab_id id, + int32 index=-1, + bool select = false); + PanelTabView* _GetPanelTabView(const char* name); TabViewList fTVList; BMessage fConfig; From 6a2661841556fc0d9877833e4433b45c9084f65f Mon Sep 17 00:00:00 2001 From: Freaxed Date: Wed, 15 Jan 2025 12:53:32 +0100 Subject: [PATCH 27/29] fixed tab selection at startup --- src/helpers/gtab/GTabView.cpp | 6 +++++- src/ui/PanelTabManager.cpp | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/helpers/gtab/GTabView.cpp b/src/helpers/gtab/GTabView.cpp index ea281506..3f9a7ae1 100644 --- a/src/helpers/gtab/GTabView.cpp +++ b/src/helpers/gtab/GTabView.cpp @@ -285,7 +285,11 @@ GTabView::MoveTabs(GTab* fromTab, GTab* toTab, TabsContainer* fromContainer) void GTabView::SelectTab(GTab* tab) { - fTabsContainer->SelectTab(tab); + int32 index = fTabsContainer->IndexOfTab(tab); + if (index > -1) { + fTabsContainer->SelectTab(tab); + fCardView->CardLayout()->SetVisibleItem(index); + } } diff --git a/src/ui/PanelTabManager.cpp b/src/ui/PanelTabManager.cpp index b2c69c9d..0c5f817c 100644 --- a/src/ui/PanelTabManager.cpp +++ b/src/ui/PanelTabManager.cpp @@ -49,8 +49,9 @@ class PanelTabView : public GTabView { { GTabID* tab = new GTabID(id, panel->Name()); GTabView::AddTab(tab, panel, index); - if (select) + if (select) { GTabView::SelectTab(tab); + } } bool HasTab(tab_id id) const From 16c80f909a5aa51a4b7f683569f20ebe1b6d41a7 Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Wed, 15 Jan 2025 16:14:05 +0100 Subject: [PATCH 28/29] Fix 32 bit build --- src/helpers/gtab/TabsContainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/gtab/TabsContainer.cpp b/src/helpers/gtab/TabsContainer.cpp index 5398efc4..002ca069 100644 --- a/src/helpers/gtab/TabsContainer.cpp +++ b/src/helpers/gtab/TabsContainer.cpp @@ -236,7 +236,7 @@ void TabsContainer::_PrintToStream() { for (int32 i = 0; i < GroupLayout()->CountItems(); i++) { - printf("%d) %s\n", i, GroupLayout()->ItemAt(i)->View()->Name()); + printf("%" B_PRIi32 ") %s\n", i, GroupLayout()->ItemAt(i)->View()->Name()); } } From 90a4bd149fb4b3f1452175100b7733acb1bf042d Mon Sep 17 00:00:00 2001 From: Jackburton79 Date: Wed, 22 Jan 2025 22:17:34 +0100 Subject: [PATCH 29/29] Change appearance menu item and config labels. With "moving" tabs, previous names did not make sense. Use "left/right/bottom pane". I didn't rename config names, though. --- src/GenioApp.cpp | 6 +-- src/ui/GenioWindow.cpp | 72 ++++++++++++++++++------------------ src/ui/GenioWindowMessages.h | 6 +-- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/GenioApp.cpp b/src/GenioApp.cpp index 90030740..f670b8ed 100644 --- a/src/GenioApp.cpp +++ b/src/GenioApp.cpp @@ -366,9 +366,9 @@ GenioApp::_PrepareConfig(ConfigManager& cfg) BString generalAppearance = general; generalAppearance.Append("/").Append(B_TRANSLATE("Appearance")); - cfg.AddConfig(generalAppearance.String(), "show_projects", B_TRANSLATE("Show projects pane"), true); - cfg.AddConfig(generalAppearance.String(), "show_outline", B_TRANSLATE("Show outline pane"), true); - cfg.AddConfig(generalAppearance.String(), "show_output", B_TRANSLATE("Show info pane"), true); + cfg.AddConfig(generalAppearance.String(), "show_projects", B_TRANSLATE("Show left pane"), true); + cfg.AddConfig(generalAppearance.String(), "show_outline", B_TRANSLATE("Show right pane"), true); + cfg.AddConfig(generalAppearance.String(), "show_output", B_TRANSLATE("Show bottom pane"), true); cfg.AddConfig(generalAppearance.String(), "show_toolbar", B_TRANSLATE("Show toolbar"), true); cfg.AddConfig(generalAppearance.String(), "show_statusbar", B_TRANSLATE("Show statusbar"), true); cfg.AddConfig(generalAppearance.String(), "use_small_icons", B_TRANSLATE("Use smaller icons in toolbar"), false); diff --git a/src/ui/GenioWindow.cpp b/src/ui/GenioWindow.cpp index cdcac2cf..d3a4ba0e 100644 --- a/src/ui/GenioWindow.cpp +++ b/src/ui/GenioWindow.cpp @@ -276,9 +276,9 @@ GenioWindow::Show() BWindow::Show(); if (LockLooper()) { - _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_LEFT_PANE); + _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_RIGHT_PANE); + _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_BOTTOM_PANE); _ShowView(fToolBar, gCFG["show_toolbar"], MSG_TOGGLE_TOOLBAR); @@ -1080,13 +1080,13 @@ GenioWindow::MessageReceived(BMessage* message) } break; } - case MSG_SHOW_HIDE_PROJECTS: + case MSG_SHOW_HIDE_LEFT_PANE: gCFG["show_projects"] = !bool(gCFG["show_projects"]); break; - case MSG_SHOW_HIDE_OUTLINE: + case MSG_SHOW_HIDE_RIGHT_PANE: gCFG["show_outline"] = !bool(gCFG["show_outline"]); break; - case MSG_SHOW_HIDE_OUTPUT: + case MSG_SHOW_HIDE_BOTTOM_PANE: gCFG["show_output"] = !bool(gCFG["show_output"]); break; case MSG_TOGGLE_TOOLBAR: @@ -1322,17 +1322,17 @@ GenioWindow::_ToogleScreenMode(int32 action) SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_MOVABLE)); ActionManager::SetEnabled(MSG_TOGGLE_TOOLBAR, false); - ActionManager::SetEnabled(MSG_SHOW_HIDE_PROJECTS, false); - ActionManager::SetEnabled(MSG_SHOW_HIDE_OUTLINE, false); - ActionManager::SetEnabled(MSG_SHOW_HIDE_OUTPUT, false); + ActionManager::SetEnabled(MSG_SHOW_HIDE_LEFT_PANE, false); + ActionManager::SetEnabled(MSG_SHOW_HIDE_RIGHT_PANE, false); + ActionManager::SetEnabled(MSG_SHOW_HIDE_BOTTOM_PANE, false); if (action == MSG_FULLSCREEN) { fScreenMode = kFullscreen; } else if (action == MSG_FOCUS_MODE) { _ShowView(fToolBar, false, MSG_TOGGLE_TOOLBAR); - _ShowPanelTabView(kTabViewLeft, false, MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView(kTabViewRight, false, MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView(kTabViewBottom, false, MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, false, MSG_SHOW_HIDE_LEFT_PANE); + _ShowPanelTabView(kTabViewRight, false, MSG_SHOW_HIDE_RIGHT_PANE); + _ShowPanelTabView(kTabViewBottom, false, MSG_SHOW_HIDE_BOTTOM_PANE); fScreenMode = kFocus; } } else { // exit fullscreen @@ -1346,15 +1346,15 @@ GenioWindow::_ToogleScreenMode(int32 action) SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); ActionManager::SetEnabled(MSG_TOGGLE_TOOLBAR, true); - ActionManager::SetEnabled(MSG_SHOW_HIDE_PROJECTS, true); - ActionManager::SetEnabled(MSG_SHOW_HIDE_OUTLINE, true); - ActionManager::SetEnabled(MSG_SHOW_HIDE_OUTPUT, true); + ActionManager::SetEnabled(MSG_SHOW_HIDE_LEFT_PANE, true); + ActionManager::SetEnabled(MSG_SHOW_HIDE_RIGHT_PANE, true); + ActionManager::SetEnabled(MSG_SHOW_HIDE_BOTTOM_PANE, true); _ShowView(fToolBar, fScreenModeSettings["show_toolbar"], MSG_TOGGLE_TOOLBAR); - _ShowPanelTabView(kTabViewLeft, fScreenModeSettings["show_projects"], MSG_SHOW_HIDE_PROJECTS); - _ShowPanelTabView(kTabViewRight, fScreenModeSettings["show_outline"], MSG_SHOW_HIDE_OUTLINE); - _ShowPanelTabView(kTabViewBottom, fScreenModeSettings["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewLeft, fScreenModeSettings["show_projects"], MSG_SHOW_HIDE_LEFT_PANE); + _ShowPanelTabView(kTabViewRight, fScreenModeSettings["show_outline"], MSG_SHOW_HIDE_RIGHT_PANE); + _ShowPanelTabView(kTabViewBottom, fScreenModeSettings["show_output"], MSG_SHOW_HIDE_BOTTOM_PANE); fScreenMode = kDefault; } @@ -2895,19 +2895,19 @@ GenioWindow::_InitActions() "kIconTerminal"); // TODO: Should we call those left/right panes ? - ActionManager::RegisterAction(MSG_SHOW_HIDE_PROJECTS, - B_TRANSLATE("Show projects pane"), - B_TRANSLATE("Show/Hide projects pane"), + ActionManager::RegisterAction(MSG_SHOW_HIDE_LEFT_PANE, + B_TRANSLATE("Show left pane"), + B_TRANSLATE("Show/Hide left pane"), "kIconWinNav"); - ActionManager::RegisterAction(MSG_SHOW_HIDE_OUTLINE, - B_TRANSLATE("Show outline pane"), - B_TRANSLATE("Show/Hide outline pane"), + ActionManager::RegisterAction(MSG_SHOW_HIDE_RIGHT_PANE, + B_TRANSLATE("Show right pane"), + B_TRANSLATE("Show/Hide right pane"), "kIconWinOutline"); - ActionManager::RegisterAction(MSG_SHOW_HIDE_OUTPUT, - B_TRANSLATE("Show info pane"), - B_TRANSLATE("Show/Hide info pane"), + ActionManager::RegisterAction(MSG_SHOW_HIDE_BOTTOM_PANE, + B_TRANSLATE("Show bottom pane"), + B_TRANSLATE("Show/Hide bottom pane"), "kIconWinStat"); ActionManager::RegisterAction(MSG_FULLSCREEN, @@ -3322,9 +3322,9 @@ GenioWindow::_InitMenu() BMenu* windowMenu = new BMenu(B_TRANSLATE("Window")); BMenu* submenu = new BMenu(B_TRANSLATE("Appearance")); - ActionManager::AddItem(MSG_SHOW_HIDE_PROJECTS, submenu); - ActionManager::AddItem(MSG_SHOW_HIDE_OUTLINE, submenu); - ActionManager::AddItem(MSG_SHOW_HIDE_OUTPUT, submenu); + ActionManager::AddItem(MSG_SHOW_HIDE_LEFT_PANE, submenu); + ActionManager::AddItem(MSG_SHOW_HIDE_RIGHT_PANE, submenu); + ActionManager::AddItem(MSG_SHOW_HIDE_BOTTOM_PANE, submenu); ActionManager::AddItem(MSG_TOGGLE_TOOLBAR, submenu); ActionManager::AddItem(MSG_TOGGLE_STATUSBAR, submenu); windowMenu->AddItem(submenu); @@ -3366,9 +3366,9 @@ GenioWindow::_InitToolbar() } else { fToolBar->ChangeIconSize(be_control_look->ComposeIconSize(kDefaultIconSize).Width()); } - ActionManager::AddItem(MSG_SHOW_HIDE_PROJECTS, fToolBar); - ActionManager::AddItem(MSG_SHOW_HIDE_OUTLINE, fToolBar); - ActionManager::AddItem(MSG_SHOW_HIDE_OUTPUT, fToolBar); + ActionManager::AddItem(MSG_SHOW_HIDE_LEFT_PANE, fToolBar); + ActionManager::AddItem(MSG_SHOW_HIDE_RIGHT_PANE, fToolBar); + ActionManager::AddItem(MSG_SHOW_HIDE_BOTTOM_PANE, fToolBar); fToolBar->AddSeparator(); ActionManager::AddItem(MSG_FILE_FOLD_TOGGLE, fToolBar); @@ -4528,11 +4528,11 @@ GenioWindow::_HandleConfigurationChanged(BMessage* message) bool same = ((bool)gCFG["show_white_space"] && (bool)gCFG["show_line_endings"]); ActionManager::SetPressed(MSG_TOGGLE_SPACES_ENDINGS, same); } else if (key.Compare("show_projects") == 0) { - _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_PROJECTS); + _ShowPanelTabView(kTabViewLeft, gCFG["show_projects"], MSG_SHOW_HIDE_LEFT_PANE); } else if (key.Compare("show_outline") == 0) { - _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_OUTLINE); + _ShowPanelTabView(kTabViewRight, gCFG["show_outline"], MSG_SHOW_HIDE_RIGHT_PANE); } else if (key.Compare("show_output") == 0) { - _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_OUTPUT); + _ShowPanelTabView(kTabViewBottom, gCFG["show_output"], MSG_SHOW_HIDE_BOTTOM_PANE); } else if (key.Compare("show_toolbar") == 0) { _ShowView(fToolBar, bool(gCFG["show_toolbar"]), MSG_TOGGLE_TOOLBAR); } else if (key.Compare("show_statusbar") == 0) { diff --git a/src/ui/GenioWindowMessages.h b/src/ui/GenioWindowMessages.h index aa29250a..b95e073a 100644 --- a/src/ui/GenioWindowMessages.h +++ b/src/ui/GenioWindowMessages.h @@ -114,9 +114,9 @@ enum { MSG_RUN_CONSOLE_PROGRAM = 'rcpr', MSG_REPLACE_GROUP_TOGGLED = 'regt', - MSG_SHOW_HIDE_PROJECTS = 'shpr', - MSG_SHOW_HIDE_OUTLINE = 'shol', - MSG_SHOW_HIDE_OUTPUT = 'shou', + MSG_SHOW_HIDE_LEFT_PANE = 'shpr', + MSG_SHOW_HIDE_RIGHT_PANE = 'shol', + MSG_SHOW_HIDE_BOTTOM_PANE = 'shou', MSG_FULLSCREEN = 'fscr', MSG_FOCUS_MODE = 'focu', MSG_SELECT_TAB = 'seta',