Bladeren bron

Merge pull request #1756 from kallisto56/master

Feature: Pinned tabs
Brian Fiete 2 jaren geleden
bovenliggende
commit
f01665ac06

+ 19 - 4
BeefLibs/Beefy2D/src/theme/dark/DarkTabbedView.bf

@@ -27,7 +27,13 @@ namespace Beefy.theme.dark
                         g.Draw(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.CloseOver), GS!(-4), GS!(-4));
                 }
                 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)
@@ -260,19 +266,25 @@ namespace Beefy.theme.dark
 				menuItem = menu.AddItem("Close");
 				menuItem.mOnMenuItemSelected.Add(new (evt) =>
 					{
-						mTabbedView.CloseTabs(true, true);
+						mTabbedView.CloseTabs(true, true, true);
 					});
 
 				menuItem = menu.AddItem("Close Tabs");
 				menuItem.mOnMenuItemSelected.Add(new (evt) =>
 					{
-						mTabbedView.CloseTabs(false, true);
+						mTabbedView.CloseTabs(false, true, true);
 					});
 
 				menuItem = menu.AddItem("Close Tabs Except Current");
 				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();
@@ -280,6 +292,9 @@ namespace Beefy.theme.dark
                 for (var tab in mTabbedView.mTabs)
                 {
                     menuItem = menu.AddItem(tab.mLabel);
+					if (tab.mIsPinned)
+						menuItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.PinnedTab);
+
                     menuItem.mOnMenuItemSelected.Add(new (selMenuItem) =>
 	                    {
 	                        TabbedView.TabButton activateTab = tab;

+ 2 - 0
BeefLibs/Beefy2D/src/theme/dark/DarkTheme.bf

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

+ 57 - 1
BeefLibs/Beefy2D/src/widgets/TabbedView.bf

@@ -12,6 +12,7 @@ namespace Beefy.widgets
         public class TabButton : Widget, IDockable, IDragInterface
         {
             public bool mIsActive;
+			public bool mIsPinned;
             public String mLabel ~ delete _;
             public TabbedView mTabbedView;
             public WidgetWindow mNewDraggingWindow;
@@ -159,6 +160,7 @@ namespace Beefy.widgets
             public void DragEnd()
             {
                 //mWidgetWindow.mMouseLeftWindowDelegate.Remove(scope => MouseLeftWindow, true);
+				AdjustPinnedState();
 
                 if ((mSrcDraggingWindow != null) && (mSrcDraggingWindow.mCaptureWidget != null))
 					mSrcDraggingWindow.ReleaseMouseCaptures();
@@ -175,6 +177,25 @@ namespace Beefy.widgets
                 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)
             {
                	mTabbedView.mParentDockingFrame?.GetRootDockingFrame().ShowDragTarget(this);                
@@ -309,6 +330,7 @@ namespace Beefy.widgets
                         mTabbedView.RemoveTab(this, false);
                         tabbedView.AddTab(this, tabbedView.GetInsertPositionFromCursor());
                         Activate();
+						AdjustPinnedState();
                     }
                 }
                 else
@@ -391,7 +413,7 @@ namespace Beefy.widgets
 			return ThemeFactory.mDefault.CreateTabbedView(sharedData);
 		}
 
-		public void CloseTabs(bool autoClose, bool closeCurrent)
+		public void CloseTabs(bool autoClose, bool closeCurrent, bool closePinned)
 		{
 			let prevAutoClose = mAutoClose;
 			mAutoClose = autoClose;
@@ -414,8 +436,14 @@ namespace Beefy.widgets
 			{
 				for (var tab in tabs)
 				{
+					// Close all except active tab
 					if ((!closeCurrent) && (tab.mIsActive))
 						continue;
+
+					// Close all except pinned tabs
+					if (closePinned == false && tab.mIsPinned == true)
+						continue;
+
 					tab.mCloseClickedEvent();
 				}
 			}
@@ -570,6 +598,7 @@ namespace Beefy.widgets
                     RemoveTab(tab, false);
                     tabbedView.AddTab(tab, tabbedView.GetInsertPositionFromCursor());
                     tab.Activate();
+					tab.AdjustPinnedState();
                 }                
                 mParentDockingFrame.RemoveDockedWidget(this);
 
@@ -603,5 +632,32 @@ namespace Beefy.widgets
             if (tab != null)
                 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();
+		}
     }
 }

BIN
IDE/dist/images/DarkUI.png


BIN
IDE/dist/images/DarkUI.psd


BIN
IDE/dist/images/DarkUI_2.png


BIN
IDE/dist/images/DarkUI_4.png


+ 34 - 5
IDE/src/IDEApp.bf

@@ -1295,7 +1295,7 @@ namespace IDE
 			void CloseTabs()
 			{
 				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("TabWidth", tabWidget.mWantWidth / DarkTheme.sScale);
+						data.Add("TabIsPinned", tabWidget.mIsPinned);
 
 						if (var watchPanel = tabWidget.mContent as WatchPanel)
 						{
@@ -3186,6 +3187,7 @@ namespace IDE
                 var newTabButton = new SourceViewTabButton();
                 newTabButton.Label = "";
                 data.GetString("TabLabel", newTabButton.mLabel);
+				newTabButton.mIsPinned = data.GetBool("TabIsPinned");
 				newTabButton.mOwnsContent = panel.mAutoDelete;
 				newTabButton.mTabWidthOffset = panel.TabWidthOffset;
                 //newTabButton.mWantWidth = (float)Math.Round(data.GetFloat("TabWidth") * DarkTheme.sScale);
@@ -6251,9 +6253,22 @@ namespace IDE
 		int GetTabInsertIndex(TabbedView tabs)
 		{
 			if (mSettings.mUISettings.mInsertNewTabs == .RightOfExistingTabs)
+			{
 				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
@@ -6347,7 +6362,16 @@ namespace IDE
 					Menu menu = new Menu();
 					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) =>
 							{
 								gApp.SetClipboardText(sourceViewPanel.mFilePath);
@@ -6378,7 +6402,12 @@ namespace IDE
 						item = menu.AddItem("Close All Except This");
 						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);
 							});
 					}