dockable panels, part 1

This commit is contained in:
Vadim Lopatin 2015-01-15 17:35:28 +03:00
parent 96a0213145
commit 94c494a690
7 changed files with 169 additions and 3 deletions

View File

@ -381,6 +381,7 @@
<File path="src\dlangui\widgets\appframe.d" />
<File path="src\dlangui\widgets\combobox.d" />
<File path="src\dlangui\widgets\controls.d" />
<File path="src\dlangui\widgets\docks.d" />
<File path="src\dlangui\widgets\editors.d" />
<File path="src\dlangui\widgets\grid.d" />
<File path="src\dlangui\widgets\layouts.d" />

View File

@ -223,6 +223,39 @@
padding="4,4,4,4"
layoutWeight="0"
/>
<style id="DOCK_HOST"
backgroundColor="#303080"
layoutWidth="FILL_PARENT"
layoutHeight="FILL_PARENT"
padding="4,4,4,4"
margins="4,4,4,4"
/>
<style id="DOCK_WINDOW"
backgroundColor="#D0D0FF"
layoutWidth="FILL_PARENT"
layoutHeight="FILL_PARENT"
padding="1,1,1,1"
margins="4,4,4,4"
/>
<style id="DOCK_WINDOW_CAPTION"
backgroundColor="#202060"
layoutWidth="FILL_PARENT"
layoutHeight="WRAP_CONTENT"
padding="1,1,1,1"
/>
<style id="DOCK_WINDOW_CAPTION_LABEL"
textColor="#FFFFFF"
layoutWidth="FILL_PARENT"
layoutHeight="WRAP_CONTENT"
padding="2,2,2,2"
align="Left|VCenter"
/>
<style id="DOCK_WINDOW_BODY"
backgroundColor="#FFFFFF"
layoutWidth="FILL_PARENT"
layoutHeight="FILL_PARENT"
padding="1,1,1,1"
/>
<style id="TREE_ITEM"
padding="2,2,2,2"
margins="0,0,0,0"

View File

@ -69,6 +69,7 @@ public import dlangui.widgets.combobox;
public import dlangui.widgets.popup;
public import dlangui.widgets.appframe;
public import dlangui.widgets.statusline;
public import dlangui.widgets.docks;
public import dlangui.platforms.common.platform;
// some useful imports from Phobos

View File

@ -258,6 +258,8 @@ struct ObjectList(T) {
}
/** find child index for item, return -1 if not found */
int indexOf(T item) {
if (item is null)
return -1;
for (int i = 0; i < _count; i++)
if (_list[i] == item)
return i;
@ -287,6 +289,21 @@ struct ObjectList(T) {
_list[index] = item;
destroy(old);
}
/** Replace item with another value, destroy old value. */
void replace(T newItem, T oldItem) {
int idx = indexOf(oldItem);
if (newItem is null) {
if (idx >= 0) {
T item = remove(idx);
destroy(item);
}
} else {
if (idx >= 0)
replace(newItem, idx);
else
add(newItem);
}
}
/** remove and destroy all items */
void clear() {
for (int i = 0; i < _count; i++) {

View File

@ -0,0 +1,84 @@
module dlangui.widgets.docks;
import dlangui.widgets.layouts;
import dlangui.widgets.controls;
class DockHost : WidgetGroupDefaultDrawing {
protected Widget _bodyWidget;
@property Widget bodyWidget() { return _bodyWidget; }
@property void bodyWidget(Widget widget) {
_children.replace(_bodyWidget, widget);
_bodyWidget = widget;
_bodyWidget.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
}
this() {
super("DOCK_HOST");
}
}
enum DockAlignment {
Left,
Right,
Top,
Bottom
}
class DockWindow : VerticalLayout {
protected Widget _bodyWidget;
@property Widget bodyWidget() { return _bodyWidget; }
@property void bodyWidget(Widget widget) {
_children.replace(_bodyWidget, widget);
_bodyWidget = widget;
_bodyWidget.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
}
protected DockAlignment _dockAlignment;
protected HorizontalLayout _captionLayout;
protected TextWidget _caption;
protected ImageButton _closeButton;
this(string ID) {
super(ID);
init();
}
protected bool onCloseButtonClick(Widget source) {
return true;
}
protected void init() {
styleId = STYLE_DOCK_WINDOW;
_captionLayout = new HorizontalLayout("DOCK_WINDOW_CAPTION_PANEL");
_captionLayout.layoutWidth(FILL_PARENT).layoutHeight(WRAP_CONTENT);
_captionLayout.styleId = STYLE_DOCK_WINDOW_CAPTION;
uint bcolor = _captionLayout.backgroundColor;
Log.d("caption layout back color=", bcolor);
//_captionLayout.backgroundColor = 0x204060;
_caption = new TextWidget("DOCK_WINDOW_CAPTION");
_caption.styleId = STYLE_DOCK_WINDOW_CAPTION_LABEL;
_closeButton = new ImageButton("DOCK_WINDOW_CAPTION_CLOSE_BUTTON");
_closeButton.styleId = STYLE_BUTTON_TRANSPARENT;
_closeButton.drawableId = "close";
_closeButton.trackHover = true;
_closeButton.onClickListener = &onCloseButtonClick;
_captionLayout.addChild(_caption);
_captionLayout.addChild(_closeButton);
_bodyWidget = createBodyWidget();
_bodyWidget.styleId = STYLE_DOCK_WINDOW_BODY;
//_bodyWidget.backgroundColor = 0xFFFFFF;
//_bodyWidget.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
addChild(_captionLayout);
addChild(_bodyWidget);
}
protected Widget createBodyWidget() {
return new Widget("DOCK_WINDOW_BODY");
}
}

View File

@ -34,6 +34,7 @@ class StatusLine : HorizontalLayout {
void init() {
_defStatus = new TextWidget("STATUS_LINE_TEXT");
_defStatus.layoutWidth(FILL_PARENT);
_defStatus.text = "DLANGUI"d;
addChild(_defStatus);
}
/// set text to show in status line in specific panel

View File

@ -119,6 +119,15 @@ immutable string STYLE_COMBO_BOX_BODY = "COMBO_BOX_BODY";
/// standard style id for app frame status line
immutable string STYLE_STATUS_LINE = "STATUS_LINE";
/// standard style id for dock window caption
immutable string STYLE_DOCK_WINDOW_CAPTION = "DOCK_WINDOW_CAPTION";
/// standard style id for dock window
immutable string STYLE_DOCK_WINDOW = "DOCK_WINDOW";
/// standard style id for dock window caption label
immutable string STYLE_DOCK_WINDOW_CAPTION_LABEL = "DOCK_WINDOW_CAPTION_LABEL";
/// standard style id for dock window body
immutable string STYLE_DOCK_WINDOW_BODY = "DOCK_WINDOW_BODY";
// Layout size constants
/// layout option, to occupy all available place
immutable int FILL_PARENT = int.max - 1;
@ -737,6 +746,9 @@ class Theme : Style {
~this() {
//Log.d("Theme destructor");
if (unknownStyleIds.length > 0) {
Log.e("Unknown style statistics: ", unknownStyleIds);
}
foreach(ref Style item; _byId) {
destroy(item);
item = null;
@ -817,10 +829,21 @@ class Theme : Style {
return style;
}
/// to track unknown styles refernced from code
int[string] unknownStyleIds;
/// find style by id, returns theme if not style with specified ID is not found
@property Style get(string id) {
if (id !is null && id in _byId)
if (id is null)
return this;
if (id in _byId)
return _byId[id];
// track unknown style ID references
if (id in unknownStyleIds)
unknownStyleIds[id] = unknownStyleIds[id] + 1;
else {
Log.e("Unknown style ID requested: ", id);
unknownStyleIds[id] = 1;
}
return this;
}
@ -1085,10 +1108,16 @@ int decodeLayoutDimension(string s) {
/// load style attributes from XML element
bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
//Log.d("Theme: loadStyleAttributes ", style.id, " ", elem.tag.attr);
if ("backgroundImageId" in elem.tag.attr)
style.backgroundImageId = elem.tag.attr["backgroundImageId"];
if ("backgroundColor" in elem.tag.attr)
style.backgroundColor = decodeHexColor(elem.tag.attr["backgroundColor"]);
if ("backgroundColor" in elem.tag.attr) {
uint col = decodeHexColor(elem.tag.attr["backgroundColor"]);
style.backgroundColor = col;
//Log.d(" background color=", col);
} else {
//Log.d(" no background color attr");
}
if ("textColor" in elem.tag.attr)
style.textColor = decodeHexColor(elem.tag.attr["textColor"]);
if ("margins" in elem.tag.attr)