构建Dock类型的应用窗口

Dock类型的UI窗口 是一种常见的用户界面设计模式,通常用于允许用户将某个窗口停靠(dock)在主界面的某个位置,或者将其分离(undock)为独立的浮动窗口。这种设计在许多专业软件中被广泛使用。
在这个教程中,您可以了解到关于WUI的Framework库中的以下功能:
- 在Main Window中添加Tool Bar。Tool Bar可以停靠在Main Window的任意边位、或浮动在其中的任意位置。
- 在Main Window中创建Dock Window与Dock Widget。Dock Widget可以停靠在Dock Window的任意边位、或浮动在其中的任意位置。
下面让我们一步步构建出如下图所示的UI界面。

引入WUI Framework库中Dock相关模块
在Framework库中包含了具备Dock特点的模块,包括MainWindow,DockWindow, DockWidget, EDockArea
import { Button, TreeWidget, TreeNode, TextEdit, TableWidget } from 'wui.basic';
import { MainWindow, DockWindow, DockWidget, EDockArea } from 'wui.framework';
import "./theme";
创建Main Window
Main Window在UI中承担了界面主窗口的角色,它可以容纳一个menu Bar, 一个central widget, 一个status bar, 以及任意多个tool bar。
下面我们创建一个main window,然后为它的menu bar添加一个名为File的菜单
const mainWindow = new MainWindow();
const menuBar = mainWindow.menuBar;
const fileMenu = menuBar.add('File');
菜单中添加具体的选项,比如New,Open,Save
fileMenu.width = 200;
fileMenu.addItem('New', '../../images/file_48.png').shortcutKey = 'Ctrl+N';
fileMenu.addItem('Open', '../../images/AppMenu-Open_32.png').shortcutKey = 'Ctrl+O';
fileMenu.addItem('Save', '../../images/AppMenu-Save_32.png').shortcutKey = 'Ctrl+S';
fileMenu.addItem('Save As', '../../images/AppMenu-SaveAs_32.png').shortcutKey = 'Ctrl+Shift+S';
fileMenu.addSeparator();
fileMenu.addItem('Exit', '../../images/App_Menu_Close.png').shortcutKey = 'Ctrl+Q';

添加Tool Bar
mainWindow的上、下、左、右都是tool bar的停靠位,使用addToolBar添加tool bar,如果没有指定停靠位,会默认停靠在上方位。
tool bar的最左侧是它的抓手,在界面中抓取到它后,拖动tool bar可以离开停靠位,成为浮动工具栏。
可以添加任意多个tool bar,它们可以不断堆叠停靠。
const viewToolBar = mainWindow.addToolBar(EDockArea.Top);
new Button(viewToolBar, undefined, '../../images/view_from_back_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_bottom_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_front_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_home_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_left_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_right_32.png');
new Button(viewToolBar, undefined, '../../images/view_from_top_32.png');

添加Dock Window 和 Dock Widget
先有Dock Window,再有Dock Widget,您必须使用addDockWidget,将Dock Widget添加到Dock Window中,UI中才会出现该dock widget。
首先我们创建一个dockWindow,并使它成为mainWindow的central widget,然后为这个dock window添加一个dock widget,使它初始停靠在其左侧。
在UI中,用户可以拖拽dock widget顶部的抓手,更改它的停靠方位,或者浮动在dock window任意位置。
我们之后可以陆续再为该dock window添加两个 dock widget,使它们停靠在左方和下方。
const dockWindow = new DockWindow(mainWindow.centralWidget);
const treeDockWidget = new DockWidget('Dock Widget 1');
dockWindow.addDockWidget(treeDockWidget, EDockArea.Left);

向Dock Widget添加功能组件
我们使用TreeWidget接口,创建一个树型结构的控件,并不断向这个树中添加节点。
这个树控件以我们在上面创建的dock widget为父控件,因此在拖动dock widget时,这个树也一同被拖动。
// treeWidget
const treeWidget = new TreeWidget(treeDockWidget);
treeWidget.css = { 'border': '0px' };
const partSet = new TreeNode(treeWidget.root, 'Part set');
partSet.expanded = true;
new TreeNode(partSet, 'Paremeters(0)', '../../images/Results-Parts_32.png');
const constructions = partSet.addNode('Constructions(7)', '../../images/Results-Planes_32.png');
constructions.expanded = true;
const viewIcon = '../../images/view_from_back_32.png';
constructions.addNode('Origin', viewIcon);
constructions.addNode('OX', viewIcon);
constructions.addNode('OY', viewIcon);
constructions.addNode('OZ', viewIcon);
constructions.addNode('YOZ', viewIcon);
constructions.addNode('XOZ', viewIcon);
constructions.addNode('XOY', viewIcon);
