S&box Wiki

Revision Difference

Widget_Docking#551938

<cat>Code.Editor</cat>⤶ <title>Widget Docking</title>⤶ ⤶ # Widget Docking⤶ ⤶ Widget docking makes it easy for users to layout the UI you make how they want.⤶ The editor makes heavy use of docking to allow for these customizations.⤶ If you just want to add a widget to an existing dock window (such as the editor or hammer), <page text="read this">Guide_to_Widgets#option1widgetwithdockattribute</page>.⤶ ⤶ The [DockWindow widget](https://asset.party/api/Editor.DockWindow) provides a [DockManager](https://asset.party/api/Editor.DockManager) for creating docks and adding widgets to them.⤶ ⤶ To get started, create a class the inherits the DockWindow widget and add some method of opening it.⤶ If you're not sure how to open it, <page text="read this">Guide_to_Widgets#creatingandopeningawindow</page>.⤶ ⤶ Create a widget, and add the widget to the dock manager in your constructor like this⤶ ```cs⤶ public SomeWidgetConstuctor() {⤶ //code ...⤶ ⤶ Label dockedWidget = new("a docked widget!", this) { WindowTitle = "this will show up on the tab" };⤶ DockManager.AddDock(null, dockedWidget);⤶ }⤶ ```⤶ ⤶ The result of adding these two lines will look something like this⤶ <upload src="8f39a/8dbc8234b45f814.png" size="12055" name="sbox-dev_YC6iRNpRUI.png" />⤶ ⤶ Duplicate the code above, and you will have two docks each with a widget of their own⤶ <upload src="8f39a/8dbc8251712f234.png" size="18110" name="sbox-dev_Zk3oF04mhJ.png" />⤶ ⤶ With just two docks, the widgets can now be dragged around inside the dock window and oriented how the user desires⤶ ⤶ You can have multiple widgets docked ontop each other by using [DockArea.Inside](https://asset.party/api/Editor.DockArea.Inside) as the third parameter of [DockManager.AddDock](https://asset.party/api/Editor.DockManager.AddDock(Widget,Widget,DockArea,DockProperty,float))⤶ ```cs⤶ Label widgetThree = new("some docked widget", this) { WindowTitle = "widget three" };⤶ DockManager.AddDock(null, widgetThree, DockArea.Inside);⤶ ```⤶ ⤶ You can choose what widget to dock ontop of by specifying the first parameter⤶ ⤶ ```cs⤶ Label widgetOne = new("a docked widget!", this) { WindowTitle = "widget one" };⤶ DockManager.AddDock(null, widgetOne);⤶ ⤶ //docks left of widgetOne⤶ Label widgetTwo = new("another docked widget!", this) { WindowTitle = "widget two" };⤶ DockManager.AddDock(null, widgetTwo);⤶ ⤶ //docks ontop of widgetOne⤶ Label widgetThree = new("some docked widget", this) { WindowTitle = "widget three" };⤶ DockManager.AddDock(widgetOne, widgetThree, DockArea.Inside);⤶ ```⤶ ⤶ Which will look like this⤶ <upload src="8f39a/8dbc8269cb73b6f.png" size="17936" name="sbox-dev_By658ffPBs.png" />⤶ ⤶ # Dock Properties⤶ ⤶ Remember that these widgets can be move around however the user wants.⤶ If you want to add restrictions, you can use a [DockProperty](https://asset.party/api/Editor.DockManager.DockProperty) eg.⤶ ```cs⤶ Label widgetOne = new("a docked widget!", this) { WindowTitle = "widget one" };⤶ DockManager.AddDock(null, widgetOne, DockArea.Left, DockManager.DockProperty.DisallowUserDocking);⤶ ```⤶ This will prevent the widget from being docked elsewhere. The widget can still be closed, so to prevent that you can add the [HideCloseButton](https://asset.party/api/Editor.DockManager.DockProperty.HideCloseButton) property.⤶ ```cs⤶ Label widgetOne = new("a docked widget!", this) { WindowTitle = "widget one" };⤶ DockManager.AddDock(null, widgetOne, DockArea.Left, DockManager.DockProperty.DisallowUserDocking | DockManager.DockProperty.HideCloseButton);⤶ ```⤶ ⤶ <note>All widgets are forced to use [DockProperty.AlwaysDisplayFullTabs](https://asset.party/api/Editor.DockManager.DockProperty.AlwaysDisplayFullTabs) as a dock property with the current implementation of DockManager.AddDock</note>⤶ ⤶ # Registering Docks⤶ ⤶ You may want to let players close and reopen docked widgets. You can do this by registering a dock and creating a widget with the the same name as the dock.⤶ ⤶ ```cs⤶ Label hidableWidget = new("another docked widget!", this) {⤶ Name = "SomeWidgetName",⤶ WindowTitle = "widget two",⤶ };⤶ ⤶ //register the dock, and dont delete it on close⤶ DockManager.RegisterDockType("SomeWidgetName", "directions_boat", null, false);⤶ DockManager.AddDock(null, hidableWidget);⤶ ```⤶ ⤶ We will use a view menu in the menu bar to list the widgets that can be hidden. This will let users hide and show the widget.⤶ ⤶ Add a method in your dock window's class for when the view menu opens⤶ ```cs⤶ void OnViewMenu(Menu view) {⤶ //clear the old options⤶ view.Clear();⤶ ⤶ //it's a good idea to allow resetting to some default state⤶ //you can override RestoreDefaultDockLayout to dock the widgets however you want⤶ view.AddOption("Restore To Default", "settings_backup_restore", RestoreDefaultDockLayout);⤶ view.AddSeparator();⤶ ⤶ //create an option in the view menu for every registered dock⤶ foreach (DockManager.DockInfo dockInfo in DockManager.DockTypes) {⤶ if (dockInfo.DeleteOnClose)⤶ continue;⤶ ⤶ Option option = view.AddOption(dockInfo.Title, dockInfo.Icon);⤶ option.Checkable = true;⤶ option.Checked = DockManager.IsDockOpen(dockInfo.Title);⤶ option.Toggled += (state) => DockManager.SetDockState(dockInfo.Title, state);⤶ }⤶ }⤶ ```⤶ ⤶ Then add the view menu to the menu bar in your dock window's constructor⤶ ```cs⤶ Menu viewMenu = MenuBar.AddMenu("View");⤶ viewMenu.AboutToShow += () => OnViewMenu(viewMenu);⤶ ```⤶ ⤶ It should appear like this⤶ <upload src="8f39a/8dbc82b5f80c60b.png" size="3628" name="sbox-dev_vNSaAgsdjO.png" />⤶ <upload src="8f39a/8dbc82b6ad5ea6d.png" size="5507" name="sbox-dev_uGXGYtezxS.png" />⤶ ⤶ Clicking the option in the view menu will now hide and show the widget