1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Feature: Pinned tabs

This commit is contained in:
Chernyavsky Andrey 2022-11-22 01:24:49 +05:00
parent 7293fed046
commit 98a03d5d46
8 changed files with 112 additions and 10 deletions

View file

@ -27,7 +27,13 @@ namespace Beefy.theme.dark
g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.CloseOver), GS!(-4), GS!(-4)); g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.CloseOver), GS!(-4), GS!(-4));
} }
else else
g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Close), GS!(-4), GS!(-4)); {
var tabButton = mParent as TabButton;
if (tabButton.mIsPinned == true)
g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.PinnedTab), GS!(-5), GS!(-5));
else
g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Close), GS!(-4), GS!(-4));
}
} }
public override void MouseClicked(float x, float y, float origX, float origY, int32 btn) public override void MouseClicked(float x, float y, float origX, float origY, int32 btn)
@ -260,19 +266,25 @@ namespace Beefy.theme.dark
menuItem = menu.AddItem("Close"); menuItem = menu.AddItem("Close");
menuItem.mOnMenuItemSelected.Add(new (evt) => menuItem.mOnMenuItemSelected.Add(new (evt) =>
{ {
mTabbedView.CloseTabs(true, true); mTabbedView.CloseTabs(true, true, true);
}); });
menuItem = menu.AddItem("Close Tabs"); menuItem = menu.AddItem("Close Tabs");
menuItem.mOnMenuItemSelected.Add(new (evt) => menuItem.mOnMenuItemSelected.Add(new (evt) =>
{ {
mTabbedView.CloseTabs(false, true); mTabbedView.CloseTabs(false, true, true);
}); });
menuItem = menu.AddItem("Close Tabs Except Current"); menuItem = menu.AddItem("Close Tabs Except Current");
menuItem.mOnMenuItemSelected.Add(new (evt) => menuItem.mOnMenuItemSelected.Add(new (evt) =>
{ {
mTabbedView.CloseTabs(false, false); mTabbedView.CloseTabs(false, false, true);
});
menuItem = menu.AddItem("Close All Except Pinned");
menuItem.mOnMenuItemSelected.Add(new (menu) =>
{
mTabbedView.CloseTabs(false, true, false);
}); });
menu.AddItem(); menu.AddItem();
@ -280,6 +292,9 @@ namespace Beefy.theme.dark
for (var tab in mTabbedView.mTabs) for (var tab in mTabbedView.mTabs)
{ {
menuItem = menu.AddItem(tab.mLabel); menuItem = menu.AddItem(tab.mLabel);
if (tab.mIsPinned)
menuItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.PinnedTab);
menuItem.mOnMenuItemSelected.Add(new (selMenuItem) => menuItem.mOnMenuItemSelected.Add(new (selMenuItem) =>
{ {
TabbedView.TabButton activateTab = tab; TabbedView.TabButton activateTab = tab;

View file

@ -191,6 +191,8 @@ namespace Beefy.theme.dark
PrevBookmarkInFolder, PrevBookmarkInFolder,
NextBookmarkInFolder, NextBookmarkInFolder,
PinnedTab,
COUNT COUNT
}; };

View file

@ -12,6 +12,7 @@ namespace Beefy.widgets
public class TabButton : Widget, IDockable, IDragInterface public class TabButton : Widget, IDockable, IDragInterface
{ {
public bool mIsActive; public bool mIsActive;
public bool mIsPinned;
public String mLabel ~ delete _; public String mLabel ~ delete _;
public TabbedView mTabbedView; public TabbedView mTabbedView;
public WidgetWindow mNewDraggingWindow; public WidgetWindow mNewDraggingWindow;
@ -159,6 +160,7 @@ namespace Beefy.widgets
public void DragEnd() public void DragEnd()
{ {
//mWidgetWindow.mMouseLeftWindowDelegate.Remove(scope => MouseLeftWindow, true); //mWidgetWindow.mMouseLeftWindowDelegate.Remove(scope => MouseLeftWindow, true);
AdjustPinnedState();
if ((mSrcDraggingWindow != null) && (mSrcDraggingWindow.mCaptureWidget != null)) if ((mSrcDraggingWindow != null) && (mSrcDraggingWindow.mCaptureWidget != null))
mSrcDraggingWindow.ReleaseMouseCaptures(); mSrcDraggingWindow.ReleaseMouseCaptures();
@ -175,6 +177,25 @@ namespace Beefy.widgets
mSrcDraggingWindow = null; mSrcDraggingWindow = null;
} }
public void AdjustPinnedState()
{
// Adjusts Tab.mIsPinned state based on neighbouring tabs
bool prevIsPinned = true;
bool nextIsPinned = false;
int position = mTabbedView.mTabs.IndexOf(this);
if (position - 1 >= 0)
prevIsPinned = mTabbedView.mTabs[position - 1].mIsPinned;
if (position + 1 < mTabbedView.mTabs.Count)
nextIsPinned = mTabbedView.mTabs[position + 1].mIsPinned;
mIsPinned = (prevIsPinned == nextIsPinned)
? prevIsPinned
: mIsPinned;
}
public void MouseDrag(float x, float y, float dX, float dY) public void MouseDrag(float x, float y, float dX, float dY)
{ {
mTabbedView.mParentDockingFrame?.GetRootDockingFrame().ShowDragTarget(this); mTabbedView.mParentDockingFrame?.GetRootDockingFrame().ShowDragTarget(this);
@ -309,6 +330,7 @@ namespace Beefy.widgets
mTabbedView.RemoveTab(this, false); mTabbedView.RemoveTab(this, false);
tabbedView.AddTab(this, tabbedView.GetInsertPositionFromCursor()); tabbedView.AddTab(this, tabbedView.GetInsertPositionFromCursor());
Activate(); Activate();
AdjustPinnedState();
} }
} }
else else
@ -391,7 +413,7 @@ namespace Beefy.widgets
return ThemeFactory.mDefault.CreateTabbedView(sharedData); return ThemeFactory.mDefault.CreateTabbedView(sharedData);
} }
public void CloseTabs(bool autoClose, bool closeCurrent) public void CloseTabs(bool autoClose, bool closeCurrent, bool closePinned)
{ {
let prevAutoClose = mAutoClose; let prevAutoClose = mAutoClose;
mAutoClose = autoClose; mAutoClose = autoClose;
@ -414,8 +436,14 @@ namespace Beefy.widgets
{ {
for (var tab in tabs) for (var tab in tabs)
{ {
// Close all except active tab
if ((!closeCurrent) && (tab.mIsActive)) if ((!closeCurrent) && (tab.mIsActive))
continue; continue;
// Close all except pinned tabs
if (closePinned == false && tab.mIsPinned == true)
continue;
tab.mCloseClickedEvent(); tab.mCloseClickedEvent();
} }
} }
@ -570,6 +598,7 @@ namespace Beefy.widgets
RemoveTab(tab, false); RemoveTab(tab, false);
tabbedView.AddTab(tab, tabbedView.GetInsertPositionFromCursor()); tabbedView.AddTab(tab, tabbedView.GetInsertPositionFromCursor());
tab.Activate(); tab.Activate();
tab.AdjustPinnedState();
} }
mParentDockingFrame.RemoveDockedWidget(this); mParentDockingFrame.RemoveDockedWidget(this);
@ -603,5 +632,32 @@ namespace Beefy.widgets
if (tab != null) if (tab != null)
tab.ResizeContent(); tab.ResizeContent();
} }
public void TogglePinned(TabButton tabButton)
{
// Toggles 'mIsPinned' of the tab button
// and adjusts its position in TabbedView.
tabButton.mIsPinned = !tabButton.mIsPinned;
// Remove target tabButton from the tabs
mTabs.Remove(tabButton);
// Find index of right-most non-pinned tab
int index = 0;
for (index = 0; index < mTabs.Count; index++)
{
if (mTabs[index].mIsPinned == false)
break;
}
// Re-insert target tab button
if (index == 0)
mTabs.AddFront(tabButton);
else
mTabs.Insert(index, tabButton);
RehupSize();
}
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Before After
Before After

View file

@ -1295,7 +1295,7 @@ namespace IDE
void CloseTabs() void CloseTabs()
{ {
WithDocumentTabbedViewsOf(window, scope (tabbedView) => { WithDocumentTabbedViewsOf(window, scope (tabbedView) => {
tabbedView.CloseTabs(false, true); tabbedView.CloseTabs(false, true, true);
}); });
} }
@ -1750,6 +1750,7 @@ namespace IDE
data.Add("TabLabel", tabWidget.mLabel); data.Add("TabLabel", tabWidget.mLabel);
data.Add("TabWidth", tabWidget.mWantWidth / DarkTheme.sScale); data.Add("TabWidth", tabWidget.mWantWidth / DarkTheme.sScale);
data.Add("TabIsPinned", tabWidget.mIsPinned);
if (var watchPanel = tabWidget.mContent as WatchPanel) if (var watchPanel = tabWidget.mContent as WatchPanel)
{ {
@ -3186,6 +3187,7 @@ namespace IDE
var newTabButton = new SourceViewTabButton(); var newTabButton = new SourceViewTabButton();
newTabButton.Label = ""; newTabButton.Label = "";
data.GetString("TabLabel", newTabButton.mLabel); data.GetString("TabLabel", newTabButton.mLabel);
newTabButton.mIsPinned = data.GetBool("TabIsPinned");
newTabButton.mOwnsContent = panel.mAutoDelete; newTabButton.mOwnsContent = panel.mAutoDelete;
newTabButton.mTabWidthOffset = panel.TabWidthOffset; newTabButton.mTabWidthOffset = panel.TabWidthOffset;
//newTabButton.mWantWidth = (float)Math.Round(data.GetFloat("TabWidth") * DarkTheme.sScale); //newTabButton.mWantWidth = (float)Math.Round(data.GetFloat("TabWidth") * DarkTheme.sScale);
@ -6251,9 +6253,22 @@ namespace IDE
int GetTabInsertIndex(TabbedView tabs) int GetTabInsertIndex(TabbedView tabs)
{ {
if (mSettings.mUISettings.mInsertNewTabs == .RightOfExistingTabs) if (mSettings.mUISettings.mInsertNewTabs == .RightOfExistingTabs)
{
return tabs.mTabs.Count; return tabs.mTabs.Count;
else }
return 0;
// Find right-most non-pinned tab
// after which we will put our new tab
int index = 0;
for (index = 0; index < tabs.mTabs.Count; index++)
{
if (tabs.mTabs[index].mIsPinned == false)
{
break;
}
}
return index;
} }
public class SourceViewTabButton : DarkTabbedView.DarkTabButton public class SourceViewTabButton : DarkTabbedView.DarkTabButton
@ -6347,7 +6362,16 @@ namespace IDE
Menu menu = new Menu(); Menu menu = new Menu();
if (var sourceViewPanel = mContent as SourceViewPanel) if (var sourceViewPanel = mContent as SourceViewPanel)
{ {
var item = menu.AddItem("Copy Full Path"); var item = menu.AddItem(this.mIsPinned ? "Unpin this tab" : "Pin this tab");
item.mOnMenuItemSelected.Add(new (menu) =>
{
if (mIsRightTab)
IDEApp.sApp.MakeTabPermanent(this);
mTabbedView.TogglePinned(this);
});
item = menu.AddItem("Copy Full Path");
item.mOnMenuItemSelected.Add(new (menu) => item.mOnMenuItemSelected.Add(new (menu) =>
{ {
gApp.SetClipboardText(sourceViewPanel.mFilePath); gApp.SetClipboardText(sourceViewPanel.mFilePath);
@ -6378,7 +6402,12 @@ namespace IDE
item = menu.AddItem("Close All Except This"); item = menu.AddItem("Close All Except This");
item.mOnMenuItemSelected.Add(new (menu) => item.mOnMenuItemSelected.Add(new (menu) =>
{ {
mTabbedView.CloseTabs(false, false); mTabbedView.CloseTabs(false, false, true);
});
item = menu.AddItem("Close All Except Pinned");
item.mOnMenuItemSelected.Add(new (menu) =>
{
mTabbedView.CloseTabs(false, true, false);
}); });
} }