diff --git a/Nasal/canvas/gui/Style.nas b/Nasal/canvas/gui/Style.nas
index 5b7c1813b..063333ae2 100644
--- a/Nasal/canvas/gui/Style.nas
+++ b/Nasal/canvas/gui/Style.nas
@@ -11,33 +11,47 @@ gui.Style = {
_path: style_path,
_dir_icons: gui_path ~ "/icons/" ~ name_icon_theme,
_node: io.read_properties(style_path ~ "/style.xml", root_node),
- _colors: {}
+ _colors: {},
+ _sizes: {}
};
# parse theme colors
- var comp_names = ["red", "green", "blue", "alpha"];
var colors = m._node.getChild("colors");
if( colors != nil )
{
foreach(var color; colors.getChildren())
{
- var str = "rgba(";
- for(var i = 0; i < size(comp_names); i += 1)
- {
- if( i > 0 )
- str ~= ",";
- var val = color.getValue(comp_names[i]);
- if( val == nil )
- val = 1;
- if( i < 3 )
- str ~= int(val * 255 + 0.5);
- else
- str ~= int(val * 100) / 100;
+ var tintNode = color.getChild("tint");
+ var shadeNode = color.getChild("shade");
+ var baseNode = color.getChild("base");
+
+ if (tintNode and baseNode) {
+
+ } elsif (shadeNode and baseNode) {
+
+ } else {
+ # todo : support a CSS style color as a direct text child,
+ # instead of seperate RGBA components
+ m._colors[ color.getName() ] = m._parseRGBANodes(color);
}
- m._colors[ color.getName() ] = str ~ ")";
}
}
+ var sizes = m._node.getChild("sizes");
+ if (sizes) {
+ foreach(var sizeNode; sizes.getChildren()) {
+ var factorNode = sizeNode.getChild("factor");
+ var baseNode = sizeNode.getChild("base");
+ if (factorNode or baseNode) {
+ var f = factorNode.getValue() or 1.0;
+ m._sizes[sizeNode.getName()] = f * m.getSize(baseNode.getValue(), 1.0);
+ } else {
+ # simple literal value, easy
+ m._sizes[sizeNode.getName()] = sizeNode.getValue();
+ }
+ } # of sizes iteration
+ }
+
m._dir_decoration =
m._path ~ "/" ~ (m._node.getValue("folders/decoration") or "decoration");
m._dir_widgets =
@@ -45,8 +59,31 @@ gui.Style = {
return m;
},
+ _parseRGBANodes: func(color)
+ {
+ var comp_names = ["red", "green", "blue", "alpha"];
+ var str = "rgba(";
+ for(var i = 0; i < size(comp_names); i += 1)
+ {
+ if( i > 0 )
+ str ~= ",";
+ var val = color.getValue(comp_names[i]);
+ if( val == nil )
+ val = 1;
+ if( i < 3 )
+ str ~= int(val * 255 + 0.5);
+ else
+ str ~= int(val * 100) / 100;
+ }
+ return str ~ ")";
+ },
+
getColor: func(name, def = "#00ffff")
{
return me._colors[name] or def;
+ },
+ getSize: func(name, def = 1.0)
+ {
+ return me._sizes[name] or def;
}
};
diff --git a/Nasal/canvas/gui/styles/DefaultStyle.nas b/Nasal/canvas/gui/styles/DefaultStyle.nas
index ebd1f340e..a89835f83 100644
--- a/Nasal/canvas/gui/styles/DefaultStyle.nas
+++ b/Nasal/canvas/gui/styles/DefaultStyle.nas
@@ -1063,8 +1063,11 @@ DefaultStyle.widgets["combo-box"] = {
setSize: func(model, w, h)
{
var halfWidth = int(w * 0.5);
+ var m = me._style.getSize("margin");
+ var inset = me._style.getSize("text-inset");
+
me._bg.reset()
- .rect(3, 3, w - 6, h - 6, {"border-radius": 5});
+ .rect(m, m, w - (m * 2), h - (m * 2), {"border-radius": me._style.getSize("frame-radius")});
# we split the two pieces
me._border.setSize(halfWidth, h);
@@ -1072,15 +1075,15 @@ DefaultStyle.widgets["combo-box"] = {
me._buttonBorder.setSize(w - halfWidth, h);
var arrowSize = me._arrowIcon.imageSize();
- me._arrowIcon.setTranslation(w - (arrowSize[0] + 20), (h - arrowSize[1]) * 0.5);
+ me._arrowIcon.setTranslation(w - (arrowSize[0] + inset), (h - arrowSize[1]) * 0.5);
- me._label.setTranslation(20, h * 0.5);
+ me._label.setTranslation(inset, h * 0.5);
},
setText: func(model, text)
{
me._label.setText(text);
-
- var min_width = math.max(80, me._label.maxWidth() + 16 + me._arrowIcon.imageSize()[0]);
+ var inset = me._style.getSize("text-inset");
+ var min_width = math.max(80, me._label.maxWidth() + inset + me._arrowIcon.imageSize()[0]);
model.setLayoutMinimumSize([min_width, 16]);
model.setLayoutSizeHint([min_width, 28]);
@@ -1142,23 +1145,26 @@ DefaultStyle.widgets["list-item"] = {
new: func(parent, cfg) {
me._root = parent.createChild("group", "list-item");
me._bg = me._root.createChild("path");
-
+ me._itemHeight = me._style.getSize("list-item-height");
+
me._label = me._root.createChild("text")
.set("font", "LiberationFonts/LiberationSans-Regular.ttf")
- .set("character-size", 14)
+ .set("character-size", me._style.getSize("list-font-size"))
.set("alignment", "left-baseline");
},
setSize: func(model, w, h) {
- me._bg.reset().rect(0, 0, w, 24);
- me._label.setTranslation(5, int(h / 2) + 4);
+ me._bg.reset().rect(0, 0, w, me._itemHeight);
+ var m = me._style.getSize("margin");
+ me._label.setTranslation(m, int(h / 2) + m);
return me;
},
_updateLayoutSizes: func(model) {
- var min_width = 5 + me._label.maxWidth() + 5;
- model.setLayoutMinimumSize([min_width, 24]);
- model.setLayoutSizeHint([min_width, 24]);
+ var m = me._style.getSize("margin");
+ var min_width = m + me._label.maxWidth() + m;
+ model.setLayoutMinimumSize([min_width, me._itemHeight]);
+ model.setLayoutSizeHint([min_width, me._itemHeight]);
return me;
},
@@ -1195,6 +1201,11 @@ DefaultStyle.widgets.list = {
me._bg.set("fill", me._style.getColor("bg_color"));
return me;
- }
+ },
+
+ _updateLayoutSizes: func(model) {
+ model.setLayoutMinimumSize([me._itemHeight * 2, me._itemHeight]);
+ model.setLayoutMaximumSize([model._MAX_SIZE, me._itemHeight]);
+ }
};
diff --git a/Nasal/canvas/gui/widgets/List.nas b/Nasal/canvas/gui/widgets/List.nas
index dce10988e..b1057811c 100644
--- a/Nasal/canvas/gui/widgets/List.nas
+++ b/Nasal/canvas/gui/widgets/List.nas
@@ -16,10 +16,8 @@ gui.widgets.ListItem = {
m._list = nil;
m._setView(style.createWidget(parent, "list-item", m._cfg));
+ m._view._updateLayoutSizes(m);
- m.setLayoutMinimumSize([48, 24]);
- m.setLayoutMaximumSize([m._MAX_SIZE, 24]);
-
m.setText(m._text);
m.setSelected(m._selected);
diff --git a/gui/styles/AmbianceClassic/style.xml b/gui/styles/AmbianceClassic/style.xml
index f4d4993f4..80243f04a 100644
--- a/gui/styles/AmbianceClassic/style.xml
+++ b/gui/styles/AmbianceClassic/style.xml
@@ -258,4 +258,20 @@
1
+
+
+ 5
+ 5
+
+
+
+ margin
+ 3.0
+
+
+ 14
+ 14
+ 24
+
+