Revision: 4793
http://sourceforge.net/p/vexi/code/4793
Author: clrg
Date: 2015-05-09 09:40:24 +0000 (Sat, 09 May 2015)
Log Message:
-----------
Widgets for integrated layout
- Button, CheckBox, RadioButton
- move to vexi.gui namespace
Modified Paths:
--------------
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_poke/testfeature.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/default.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/lib/button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_poke/poke/widgets/basic.t
Added Paths:
-----------
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/BasicWidgets.t
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/Icon.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Defaults.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Icon.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Clickable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Container.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/ContextMenuAgent.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Draggable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/FocusManager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Focusable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Polarized.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/PopupManager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Popupable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Repeater.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectContainer.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectGrouper.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectList.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Selectable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Subsurface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Surface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/TooltipAgent.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/TooltipManager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/theme/
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Bevel.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/CheckBox.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/RadioButton.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Settings.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Surface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Tooltip.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/lib/FocusBorder.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/conf/Settings.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/conf/Theme.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Bevel.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/ButtonGroup.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/CheckBox.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/RadioButton.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Surface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_poke/poke/gui/
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_poke/poke/gui/RadioButton.t
Removed Paths:
-------------
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/widgets_basic.t
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/icon.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/icon.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/clickable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/contextable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/draggable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/polarizable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/popupable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/popupmanager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/repeatable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectcontainer.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectgroup.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectlist.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/subsurface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/tooltipable.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/tooltipmanager.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/check.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/radio.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/bevel.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/check.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/lib/focusborder.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/radio.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/settings.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/surface.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/tooltip.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/conf/settings.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/conf/theme.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/bevel.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/button.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/check.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/radio.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/selectgroup.t
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/surface.t
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/BasicWidgets.t
(from rev 4791,
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/widgets_basic.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/BasicWidgets.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/BasicWidgets.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,101 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+ xmlns="vexi.gui">
+
+ static.name = "Widgets (Basic)";
+ static.category = "Widgets";
+
+ <ui:Box orient="vertical" padding="10">
+ <ui:Box vshrink="true">
+ <ui:Box />
+ <ButtonGroup id="radios" align="left" orient="vertical"
shrink="true">
+ <RadioButton id="r1" margin="10 5 0 5" text="white bg" />
+ <RadioButton id="r2" margin="10 5 0 5" text="red bg" />
+ <RadioButton id="r3" margin="10 5 0 5" text="green bg" />
+ <RadioButton id="r4" margin="10 5 0 5" text="blue bg" />
+ </ButtonGroup>
+ <ui:Box id="checks" align="left" orient="vertical" shrink="true">
+ <CheckBox id="c1" margin="10 5 0 5" text="disable white
button" />
+ <CheckBox id="c2" margin="10 5 0 5" text="disable red button"
/>
+ <CheckBox id="c3" margin="10 5 0 5" text="disable green
button" />
+ <CheckBox id="c4" margin="10 5 0 5" text="disable blue button"
/>
+ </ui:Box>
+ <ui:Box />
+ </ui:Box>
+ <ui:Box id="buttons" vshrink="true">
+ <ui:Box />
+ <Button id="b1" margin="10 5 0 5" text="cycle" shrink="false" />
+ <Button id="b2" margin="10 5 0 5" text="random" shrink="false" />
+ <Button id="b3" margin="10 5 0 5" text="reset" shrink="false" />
+ <ui:Box />
+ </ui:Box>
+ <Bevel id="bg" form="down" margin="10" />
+
+ // alternative to selectgroup
+ //$r2.group = $r1.group;
+ //$r3.group = $r1.group;
+ //$r4.group = $r1.group;
+
+ var noValidColors = false;
+
+ $bg.fill ++= function(v) {
+ cascade = v;
+ if (v == null) {
+ if ($r1.group.selected)
+ $r1.group.selected.selected = false;
+ $bg.text = noValidColors ? "No enabled colors to choose from!"
: "";
+ return;
+ }
+ $bg.text = "";
+ noValidColors = false;
+ if (v == "white") $r1.selected = true;
+ else if (v == "red") $r2.selected = true;
+ else if (v == "green") $r3.selected = true;
+ else if (v == "blue") $r4.selected = true;
+ }
+
+ $b1.action ++= function(v) {
+ cascade = v;
+ if ($radios.selected and $radios.selected.nextselect) {
+ $radios.selected.nextselect.selected = true;
+ } else {
+ $radios.selectFirst();
+ }
+ if ($radios.selected == null) {
+ noValidColors = true;
+ $bg.fill = null;
+ }
+ }
+
+ $b2.action ++= function(v) {
+ cascade = v;
+ var targets = [];
+ for (var i=0; 4 > i; i++) {
+ if ($radios[i].enabled)
+ targets[targets.length] = $radios[i];
+ }
+
+ if (targets.length > 0) {
+ var n = vexi.math.floor(targets.length * vexi.math.random());
+ targets[n].selected = true;
+ } else {
+ noValidColors = true;
+ $bg.fill = null;
+ }
+ }
+
+ $b3.action ++= function(v) { noValidColors = false; $bg.fill = null;
cascade = v; }
+
+ $c1.selected ++= function(v) { $r1.enabled = !v; cascade = v; }
+ $c2.selected ++= function(v) { $r2.enabled = !v; cascade = v; }
+ $c3.selected ++= function(v) { $r3.enabled = !v; cascade = v; }
+ $c4.selected ++= function(v) { $r4.enabled = !v; cascade = v; }
+
+ $r1.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#ffffff") $bg.fill = "white"; }
+ $r2.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#ff0000") $bg.fill = "red"; }
+ $r3.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#008000") $bg.fill = "green"; }
+ $r4.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#0000ff") $bg.fill = "blue"; }
+
+ </ui:Box>
+</vexi>
Deleted:
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/widgets_basic.t
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/widgets_basic.t
2015-05-09 09:29:30 UTC (rev 4792)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_main/org/vexi/demo/feature/widgets_basic.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -1,100 +0,0 @@
-<!-- Copyright 2007 - see COPYING for details [LGPL] -->
-
-<vexi xmlns:ui="vexi://ui" xmlns:lay="vexi.layout" xmlns="vexi.widget">
-
- static.name = "Widgets (Basic)";
- static.category = "Widgets";
-
- <lay:pad orient="vertical" padding="10">
- <ui:box vshrink="true">
- <ui:box />
- <selectgroup id="radios" align="left" orient="vertical"
shrink="true">
- <radio id="r1" margin="10 5 0 5" text="white bg" />
- <radio id="r2" margin="10 5 0 5" text="red bg" />
- <radio id="r3" margin="10 5 0 5" text="green bg" />
- <radio id="r4" margin="10 5 0 5" text="blue bg" />
- </selectgroup>
- <ui:box id="checks" align="left" orient="vertical" shrink="true">
- <check id="c1" margin="10 5 0 5" text="disable white button" />
- <check id="c2" margin="10 5 0 5" text="disable red button" />
- <check id="c3" margin="10 5 0 5" text="disable green button" />
- <check id="c4" margin="10 5 0 5" text="disable blue button" />
- </ui:box>
- <ui:box />
- </ui:box>
- <ui:box id="buttons" vshrink="true">
- <ui:box />
- <button id="b1" margin="10 5 0 5" text="cycle" shrink="false" />
- <button id="b2" margin="10 5 0 5" text="random" shrink="false" />
- <button id="b3" margin="10 5 0 5" text="reset" shrink="false" />
- <ui:box />
- </ui:box>
- <bevel id="bg" form="down" margin="10" />
-
- // alternative to selectgroup
- //$r2.group = $r1.group;
- //$r3.group = $r1.group;
- //$r4.group = $r1.group;
-
- var noValidColors = false;
-
- $bg.fill ++= function(v) {
- cascade = v;
- if (v == null) {
- if ($r1.group.selected)
- $r1.group.selected.selected = false;
- $bg.text = noValidColors ? "No enabled colors to choose from!"
: "";
- return;
- }
- $bg.text = "";
- noValidColors = false;
- if (v == "white") $r1.selected = true;
- else if (v == "red") $r2.selected = true;
- else if (v == "green") $r3.selected = true;
- else if (v == "blue") $r4.selected = true;
- }
-
- $b1.action ++= function(v) {
- cascade = v;
- if ($radios.selected and $radios.selected.nextselect) {
- $radios.selected.nextselect.selected = true;
- } else {
- $radios.selectFirst();
- }
- if ($radios.selected == null) {
- noValidColors = true;
- $bg.fill = null;
- }
- }
-
- $b2.action ++= function(v) {
- cascade = v;
- var targets = [];
- for (var i=0; 4 > i; i++) {
- if ($radios[i].enabled)
- targets[targets.length] = $radios[i];
- }
-
- if (targets.length > 0) {
- var n = vexi.math.floor(targets.length * vexi.math.random());
- targets[n].selected = true;
- } else {
- noValidColors = true;
- $bg.fill = null;
- }
- }
-
- $b3.action ++= function(v) { noValidColors = false; $bg.fill = null;
cascade = v; }
-
- $c1.selected ++= function(v) { $r1.enabled = !v; cascade = v; }
- $c2.selected ++= function(v) { $r2.enabled = !v; cascade = v; }
- $c3.selected ++= function(v) { $r3.enabled = !v; cascade = v; }
- $c4.selected ++= function(v) { $r4.enabled = !v; cascade = v; }
-
- $r1.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#ffffff") $bg.fill = "white"; }
- $r2.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#ff0000") $bg.fill = "red"; }
- $r3.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#008000") $bg.fill = "green"; }
- $r4.selected ++= function(v) { cascade = v; if (v and $bg.fill !=
"#0000ff") $bg.fill = "blue"; }
-
- </lay:pad>
-</vexi>
Modified:
branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_poke/testfeature.t
===================================================================
--- branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_poke/testfeature.t
2015-05-09 09:29:30 UTC (rev 4792)
+++ branches/vexi3_integrated_layout/org.vexi-vexi.demo/src_poke/testfeature.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -1,12 +1,12 @@
<!-- public domain -->
-<vexi xmlns:ui="vexi://ui" xmlns="vexi.widget" xmlns:f="org.vexi.demo.feature">
- <surface />
+<vexi xmlns:ui="vexi://ui" xmlns="vexi.gui" xmlns:f="org.vexi.demo.feature">
+ <Surface />
<ui:box>
// very simple template to open a feature in a frame
var feature = vexi.params["feature"];
- if (feature==null) feature = "grid";
+ if (feature==null) feature = "BasicWidgets";
thisbox[0] = f[feature](vexi.box);
// or comment out the above and uncomment this
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/Icon.t
(from rev 4791,
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/icon.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/Icon.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/Icon.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,5 @@
+<!-- provides the location to look for icons -->
+<vexi xmlns:ui="vexi://ui">
+ <ui:box />
+ static.iconpath = [vexi..org.vexi.crystal];
+</vexi>
\ No newline at end of file
Deleted:
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/icon.t
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/icon.t
2015-05-09 09:29:30 UTC (rev 4792)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.icons/src_main/vexi/conf/icon.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -1,5 +0,0 @@
-<!-- provides the location to look for icons -->
-<vexi xmlns:ui="vexi://ui">
- <ui:box />
- static.iconpath = [vexi..org.vexi.crystal];
-</vexi>
\ No newline at end of file
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/button.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,7 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+ <Clickable />
+ <Focusable />
+ <TooltipAgent />
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/check.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,29 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <note>
+ At some point this should be using selectable (which
+ should also implement the necessary action/value traps)
+ </note>
+ </meta:doc>
+
+ <Clickable />
+ <Focusable />
+ <TooltipAgent />
+ <ui:Box>
+
+ thisbox.selected = false;
+
+ thisbox.action ++= static.actionWrite;
+ thisbox.value ++= static.valueWrite;
+ thisbox.value ++= static.valueRead;
+
+ </ui:Box>
+
+ static.actionWrite = function(v) { trapee.selected = !trapee.selected;
cascade = v; }
+ static.valueWrite = function(v) { trapee.selected = v == true; return; }
+ static.valueRead = function() { return trapee.selected == true; }
+
+</vexi>
Added:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Defaults.t
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Defaults.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Defaults.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,15 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="vexi://ui">
+ <Box>
+ {
+ const s = thisbox.v_defaultSettings;
+ if (s!=null) {
+ // initialize properties
+ for (var p,v in s) {
+ thisbox[p] = v;
+ }
+ }
+ }
+ </Box>
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/radio.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,8 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+ <Clickable />
+ <Selectable />
+ <Focusable />
+ <TooltipAgent />
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Icon.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/icon.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Icon.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Icon.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,110 @@
+<!-- Copyright 2014 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+ xmlns:icon="vexi.icon">
+
+
+ <ui:box shrink="true">
+ <ui:box id="size" align="bottomright" layout="layer">
+ <ui:box id="image" shrink="true" />
+ <ui:box id="emblem" shrink="true" />
+ </ui:box>
+
+ thisbox.emblem ++= static.emblemWrite;
+ thisbox.image ++= static.imageWrite;
+ thisbox.icon ++= static.iconWrite;
+ thisbox.size ++= static.sizeWrite;
+
+ </ui:box>
+
+ /** set the emblem, a 1/4 size image in the bottom right corner */
+ static.emblemWrite = function(v) {
+ cascade = v;
+ if (!trapee.size) {
+ return;
+ }
+ trapee[0][1].fill = v ? static.getIcon("icon"+(trapee.size/2), v) :
null;
+ }
+
+ /** sets the icon's image to the specified resource */
+ static.imageWrite = function(v) {
+ cascade = v;
+ trapee[0][0].fill = v;
+ }
+
+ /** sets the icon's image to an existing icon */
+ static.iconWrite = function(v) {
+ cascade = v;
+ if (!trapee.size) {
+ return;
+ }
+ trapee[0][0].fill = v ? static.getIcon("icon"+trapee.size, v) : null;
+ }
+
+ /** sets the size, in pixels, of this icon */
+ static.sizeWrite = function(v) {
+ cascade = v;
+ var i = trapee[0];
+ i.width = v;
+ i.height = v;
+ if (trapee.icon) {
+ trapee.icon = trapee.icon;
+ }
+ if (trapee.image) {
+ trapee.image = trapee.image;
+ }
+ }
+
+ const icons = {};
+
+ static.iconpath ++= function(v){
+ cascade = v;
+ // done like this because we cannot test easily if an icon exists or
not (no method for this, and threading issues
+ // which don't exist for listing)
+ for(var i,subkey in ["icon8", "icon16", "icon32"]){
+ const submap = icons[subkey] = {};
+ for(var j,l in static.iconpath){
+ const lsub = l[subkey];
+ for(var k in lsub){
+ var d = k.indexOf('.');
+ if (d==0) {
+ // skips hidden dirs e.g. .svn
+ continue;
+ }
+ if (d>=1) {
+ // image files should have an extension e.g.
image.png
+ k = k.substring(0, d);
+ }
+ submap[k] = lsub[k];
+ }
+ }
+ }
+ };
+
+
+
+ const list = function(subdir){
+ var r = (keysof icons[subdir]).toArray();
+ r.sort();
+ return r;
+ };
+
+ const listed = {};
+
+ static.getIcon = function(subdir, name){
+ const key = subdir+"."+name;
+ var r = icons[subdir][name];
+ if(!r){
+
+ var msg = "[WARNING] icon not found: "+subdir+"/"+name;
+ vexi.log.warn(new vexi.js.Exception(msg));
+ if(!listed[subdir]){
+ listed[subdir] = true;
+ vexi.log.warn(list(subdir).join("\n "));
+ }
+ r = icon[subdir]["blank"];
+ }
+ return r;
+ };
+
+</vexi>
Deleted:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/icon.t
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/icon.t
2015-05-09 09:29:30 UTC (rev 4792)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/icon.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -1,110 +0,0 @@
-<!-- Copyright 2014 - see COPYING for details [LGPL] -->
-
-<vexi xmlns:ui="vexi://ui"
- xmlns:icon="vexi.icon">
-
-
- <ui:box shrink="true">
- <ui:box id="size" align="bottomright" layout="layer">
- <ui:box id="image" shrink="true" />
- <ui:box id="emblem" shrink="true" />
- </ui:box>
-
- thisbox.emblem ++= static.emblemWrite;
- thisbox.image ++= static.imageWrite;
- thisbox.icon ++= static.iconWrite;
- thisbox.size ++= static.sizeWrite;
-
- </ui:box>
-
- /** set the emblem, a 1/4 size image in the bottom right corner */
- static.emblemWrite = function(v) {
- cascade = v;
- if (!trapee.size) {
- return;
- }
- trapee[0][1].fill = v ? static.getIcon("icon"+(trapee.size/2), v) :
null;
- }
-
- /** sets the icon's image to the specified resource */
- static.imageWrite = function(v) {
- cascade = v;
- trapee[0][0].fill = v;
- }
-
- /** sets the icon's image to an existing icon */
- static.iconWrite = function(v) {
- cascade = v;
- if (!trapee.size) {
- return;
- }
- trapee[0][0].fill = v ? static.getIcon("icon"+trapee.size, v) : null;
- }
-
- /** sets the size, in pixels, of this icon */
- static.sizeWrite = function(v) {
- cascade = v;
- var i = trapee[0];
- i.width = v;
- i.height = v;
- if (trapee.icon) {
- trapee.icon = trapee.icon;
- }
- if (trapee.image) {
- trapee.image = trapee.image;
- }
- }
-
- const icons = {};
-
- static.iconpath ++= function(v){
- cascade = v;
- // done like this because we cannot test easily if an icon exists or
not (no method for this, and threading issues
- // which don't exist for listing)
- for(var i,subkey in ["icon8", "icon16", "icon32"]){
- const submap = icons[subkey] = {};
- for(var j,l in static.iconpath){
- const lsub = l[subkey];
- for(var k in lsub){
- var d = k.indexOf('.');
- if (d==0) {
- // skips hidden dirs e.g. .svn
- continue;
- }
- if (d>=1) {
- // image files should have an extension e.g.
image.png
- k = k.substring(0, d);
- }
- submap[k] = lsub[k];
- }
- }
- }
- };
-
-
-
- const list = function(subdir){
- var r = (keysof icons[subdir]).toArray();
- r.sort();
- return r;
- };
-
- const listed = {};
-
- static.getIcon = function(subdir, name){
- const key = subdir+"."+name;
- var r = icons[subdir][name];
- if(!r){
-
- var msg = "[WARNING] icon not found: "+subdir+"/"+name;
- vexi.log.warn(new vexi.js.Exception(msg));
- if(!listed[subdir]){
- listed[subdir] = true;
- vexi.log.warn(list(subdir).join("\n "));
- }
- r = icon[subdir]["blank"];
- }
- return r;
- };
-
-</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Clickable.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/clickable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Clickable.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Clickable.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,246 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:meta="vexi://meta"
+ xmlns="org.vexi.lib.role">
+
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ Implements standard clickable widget behaviour by providing
+ an interface to the state to make implementation of visual
+ feedback easy as well as behaving as the user expects.
+ </desc>
+ <notes>
+ We trap only on Press1 instead of _Press1 because it is not
+ unlikely that we may need to prevent press events reaching
+ a clickable widget e.g. it is overlaid by another widget.
+
+ We trap on surface._Release1 because we always want to
+ reset a clickable widget on release.
+ </notes>
+ <usage>
+ By preapplying clickable, a widget gains access to several
+ state properties that are used as triggers i.e. can be
+ trapped to know when the clickable widget changes state:
+
+ * hover - When a mouse is over a widget without the left
+ mouse button having been depressed first
+
+ * normal - When a widget has no interaction with the mouse
+ or keyboard
+
+ * active - When the left mouse button is depressed or the
+ widget is focused and spacebar depressed
+
+ * action - This is put to when a clickable widget is
+ successfully clicked upon
+
+ As the only value put to these state properties is 'true',
+ their actual value is meaningless; they are just triggers.
+
+ Clickable widgets recognise the following state property:
+
+ * enabled - Put 'true' (default) to enable the widget and
+ allow user interaction, 'false' to disable it
+ </usage>
+ </meta:doc>
+
+ <Repeater>
+
+ // template properties
+ thisbox.action; // action trigger
+ thisbox.enabled; // self explanatory
+ thisbox.focused; // focusable integration
+ thisbox.active; // active state (mouse.inside and primed)
+ thisbox.hover; // hover state (mouse.inside and !primed)
+ thisbox.normal; // normal state (!mouse.inside)
+ thisbox.primed; // track activation irrespective of
mouse.inside
+ thisbox.repeats = false; // if a repeating action is desired
+
+ // initialize enabled state (from preapply)
+ if (enabled === null)
+ enabled = true;
+ if (enabled) {
+ Enter ++= static.enterEvent;
+ Leave ++= static.leaveEvent;
+ }
+
+ // assign trap functions
+ enabled ++= static.enabledWrite;
+ focused ++= static.focusedWrite;
+ interval ++= static.intervalWrite;
+ primed ++= static.primedWrite;
+ KeyPressed ++= static.keypressEvent;
+ KeyReleased ++= static.keyreleaseEvent;
+ Press1 ++= static.pressEvent;
+ surface ++= static.initNormal;
+
+ </Repeater>
+
+ static.defaultinterval = 100;
+ static.initialinterval = 500;
+
+ /** initialise as normal state */
+ static.initNormal = function(v) {
+ cascade = v;
+ trapee.normal = true;
+ trapee.surface --= callee;
+ }
+
+ /** enabled write trap */
+ static.enabledWrite = function(v) {
+ var e = trapee.enabled;
+ cascade = v;
+ if (e != trapee.enabled) {
+ if (trapee.enabled) {
+ trapee.Enter ++= static.enterEvent;
+ trapee.Leave ++= static.leaveEvent;
+ } else {
+ trapee.Enter --= static.enterEvent;
+ trapee.Leave --= static.leaveEvent;
+ // deprime us when disabled
+ trapee.primed = false;
+ }
+ // sets visible state
+ trapee.normal = true;
+ }
+ }
+
+ /** focused write trap */
+ static.focusedWrite = function(v) {
+ var f = trapee.focused;
+ cascade = v;
+ if (f and !trapee.focused and trapee.primed) {
+ // unprime if defocused
+ trapee.primed = false;
+ }
+ }
+
+ /** returns the appropriate interval for repeating clickable to use */
+ static.intervalWrite = function() {
+ return (trapee.counter==0)
+ ? (trapee.initialinterval
+ ? trapee.initialinterval
+ : static.initialinterval)
+ : (cascade
+ ? cascade
+ : trapee.defaultinterval);
+ }
+
+ /** primed write trap */
+ static.primedWrite = function(v) {
+ // behaviour if widget is enabled
+ if (trapee.enabled) {
+ // determine physical state and activate trigger
+ if (v) trapee.active = true;
+ else {
+ var m = trapee.mouse;
+ if (m and m.inside) {
+ trapee.hover = true;
+ } else {
+ trapee.normal = true;
+ }
+ }
+ // set repeat state if necessary
+ if (trapee.repeats) {
+ trapee.repeat = v;
+ }
+ cascade = v;
+ }
+ // do nothing when not enabled
+ else cascade = false;
+ }
+
+ /** KeyPressed write trap */
+ static.keypressEvent = function(v) {
+ switch (v) {
+ case "enter": case " ":
+ trapee.primed = true;
+ break;
+ case "escape":
+ trapee.primed = false;
+ break;
+ default:
+ cascade = v;
+ }
+ }
+
+ /** KeyReleased write trap */
+ static.keyreleaseEvent = function(v) {
+ if ((v == "enter" or v == " ") and trapee.primed and trapee.enabled) {
+ trapee.action = true;
+ trapee.primed = false;
+ }
+ else cascade = v;
+ }
+
+ /** Enter write trap */
+ static.enterEvent = function(v) {
+ if (trapee.enabled) {
+ if (trapee.primed) {
+ trapee.active = true;
+ if (trapee.repeats) {
+ trapee.repeat = true;
+ }
+ } else {
+ trapee.hover = true;
+ }
+ }
+ cascade = v;
+ }
+
+ /** Leave write trap */
+ static.leaveEvent = function(v) {
+ if (trapee.enabled) {
+ trapee.normal = true;
+ if (trapee.repeats and trapee.primed) {
+ trapee.repeat = false;
+ }
+ }
+ cascade = v;
+ }
+
+ /** Press1 write trap */
+ static.pressEvent = function(v) {
+ if (trapee.enabled) {
+ // set primed state; ready to fire action on release
+ trapee.primed = true;
+ // apply release trap to surface otherwise a release outside
+ // of this clickable would leave it in an active state
+ var s = trapee.surface;
+ var targ = s and s.event ? s.event : trapee;
+ var tbox = trapee;
+ targ._Release1 ++= function(v) {
+ try {
+ // important; allows focusmanager to process focused
+ // before firing an action on the clickable
+ cascade = v;
+ // check clickable conditions for
+ // firing either repeat or action
+ if (tbox.enabled) {
+ // primed e.g. button down
+ if (tbox.primed) {
+ // fire action or stop repeat
+ if (tbox.mouse?.inside) {
+ if (tbox.repeats) {
+ // note repeat fires action
+ tbox.repeat = false;
+ } else {
+ tbox.action = true;
+ }
+ }
+ }
+ }
+ } finally {
+ // clean up trap
+ targ._Release1 --= callee;
+ // deprime widget - this handleds repeat
+ // and other button deactivation tasks
+ tbox.primed = false;
+ }
+ }
+ }
+ cascade = v;
+ }
+
+</vexi>
Added:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Container.t
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Container.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Container.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,21 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns:util="vexi.util">
+ <meta:doc>
+ <name>Container</name>
+ <desc>Signals container's readiness</desc>
+ <usage>
+ Post-apply container to your full constructed widget
+ </usage>
+ </meta:doc>
+
+ <ui:box>
+
+ if (v_content == null) v_content = thisbox;
+
+ // signal readiness - allows widgets to finalize
+ // container targets before assigning redirects
+ thisbox.v_container = true;
+
+ </ui:box>
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/ContextMenuAgent.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/contextable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/ContextMenuAgent.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/ContextMenuAgent.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,36 @@
+<!-- Copyright 2012 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+ xmlns="vexi.widget">
+
+ <ui:box>
+
+ thisbox.Press2 ++= static.popupContext;
+
+ </ui:box>
+
+ static.popupContext = function(p) {
+ cascade = p;
+ var actions = trapee.contextActions;
+ if (actions != null and actions.length>1) {
+ var model = trapee.surface.popup;
+ var popup = new .menu();
+ var close = function(v) { cascade = v; model.pop(popup, false); }
+ popup.popdownOnExternalEvent = true;
+ for (var i,item in actions) {
+ item.action ++= close;
+ popup.add(item);
+ }
+ popup.v_popbox.visible ++= function(v) {
+ cascade = v;
+ if (!v) model.delPopBox(popup);
+ }
+ var m = trapee.surface.frame.mouse;
+ popup.v_popbox.surface_x = m.x;
+ popup.v_popbox.surface_y = m.y;
+ model.addPopBox(popup);
+ model.pop(popup, true);
+ }
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Draggable.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/draggable.t)
===================================================================
(Binary files differ)
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/FocusManager.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/FocusManager.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/FocusManager.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,250 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <author>David Crawshaw</author>
+ <desc>Manages the focusable widgets on a surface</desc>
+ <usage>
+ Directly apply to a surface widget (done automatically by
+ using FIXME: vexi.widget.frame) and when directly applying
+ vexi.theme.focusable (usually preapplied by widgets) to a
+ template, it should then be automatically registered as
+ focusable with the surface.
+ </usage>
+ <notes>For further documentation, see vexi.theme.surface</notes>
+ </meta:doc>
+
+ <ui:box>
+
+ // the current focus for this surface
+ var focus = null;
+ var model = {};
+ var surfaceFocused = false;
+
+ // the focus list for this surface
+ const fvector = new .util.vector();
+
+ // access to the model and current focus
+ model.focus ++= .util.common..readOnly;
+ model.current ++= function() { return focus; }
+ surface.focus ++= function() { return model; }
+ surface.focus ++= .util.common..readOnly;
+
+ /** defocus when frame/window is closed */
+ surface.frame.Close ++= function(v) {
+ cascade = v;
+ // REMARK: this seems necessary as frame.Focused
+ // is not put to when a frame or window is closed
+ if (focus!=null) {
+ focus.focused = false;
+ }
+ }
+
+ /** return current frame Focused state */
+ surface.frame.Focused ++= function() { return surfaceFocused; }
+
+ /** (un)focus the focused widget according to root.Focused */
+ surface.frame.Focused ++= function(v) {
+ cascade = v;
+ surfaceFocused = v;
+ if (focus) {
+ if (v) {
+ focus.focused = true;
+ } else {
+ focus.focused = false;
+ }
+ }
+ }
+
+ var defocus;
+
+ /** set or unset a focused widget */
+ model.setFocus = function(v, f) {
+ if (f and fvector.contains(v)) {
+ // valid request to focus
+ if (focus != v) {
+ defocus = focus;
+ if (defocus) {
+ try { defocus.focused = false; }
+ finally { defocus = null; }
+ }
+ // focus
+ focus = v;
+ model.current = v;
+ }
+ return true;
+ } else if (!f and focus == v) {
+ // request to unfocus
+ if (defocus == v) {
+ // already in setFocus; defocus as
+ // part of focusing another widget
+ return false;
+ }
+ if (surfaceFocused) {
+ // defocus
+ focus = null;
+ model.current = null;
+ return false;
+ }
+ } else {
+ // nothing to do
+ return false;
+ }
+ }
+
+ /** add a focus to the focus vector, optionally after w */
+ model.addFocus = function(v, w) {
+ // make sure we're not already in the focus list
+ model.dropFocus(v);
+
+ if (w and fvector.contains(w)) {
+ return fvector.insert(v, w);
+ }
+ return fvector.push(v);
+ }
+
+ /** drop a focus from the focus vector for this surface */
+ model.dropFocus = function(v) {
+ if (fvector.contains(v)) {
+ // remove v from surface's focus model
+ if (focus == v) {
+ var nf = model.nextFocus(v);
+ if (nf != null and nf != v) {
+ nf.focused = true;
+ } else {
+ v.focused = false;
+ focus = null;
+ }
+ }
+ return fvector.remove(v);
+ } else {
+ // not a member of this surface's focus model
+ return false;
+ }
+ }
+
+ /** return the next-in-line for focus after v */
+ model.nextFocus = function(v) {
+ var nf = fvector.after(v);
+ if (!nf) {
+ // wrap around
+ nf = fvector.first;
+ }
+ while (nf != v) {
+ if (nf.focusable) {
+ return nf;
+ }
+ nf = fvector.after(nf);
+ if (!nf) {
+ // wrap around
+ nf = fvector.first;
+ }
+ }
+ return v.focusable ? v : null;
+ }
+
+ /** return the previous-in-line for focus after v */
+ model.prevFocus = function(v) {
+ var pf = fvector.before(v);
+ if (!pf) {
+ // wrap around
+ pf = fvector.last;
+ }
+ while (pf != v) {
+ if (pf.focusable) {
+ return pf;
+ }
+ pf = fvector.before(pf);
+ if (!pf) {
+ // wrap around
+ pf = fvector.last;
+ }
+ }
+ return v.focusable ? v : null;
+ }
+
+
+ model.lastFocus ++= function() { return fvector.last; };
+
+
+ /** give the requested widget the focus */
+ surface.event._Press1 ++= function(v) {
+ // clear focusrequest as it gets set by manual focused puts
+ model.focusrequest = null;
+ // pass event to rest of ui
+ cascade = v;
+ }
+
+ /** give the requested widget the focus */
+ surface.event._Release1 ++= function(v) {
+ // if a request for focus has been made, honor it
+ if (model.focusrequest) {
+ // focus but avoid repeat focusing
+ if (!model.focusrequest.focused) {
+ model.focusrequest.focused = true;
+ }
+ model.focusrequest = null;
+ }
+ // et fini
+ cascade = v;
+ }
+
+ //////// Key Event Handling ///////////////////////////////////
+
+ /** pass key-press events to focused child */
+ var surfaceKeyPress = function(v) {
+ model.focusModelKeyPressed(v);
+ return;
+ }
+
+ surface.event._KeyPressed ++= surfaceKeyPress;
+
+ /** pass key-release events to focused child */
+ var surfaceKeyRelease = function(v) {
+ model.focusModelKeyReleased(v);
+ return;
+ }
+
+ surface.event._KeyReleased ++= surfaceKeyRelease;
+
+ /** focus model keypress event */
+ model.focusModelKeyPressed = function(v) {
+ if (focus and focus.grabKeyList and focus.grabKeyList[v]) {
+ // the focused widget wishes to intercept special keys
+ focus.KeyPressed = v;
+
+ } else if (v.charCodeAt(0) == 65535) {
+ // ignore capslock
+ //break;
+
+ } else if (v=="tab") {
+ // on tab, move forwards through focus list
+ var f = focus ? focus.nextfocus :
model.nextFocus(fvector.last);
+ if (f) {
+ f.focused = true;
+ }
+
+ } else if (v=="TAB") {
+ // on shift-tab, move backwards through focus list
+ var f = focus ? focus.prevfocus :
model.prevFocus(fvector.first);
+ if (f) {
+ f.focused = true;
+ }
+
+ } else if (focus) {
+ // pass keypress onto focused widget
+ focus.KeyPressed = v;
+ }
+ }
+
+ /** focus model keyrelease event */
+ model.focusModelKeyReleased = function(v) {
+ if (focus and ((focus.grabKeyList and focus.grabKeyList[v])
+ or v!="tab" or v!="TAB" or v.charCodeAt(0)!=65535)) {
+ focus.KeyReleased = v;
+ }
+ }
+
+ </ui:box>
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Focusable.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Focusable.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Focusable.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,138 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ Handles widget focusing, automating keyboard navigation, when
+ combined with a focusmanager-enabled surface
+ </desc>
+ <details>
+ The following state properties are meaningful:
+
+ * enabled - Whether this widget is 'on'; only an enabled
+ (true) widget may be focused
+
+ * focusable - If 'true' widget desires focus, otherwise it
+ (true) rejects focus
+
+ * focused - Set 'true' when the widget is focused and
+ (false) conversely set to 'false' when defocused
+
+ * nextfocus - The next available focusable widget
+ (null)
+
+ * prevfocus - The previous available focuslable widget
+ (null)
+
+ All of these properties may be manually put to in order to
+ arbitrarily update their focused (sic) state.
+ </details>
+ </meta:doc>
+
+ <ui:Box>
+
+ if (thisbox.enabled==null) {
+ enabled = true;
+ }
+
+ thisbox.focusable = true; // whether a focusable may be focused
+ thisbox.focused; // whether a focusable is focused
+ thisbox.nextfocus; // read for the focus after thisbox on the
surface
+ thisbox.prevfocus; // read for the focus before thisbox on the
surface
+ thisbox.v_focusmodel;
+
+ // assign checkFocus traps
+ display ++= static.checkFocus; // defocus when hidden
+ enabled ++= static.checkFocus; // defocus when disabled
+ focusable ++= static.checkFocus; // defocus if made unfocusable
+ visible ++= static.checkFocus; // defocus if no longer visible
+
+ // assign trap functions
+ focusable ++= static.focusableRead;
+ focused ++= static.focusedWrite;
+ nextfocus ++= static.nextfocusRead;
+ prevfocus ++= static.prevfocusRead;
+ surface ++= static.surfaceWrite;
+ Press1 ++= static.pressWrite;
+
+ </ui:Box>
+
+ /** private function to assign to traps */
+ static.checkFocus = function(v) {
+ if (!v and trapee.focused) {
+ trapee.focused = false;
+ }
+ cascade = v;
+ }
+
+ /** read trap to return focusable state */
+ static.focusableRead = function() {
+ return trapee.visible and trapee.enabled and cascade;
+ }
+
+ /** write trap to set focused state */
+ static.focusedWrite = function(v) {
+ // REMARK: the following sequence could be more compact
+ // but it is easier to follow in the more explicit form
+ const model = trapee.surface?.focus;
+ if (model==null) {
+ cascade = false;
+ } else if (v) {
+ if (trapee.focusable) {
+ model.focusrequest = trapee;
+ cascade = model.setFocus(trapee, true);
+ }
+ } else {
+ if (model.current == trapee) {
+ cascade = model.setFocus(trapee, false);
+ } else {
+ cascade = false;
+ }
+ }
+ }
+
+ /** read trap to return the focus after trapee on the surface */
+ static.nextfocusRead = function() {
+ var s = trapee.surface;
+ if (s and s.focus) {
+ return s.focus.nextFocus(trapee);
+ }
+ return null;
+ }
+
+ /** read trap to return the focus before trapee on the surface */
+ static.prevfocusRead = function() {
+ var s = trapee.surface;
+ if (s and s.focus) {
+ return s.focus.prevFocus(trapee);
+ }
+ return null;
+ }
+
+ /** write trap to handle surface change */
+ static.surfaceWrite = function(v) {
+ var s = trapee.surface;
+ if (s and s.focus) {
+ // drop from current surface
+ s.focus.dropFocus(trapee);
+ }
+ if (v and v.focus) {
+ // add to new surface
+ v.focus.addFocus(trapee);
+ }
+ cascade = v;
+ }
+
+ /** write trap to focus on Press1 */
+ static.pressWrite = function(v) {
+ cascade = v;
+ if (trapee.focusable) {
+ var s = trapee.surface;
+ if (s and s.focus and !s.focus.focusrequest) {
+ s.focus.focusrequest = trapee;
+ }
+ }
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Polarized.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/polarizable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Polarized.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Polarized.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,77 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ </meta:doc>
+
+ <ui:box>
+
+ thisbox.contentdim = "contentwidth";
+ thisbox.dim = "width";
+ thisbox.mindim = "minwidth";
+ thisbox.maxdim = "maxwidth";
+ thisbox.orient = "horizontal";
+ thisbox.mousewheel = "HScroll";
+ thisbox.pos = "x";
+ thisbox.shr = "hshrink";
+ thisbox.flip = static.flip;
+ thisbox.horizontal = true;
+ thisbox.orient ++= static.orientWrite;
+
+ </ui:box>
+
+ static.flip = function(f) {
+ switch (f) {
+ case "width": return "height";
+ case "height": return "width";
+ case "x": return "y";
+ case "y": return "x";
+ case "contentwidth": return "contentheight";
+ case "contentheight": return "contentwidth";
+ case "maxwidth": return "maxheight";
+ case "maxheight": return "maxwidth";
+ case "minwidth": return "minheight";
+ case "minheight": return "minwidth";
+ case "horizontal": return "vertical";
+ case "vertical": return "horizontal";
+ case "hshrink": return "vshrink";
+ case "vshrink": return "hshrink";
+ case "HScroll": return "VScroll";
+ case "VScroll": return "HScroll";
+ default: return null;
+ }
+ }
+
+ static.orientWrite = function(v) {
+ var t = trapee;
+ var c = trapee.v_container ? null : trapee.v_content;
+ if (c) {
+ if (v==c.orient) return;
+ c.orient = v;
+ } else {
+ if (v==trapee.orient) return;
+ cascade = v;
+ }
+ if (v == "horizontal") {
+ t.contentdim = "contentwidth";
+ t.dim = "width";
+ t.maxdim = "maxwidth";
+ t.mindim = "minwidth";
+ t.pos = "x";
+ t.shr = "hshrink";
+ t.mousewheel = "HScroll";
+ t.horizontal = true;
+ } else {
+ t.contentdim = "contentheight";
+ t.dim = "height";
+ t.maxdim = "maxheight";
+ t.mindim = "minheight";
+ t.pos = "y";
+ t.shr = "vshrink";
+ t.mousewheel = "VScroll";
+ t.horizontal = false;
+ }
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/PopupManager.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/popupmanager.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/PopupManager.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/PopupManager.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,318 @@
+<!-- Copyright 2012 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+ xmlns:meta="vexi://meta"
+ xmlns="vexi">
+
+ <ui:box redirect=":$content" layout="layer">
+ <ui:box id="content" />
+ <ui:box id="container" align="topleft" display="false" layout="place"
/>
+
+ .util.redirect..addRedirect(thisbox, $content, "align", "layout",
"orient");
+
+ var model = {};
+ surface.popup ++= function() { return model; }
+ surface.popup ++= .util.common..readOnly;
+
+ var interval = 50; // sleep interval for pop thread
+ var popcount = 0; // number of active popups
+ var popforegs = {}; // popgroup foregrounds
+ var popbygroup = {}; // track current popup by group
+ var poptip; // pop thread in progress marker
+ var requests = {}; // pop request array
+ var reqtimes = {}; // pop request times
+
+ /** implement event blocking when a popup is displayed to
+ * stop mouse events being passed to widgets underneath */
+ var eventBlock = function(v) { return; }
+
+ var pressWrite = function(v) {
+ cascade = v;
+ for (var k,p in popbygroup) {
+ // keys may be invalidated by popdowns occuring
+ // as a consequence of other group popdowns
+ if (p==null) {
+ continue;
+ }
+ // take into account whether interacting with the
+ // original popupable as often they are designed
+ // to toggle popped state; this would interfere
+ var m = p.v_popmaster;
+ if (m?.popdownOnExternalEvent and !(m?.mouse?.inside)) {
+ m.popdown = true;
+ // popmaster may be off-screen
+ if (!m.surface) model.pop(m, false);
+ }
+ }
+ }
+
+ var setupHoldingBox = function(b) {
+ // block Enter/Leave underneath popup
+ b.Move ++= eventBlock;
+ b.Press1 ++= eventBlock;
+ b.Press2 ++= eventBlock;
+ b.Press3 ++= eventBlock;
+ b.Click1 ++= eventBlock;
+ b.Click2 ++= eventBlock;
+ b.Click3 ++= eventBlock;
+ b.DoubleClick1 ++= eventBlock;
+ b.DoubleClick2 ++= eventBlock;
+ b.DoubleClick3 ++= eventBlock;
+ }
+
+ $container.Press1 ++= pressWrite;
+ $container.Press2 ++= pressWrite;
+ $container.Press3 ++= pressWrite;
+
+ /** used to track surface_x/y changes */
+ var syncXPos = function(v) { cascade = v;
popforegs[trapee.popgroup?:"default"].x = v; }
+ var syncYPos = function(v) { cascade = v;
popforegs[trapee.popgroup?:"default"].y = v; }
+ var updateXPos = function(v) {
+ cascade = v;
+ var m = trapee.v_popmaster;
+ var s = surface;
+ var sW = m.surfaceWidth;
+ if (s and sW) {
+ var d = s.frame.distanceto(m);
+ sW(d.x, s.frame.width);
+ }
+ }
+ var updateYPos = function(v) {
+ cascade = v;
+ var m = trapee.v_popmaster;
+ var s = surface;
+ var sH = m.surfaceHeight;
+ if (s and sH) {
+ var d = s.frame.distanceto(m);
+ sH(d.y, s.frame.height);
+ }
+ }
+
+ /** private function to pop down popupable 'v' */
+ var popDown = function(v) {
+ var p = v.v_popbox;
+ // ignore non-visible requests
+ if (p.visible) {
+ p.display = false;
+ }
+ }
+
+ var popboxDisplay = function(v) {
+ cascade = v;
+ if (v) {
+ return;
+ }
+ var p = trapee;
+ // drop active popup traps
+ p.surface_x --= syncXPos;
+ p.surface_y --= syncYPos;
+ p.width --= updateXPos;
+ p.height --= updateYPos;
+ p.visible --= callee;
+ // handle container display
+ popcount--;
+ $container.display = popcount>0;
+ // use default group if none is specified
+ var g = p.popgroup ? p.popgroup : "default";
+ if (popforegs[g]) {
+ popforegs[g].display = false;
+ }
+ if (popbygroup[g]) {
+ (keysof(popbygroup)).remove(g);
+ }
+ }
+
+ /** private function to pop up box 'v' */
+ var popUp = function(v) {
+ var p = v.v_popbox;
+ // p.v_popmaster == v;
+ // use default group if none is specified
+ var g = p.popgroup ? p.popgroup : "default";
+ // establish popup group
+ var fg = popforegs[g];
+ // establish 'v' as active popup for group
+ if (popbygroup[g]) {
+ // undisplay previous popup in group
+ popbygroup[g].display = false;
+ }
+ popbygroup[g] = p;
+ // call surface update functions
+ var s = surface;
+ var sW = v.surfaceWidth;
+ var sH = v.surfaceHeight;
+ if (s and (sW or sH)) {
+ var d = s.frame.distanceto(v);
+ if (sW) {
+ sW(d.x, s.frame.width);
+ }
+ if (sH) {
+ sH(d.y, s.frame.height);
+ }
+ }
+ // display and position popup
+ fg.display = true;
+ fg.x = p.surface_x;
+ fg.y = p.surface_y;
+ p.display = true;
+ // assign active popup traps
+ p.surface_x ++= syncXPos;
+ p.surface_y ++= syncYPos;
+ p.width ++= updateXPos;
+ p.height ++= updateYPos;
+ p.visible ++= popboxDisplay;
+ // handle container display
+ popcount++;
+ $container.display = true;
+ }
+
+ /** private function to handle timed pop requests */
+ var popRequest = function(v, up, time) {
+ if (time==0 or 2>=arguments.length) {
+ // no delay stated, perform immediate popup/popdown
+ if (requests[v]) {
+ // drop existing request
+ (keysof(reqtimes)).remove(v);
+ (keysof(requests)).remove(v);
+ }
+ up ? popUp(v) : popDown(v);
+ return;
+ }
+
+ if (requests[v]) {
+ // in request queue
+ if (up == requests[v].display) {
+ // delete request if display state is same as request
+ (keysof(reqtimes)).remove(v);
+ (keysof(requests)).remove(v);
+ } else {
+ // update time
+ reqtimes[v] = time;
+ }
+ } else if (up != v.v_popbox.display) {
+ // add to request queue
+ requests[v] = v;
+ reqtimes[v] = time;
+ } else {
+ return;
+ }
+
+ // check if pop request thread is running and necessary
+ if (!poptip and requests[v]) {
+ // signal thread is active
+ poptip = true;
+ // initiate a background thread to hande timed pop requests
+ vexi.thread = function() {
+ var activerequests;
+ do {
+ // reset active marker
+ activerequests = false;
+ // loop through pop requests
+ for (var key in requests) {
+ // update request time and act if necessary
+ if (0 >= (reqtimes[key] -= interval)) {
+ requests[key].display ? popDown(v) : popUp(v);
+ continue;
+ }
+ // mark to keep loop active
+ activerequests = true;
+ }
+ // sleep
+ vexi.thread.sleep( interval );
+ // loop if marked
+ } while (activerequests);
+ // signal thread has ended
+ poptip = false;
+ }
+ }
+ }
+
+ /** add a popupable box to the surface */
+ model.addPopBox = function(v) {
+ var p = v.v_popbox;
+
+ // detach popbox
+ p.thisbox = null;
+
+ // use default group if none is specified
+ var g = p.popgroup ? p.popgroup : "default";
+
+ if (popforegs[g]) {
+ // if group exists slot into it
+ popforegs[g].add(p);
+
+ } else {
+ // initialize new group, especially its foreground box
+ var z = p.popindex;
+ if (z==null) {
+ z = 0;
+ }
+ var fg = vexi.box;
+ fg.cursor = "default";
+ fg.display = false;
+ fg.shrink = true;
+ fg.zindex = z;
+ fg.add(p);
+ setupHoldingBox(fg);
+ popforegs[g] = fg;
+ var n = $container.numchildren;
+ for (var i=1; n>i; i++) {
+ if ($container[i].zindex>z) {
+ $container[i] = fg;
+ return;
+ }
+ }
+ $container[n] = fg;
+ }
+ }
+
+ /** remove a popupable box from the surface */
+ model.delPopBox = function(v) {
+ var p = v.v_popbox;
+ // use default group if none is specified
+ var g = p.popgroup ? p.popgroup : "default";
+ if (p.visible) {
+ // clean up popbox
+ popDown(v);
+ }
+ var fg = popforegs[g];
+ // FIXME: needed to avoid error; open/close 'packed layout' tab in
demo
+ if (fg==null) {
+ return;
+ }
+ fg[fg.indexof(p)] = null;
+
+ if (fg.numchildren == 0) {
+ // clean up unused foreground box
+ popforegs[g] = null;
+ fg.thisbox = null;
+ }
+ }
+
+ /** pop box 'v', direction 'up', optionally after 'time' */
+ model.pop = function(v, up, time) {
+ if (time) {
+ popRequest(v, up, time);
+ } else {
+ if (up) {
+ popUp(v);
+ } else {
+ popDown(v);
+ }
+ }
+ }
+
+ /** popdown when surface loses focus unless told to otherwise */
+ surface.frame.Focused ++= function(v) {
+ cascade = v;
+ if (!v) {
+ for (var k,p in popbygroup) {
+ var m = p.v_popmaster;
+ if (!m.ignoreFocusLoss) {
+ m.popdown = true;
+ }
+ }
+ }
+ }
+
+ </ui:box>
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Popupable.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/popupable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Popupable.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Popupable.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,157 @@
+<!-- Copyright 2011 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <usage>
+ Point v_popbox to the box that should be popped up.
+ This should not be the same as the box applying popupable,
+ but instead should be a child box of the template.
+
+ The popbox is positioned according to its surface_x and
+ surface_y properties so set the appropriate traps to
+ adjust these as necessary (v_popbox.surface_x = ...).
+
+ For examples see option and combo in org.vexi.theme.classic
+ </usage>
+ </meta:doc>
+
+ <ui:box>
+
+ // public properties
+ thisbox.focused;
+ thisbox.popupable;
+ thisbox.popup;
+ thisbox.popdown;
+ thisbox.popupdelay = 0;
+ thisbox.popdowndelay = 0;
+ thisbox.popped = false;
+
+ // implementation properties
+ // TODO: thisbox.blockEvents = true;
+ thisbox.popdownOnExternalEvent = true;
+ thisbox.v_popbox = null;
+
+ // assign static trap functions
+ focused ++= static.focusWrite;
+ popdown ++= static.popdownWrite;
+ popped ++= static.poppedRead;
+ popup ++= static.popupWrite;
+ popupable ++= static.popupableRead;
+ surface ++= static.surfaceWrite;
+ v_popbox ++= static.popboxWrite;
+ KeyPressed ++= static.keypressWrite;
+
+ </ui:box>
+
+ // for code readabiliy
+ static.UP = true;
+ static.DOWN = false;
+
+ /** popdown if popbox undisplays itself */
+ static.displayWrite = function(v) {
+ cascade = v;
+ var m = trapee.v_popmaster;
+ if (m.popped and !v) {
+ m.popdown = true;
+ }
+ if (!m.popped and v) {
+ m.popup = true;
+ }
+ }
+
+ /** integration with focusable */
+ static.focusWrite = function(v) {
+ if (!v and trapee.v_popbox and trapee.v_popbox.visible) {
+ trapee.popdown = true;
+ }
+ cascade = v;
+ }
+
+ /** write trap on KeyPressed event */
+ static.keypressWrite = function(v) {
+ cascade = v;
+ if (v == "escape") {
+ trapee.popdown = true;
+ }
+ }
+
+ /** write trap to popdown v_popbox */
+ static.popdownWrite = function(v) {
+ cascade = v;
+ var s = trapee.surface;
+ // need a surface to function
+ if (!s or !trapee.popped) {
+ return;
+ }
+ // pop down
+ s.popup.pop(trapee, static.DOWN, trapee.popdowndelay);
+ trapee.v_popbox.display --= static.displayWrite;
+ }
+
+ /** indicate state of the popbox */
+ static.poppedRead = function() { return trapee.v_popbox.display; }
+
+ /** write trap to popup v_popbox */
+ static.popupWrite = function(v) {
+ cascade = v;
+ var s = trapee.surface;
+ // need a surface to function
+ if (!s or trapee.popped) {
+ return;
+ }
+ // pop up
+ s.popup.pop(trapee, static.UP, trapee.popupdelay);
+ trapee.v_popbox.display ++= static.displayWrite;
+ }
+
+ /** read trap to detect popupable state */
+ static.popupableRead = function() { return trapee.enabled; }
+
+ /** initialize popbox */
+ static.popboxWrite = function(v) {
+ var s = trapee.surface;
+ var p = trapee.v_popbox;
+ if (p) {
+ p.Move --= static.blockEvent;
+ p.v_popmaster = null;
+ if (s) {
+ s.popup.delPopBox(p);
+ }
+ }
+ cascade = v;
+ if (v) {
+ v.Move ++= static.blockEvent;
+ v.display = false;
+ v.v_popmaster = trapee;
+ if (s) {
+ s.popup.addPopBox(trapee);
+ }
+ }
+ }
+
+ /** block press events hitting underneath the popbox */
+ static.blockEvent = function(v) { return true; }
+
+ /** register popbox once surface is available */
+ static.surfaceWrite = function(v) {
+ // clean up old surface
+ var s = trapee.surface;
+ if (s and trapee.v_popbox) { // FIXME: why is the 2nd check required?
+ if (trapee.popped) {
+ s.popup.pop(trapee, static.DOWN, 0);
+ }
+ s.popup.delPopBox(trapee);
+ trapee.v_popbox.display --= static.displayWrite;
+ }
+ // register with new surface
+ if (v and trapee.v_popbox) {
+ v.popup.addPopBox(trapee);
+ // must do this because v_popbox is removed
+ // and its surface trap won't fire otherwise
+ trapee.v_popbox.surface = v;
+ }
+ cascade = v;
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Repeater.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/repeatable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Repeater.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Repeater.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,88 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>Apply to make a widget have a repeating action</desc>
+ <usage>
+ The repeating behaviour depends on the following:
+
+ * repeat - put to true or false to start/stop repeating
+
+ * interval - the interval between repeats in ms
+
+ * repeatCall - the property to put to when repeating
+
+ Repeater widgets recognise the following state property:
+
+ * enabled - Repeating behaviour only works if 'true'
+ and putting 'false' to enabled will end any
+ ongoing repeating
+ </usage>
+ </meta:doc>
+
+ <ui:Box>
+
+ thisbox.counter = 0; // consecutive repetition counter
+ thisbox.enabled;
+ thisbox.interval = 100; // repetition interval (ms)
+ thisbox.repeat = false; // repeating state
+ thisbox.repeatCall = "action"; // the property to repeat to
+
+ if (enabled==null) {
+ enabled = true;
+ }
+
+ enabled ++= static.enableWrite;
+ repeat ++= static.repeatWrite;
+
+ </ui:Box>
+
+ /** initiate (true) or stop (false) repeating action */
+ static.enableWrite = function(v) {
+ cascade = v;
+ if (!trapee.enabled and trapee.repeat) {
+ trapee.repeat = false;
+ }
+ }
+
+ /** initiate (true) or stop (false) repeating action */
+ static.repeatWrite = function(v) {
+ if (v) {
+ if (!trapee.repeat) {
+ // perform first action immediately
+ trapee.v_repeatCallTime = vexi.date().getTime();
+ trapee.action = true;
+ // only start if previously false and thread is inactive
+ if (!trapee.v_repeat_thread) {
+ // marks the thread as active
+ trapee.v_repeat_thread = true;
+ // begin background thread
+ vexi.thread = function() {
+ do {
+ // pause before first repeating action
+ var t = vexi.date().getTime();
+ var d = t - trapee.v_repeatCallTime;
+ while (trapee.repeat and (trapee.interval > d)) {
+ vexi.thread.sleep(trapee.interval - d);
+ t = vexi.date().getTime();
+ d = t - trapee.v_repeatCallTime;
+ }
+ if (trapee.repeat) {
+ trapee.v_repeatCallTime = t;
+ trapee[trapee.repeatCall] = true;
+ trapee.counter ++;
+ }
+ } while (trapee.repeat);
+ // mark thread inactive
+ trapee.v_repeat_thread = false;
+ }
+ }
+ }
+ } else {
+ trapee.counter = 0;
+ }
+ cascade = v;
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectContainer.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectcontainer.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectContainer.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectContainer.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,123 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role"
xmlns:rdt="vexi.util.redirect" >
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ Implements a container for selectable children.
+ </desc>
+ <notes>
+ If using this template, you must either post-apply
+ org.vexi.lib.layout.container or alternatively put
+ 'true' to the 'v_container' property manually.
+ </notes>
+ </meta:doc>
+
+ <ui:box>
+
+ thisbox.v_content = thisbox;
+ thisbox.v_listgroup;
+
+ thisbox.group ++= static.groupRead;
+ thisbox.v_listgroup ++= static.listgroupWrite;
+
+ /** select the first available item in the list */
+ thisbox.selectFirst = function() {
+ var group = v_listgroup;
+ if (group==null) {
+ return;
+ }
+ var vec = group.members;
+ var item = vec.first;
+ while (item!=null) {
+ if (item.display and item.enabled) {
+ item.selected = true;
+ break;
+ }
+ item = vec.after(item);
+ }
+ }
+
+ /** select the lastmost available item in the list */
+ thisbox.selectLast = function() {
+ var group = v_listgroup;
+ if (group==null) {
+ return;
+ }
+ var vec = group.members;
+ var item = vec.last;
+ while (item!=null) {
+ if (item.display and item.enabled) {
+ item.selected = true;
+ break;
+ }
+ item = vec.before(item);
+ }
+ }
+
+ thisbox.v_container ++= static.containerWrite;
+
+ </ui:box>
+
+ /** access to the group */
+ static.groupRead = function() {
+ return trapee.v_listgroup;
+ }
+
+ /** allow trapping/putting to selected */
+ static.listgroupWrite = function(v) {
+ cascade = v;
+ rdt..addRedirect(trapee, trapee.v_listgroup, "selected");
+ }
+
+ /** assign group and traps to children */
+ static.childrenAdded = function(c) {
+ cascade = c;
+ var t = trapee;
+ var g = t.v_listgroup;
+ if (c) {
+ if (g) {
+ // insert into existing group
+ // NB write trap on selectable.group handles assignment
+ c.group = g;
+ } else {
+ // no group yet, create one
+ // NB read trap on selectable.group handles group creation
+ g = c.group;
+ if (g==null) {
+ // not a selectable
+ return;
+ }
+ t.v_listgroup = g;
+
+ if (trapee.syncView) {
+ // keep selected in view if a scrolling widget
+ g.selected ++= trapee.syncView;
+ }
+ if (c.selected) {
+ // respect selected state of c
+ t.v_listgroup.selected = c;
+ }
+ }
+ }
+ }
+
+ /** assign group and traps to children */
+ static.childrenRemoved = function(c) {
+ if (c==null) {
+ var _c = trapee[trapname];
+ if (_c and _c.v_group) {
+ _c.group = null;
+ }
+ }
+ cascade = c;
+ }
+
+ /** complete widget is set up */
+ static.containerWrite = function(v) {
+ cascade = v;
+ trapee.Children ++= static.childrenAdded;
+ trapee.v_content.Children ++= static.childrenRemoved;
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectGrouper.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectgroup.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectGrouper.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectGrouper.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,34 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:meta="vexi://meta"
+ xmlns="org.vexi.lib.role">
+
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ Groups visible selectable children e.g. RadioButtons
+ </desc>
+ <notes>
+ If using this template, you must either post-apply
+ org.vexi.lib.role.Container or alternatively put
+ 'true' to the 'v_container' property manually.
+ </notes>
+ </meta:doc>
+
+ <SelectContainer>
+
+ // allow group enable/disable
+ thisbox.enabled ++= static.enableWrite;
+
+ </SelectContainer>
+
+ static.enableWrite = function(v) {
+ cascade = v;
+ var content = trapee.v_content;
+ var n = content.numchildren;
+ for (var i=n-1; i>=0; i--) {
+ content[i].enabled = v;
+ }
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectList.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectlist.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectList.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectList.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,97 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ Implements a container for selectable children.
+ </desc>
+ <notes>
+ If using this template, you must either post-apply
+ org.vexi.lib.layout.container or alternatively put
+ 'true' to the 'v_container' property manually.
+ </notes>
+ </meta:doc>
+
+ <SelectContainer>
+
+ thisbox.selection;
+
+ // reusable distanceto objects
+ var dtscroll = null;
+ var dtcontent = null;
+
+ /** keeps the selected item within view */
+ thisbox.syncView = function(v) {
+ cascade = v;
+ if (!v or !popped) {
+ return;
+ }
+ if (dtscroll==null) {
+ dtscroll = th_scroll.distanceto(v);
+ dtcontent = v_content.distanceto(v);
+ } else {
+ dtscroll.to = v;
+ dtcontent.to = v;
+ }
+ if (dtscroll.y+v.height > th_scroll.height) {
+ th_scroll.viewy = dtcontent.y+v.height-th_scroll.height;
+ } else if (0 > dtscroll.y) {
+ th_scroll.viewy = dtcontent.y;
+ }
+ }
+
+ thisbox.selection ++= static.selectionRead;
+ thisbox.v_container ++= static.containerWrite;
+
+ </SelectContainer>
+
+ /** applied to list items */
+ static.enterEvent = function(v) {
+ if (trapee.enabled) {
+ trapee.selected = true;
+ }
+ cascade = v;
+ }
+
+ /** applied to list items */
+ static.leaveEvent = function(v) {
+ if (trapee.selected) {
+ trapee.selected = false;
+ }
+ cascade = v;
+ }
+
+ /** assign group and traps to children */
+ static.childrenWrite = function(c) {
+ if (c) {
+ c.Enter ++= static.enterEvent;
+ c.Leave ++= static.leaveEvent;
+ } else {
+ var _c = trapee[trapname];
+ if (_c) {
+ _c.Enter ++= static.enterEvent;
+ _c.Leave --= static.leaveEvent;
+ }
+ }
+ cascade = c;
+ }
+
+ /** complete widget is set up */
+ static.containerWrite = function(v) {
+ cascade = v;
+ trapee.v_content.Children ++= static.childrenWrite;
+ }
+
+ /** return selected elements as an array */
+ static.selectionRead = function() {
+ var s = [];
+ for (var i,child in trapee.v_content) {
+ if (child.selected) {
+ s.push(child);
+ }
+ }
+ return s;
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Selectable.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/selectable.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Selectable.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Selectable.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,264 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi.util">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>
+ </desc>
+ <todo>
+ 1..n selection model with rolling selection
+ Split group manager code into 'lib.role.selectmanager'
+ </todo>
+ <details>
+ Items which wish to be part of a group of selectable widgets
+ are grouped together using the following properties:
+
+ * group - When read this returns the group of a selectable
+ widget. If it has no group, one is created and then
+ returned, so reading this property inserts a widget
+ into a group of its own. Putting a different group
+ to this property will add the widget to that group.
+
+ * selected - Whether this is the (or one of the) selected
+ members of its group.
+
+ It integrates with clickable and focusable.
+ </details>
+ </meta:doc>
+
+ <ui:box>
+
+ thisbox.action; // clickable integration
+ thisbox.focusable; // focusable integration
+ thisbox.group; // external access to group
+ thisbox.v_group; // internal reference to group
+ thisbox.mixed = false; // mixed status
+ thisbox.nextselect; // next group member to select
+ thisbox.prevselect; // previous group member to select
+ thisbox.selected = false; // selection status
+
+ action ++= static.actionWrite;
+ focusable ++= static.focusableRead;
+ group ++= static.groupRead;
+ group ++= static.groupWrite;
+ nextselect ++= static.nextselectRead;
+ prevselect ++= static.prevselectRead;
+ selected ++= static.selectedRead;
+ selected ++= static.selectedWrite;
+ KeyPressed ++= static.keypressWrite;
+
+ </ui:box>
+
+ /** clickable integration */
+ static.actionWrite = function(v) {
+ cascade = v;
+ trapee.selected = trapee.v_group ? true : !trapee.selected;
+ }
+
+ /** integration with clickable and focusable */
+ static.focusableRead = function() {
+ var t = trapee;
+ var g = trapee.v_group;
+ // focusable property must be true
+ return cascade and (!g or
+ // selectable clickable widget being clicked on
+ (t.primed or t.selected) or
+ // navigated group with keys
+ (g.keygroup) or
+ // no other group member is selected
+ (!g.selected and (t == g.firstMember)));
+ }
+
+ /** group read trap */
+ static.groupRead = function() {
+ // if no group, get one
+ if (!trapee.v_group) {
+ trapee.v_group = static.toGroup(trapee);
+ }
+ return trapee.v_group;
+ }
+
+ /** group write trap */
+ static.groupWrite = function(v) {
+ // add us to group v
+ trapee.v_group = static.toGroup(trapee, trapee.v_group, v);
+ cascade = v;
+ }
+
+ /** find the next selectable member */
+ static.nextselectRead = function() {
+ var ns = trapee;
+ var g = ns.v_group;
+ do {
+ ns = g.members.after(ns);
+ if (!ns) {
+ ns = g.members.first;
+ }
+ if (!ns.visible or !ns.enabled) {
+ continue;
+ }
+ return ns;
+ } while (ns != trapee);
+ return ns;
+ }
+
+ /** find the previous selectable member */
+ static.prevselectRead = function() {
+ var ps = trapee;
+ var g = ps.v_group;
+ do {
+ ps = g.members.before(ps);
+ if (!ps) {
+ ps = g.members.last;
+ }
+ if (!ps.visible or !ps.enabled) {
+ continue;
+ }
+ return ps;
+ } while (ps != trapee);
+ return ps;
+ }
+
+ /** selected read trap - use 'cascade == true' to guarrantee booleans */
+ static.selectedRead = function() { return trapee.mixed or (cascade ==
true); }
+
+ /** selected write trap */
+ static.selectedWrite = function(v) {
+ var t = trapee;
+ var g = t.v_group;
+ if (g) {
+ if (v) {
+ if (g.selected != t) {
+ if (g.selected) {
+ g.selected.selected = false;
+ }
+ g.selected = t;
+ g.focused = true;
+ }
+ } else if (g.selected == t) {
+ g.selected = null;
+ }
+ }
+ // to avoid selected == null
+ cascade = v == true;
+ }
+
+ /** selection by keyboard navigation for selectable groups */
+ static.keypressWrite = function(v) {
+ var t = trapee;
+ var g = t.v_group;
+ if (!g) {
+ // can't do anything with no group
+ cascade = v;
+ return;
+ }
+
+ // deal with key event
+ g.keygroup = true;
+ if (v == "down" or v == "right") {
+ // forwards
+ var ns = t.nextselect;
+ if (ns) {
+ ns.selected = true;
+ }
+ } else if (v == "up" or v == "left") {
+ // backwards
+ var ps = t.prevselect;
+ if (ps) {
+ ps.selected = true;
+ }
+ } else {
+ // pass to other widget code
+ cascade = v;
+ }
+ // finished - move on
+ g.keygroup = false;
+
+ // focus the next selected
+ if (g.selected and g.selected != trapee) {
+ g.selected.focused = true;
+ }
+ }
+
+ // static content
+
+ // create a new group containing, optionally, v
+ var newGroup = function(v) {
+ // initialize new group
+ var g = {
+ keygroup : false,
+ members : new .vector(v),
+ selected : null,
+ selection : []
+ };
+
+ // merge another select group with this one
+ g.merge = function(group, after) {
+ if (group.selected) {
+ group.selected = false;
+ }
+ var mem = group.members;
+ var obj = mem.first;
+ // reassign group references - must happen before merge
+ while (obj) {
+ obj.v_group = g;
+ obj = mem.after(obj);
+ }
+ // merge vectors
+ g.members.merge(mem, after);
+ }
+
+ // select the first in the group
+ g.firstMember ++= function() {
+ var f = g.members.first;
+ while (f and !f.enabled or !f.visible) {
+ f = g.members.after(f);
+ }
+ return f;
+ }
+
+ // return next member in the group after 'n'
+ g.memberAfter = function(n) { return n.nextselect; }
+
+ // select previous group member before 'p'
+ g.memberBefore = function(p) { return p.prevselect; }
+
+ return g;
+ }
+
+ /** change the group of v from oldg to newg, dealing with null args */
+ static.toGroup = function(v, oldg, newg, after) {
+ if (3 > arguments.length) {
+ // no group given, create group
+ newg = newGroup(v);
+ } else {
+ if (oldg) {
+ // remove v from oldg
+ oldg.members.remove(v);
+ if (oldg.selected == v) {
+ oldg.selected = null;
+ }
+ }
+ if (newg) {
+ // add to group
+ if (after) {
+ newg.members.insert(v, after);
+ } else {
+ newg.members.push(v);
+ }
+ } else {
+ return null;
+ }
+ }
+ if (v.selected) {
+ // initialize as selected
+ if (newg.selected) {
+ newg.selected.selected = false;
+ }
+ newg.selected = v;
+ }
+ // return the new group for reference
+ return newg;
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Subsurface.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/subsurface.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Subsurface.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Subsurface.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,46 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta"
+ xmlns:role="org.vexi.lib.role" xmlns:rdrt="vexi.util.redirect">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <name>Subsurface</name>
+ <desc>For advanced management of surface objects</desc>
+ <usage>
+ Using a subsurface allows a widget to modify a surface
+ by using read traps on a clone that will not affect the
+ original surface.
+
+ Preapply and the surface argument will always be the
+ clone. Postapply if your template requires access to
+ the original surface object as well as the clone.
+ </usage>
+ </meta:doc>
+
+ <ui:box>
+
+ var old_clone; // clone of old surface
+ var old_surface; // original old surface
+ var surface_clone; // clone of surface object
+
+ /** return the cloned surface object representing the current surface
*/
+ thisbox.surface ++= function() {
+ // the check against the old surface is required to
+ // keep descendent surface trap behaviour consistent
+ // - if we just return the clone then surface reads
+ // appear the same to descendents pre/post cascade
+ return cascade==old_surface ? old_clone : surface_clone;
+ }
+
+ /** set up clone of the surface object */
+ thisbox.surface ++= function(v) {
+ surface_clone = v==null ? null : vexi.clone(v);
+ cascade = surface_clone;
+ // all descendent surface traps are now complete
+ // so subsuquent actions here do not affect them
+ old_clone = surface_clone;
+ old_surface = v;
+ }
+
+ </ui:box>
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Surface.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t)
===================================================================
---
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Surface.t
(rev 0)
+++
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Surface.t
2015-05-09 09:40:24 UTC (rev 4793)
@@ -0,0 +1,193 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi">
+ <meta:doc>
+ <author>Charles Goodwin</author>
+ <desc>Apply to the root of a surface (frame/window)</desc>
+ </meta:doc>
+
+ <ui:Box>
+
+ const readOnly = .util.common..readOnly;
+ const addRedirect = .util.redirect..addRedirect;
+
+ // the surface object and key components
+ var s = {};
+
+ /** proxy to the surface object */
+ thisbox.surface ++= function() { return s; };
+
+ var event = {};
+ s.event ++= function() { return event; }
+ s.event ++= readOnly;
+
+ var frame = {};
+ s.frame ++= function() { return frame; }
+ s.frame ++= readOnly;
+
+ // for locking trap forwarding on CLose/s.Close
+ var closeLock = false;
+
+ /** notify surface.Close when closing surface
+ * REMARK - done this way [instead of using a redirect] to prevent
+ * application code from blocking the user closing a frame
+ */
+ thisbox.Close ++= function(v) {
+ if (!closeLock) {
+ closeLock = true;
+ frame.Close = true;
+ closeLock = false;
+ }
+ cascade = v;
+ }
+
+ /** manually redirect s.frame.Close */
+ frame.Close ++= function(v) {
+ if (closeLock) {
+ return;
+ }
+ closeLock = true;
+ Close = true;
+ closeLock = false;
+ cascade = v;
+ }
+
+ /** used to add traps on surface.Move as redirecting Move impacts
performance */
+ event.addMoveTrap = function(v) { thisbox._Move ++= v; };
+
+ /** used to remove traps from surface.Move */
+ event.delMoveTrap = function(v) { thisbox._Move --= v; };
+
+ /** redirect input events for access */
+ addRedirect(event, thisbox,
+ "Click1", "Click2", "Click3", "HScroll", "VScroll",
+ "DoubleClick1", "DoubleClick2", "DoubleClick3",
+ "Press1", "Press2", "Press3",
+ "Release1", "Release2", "Release3",
+ "_Click1", "_Click2", "_Click3", "_HScroll", "_VScroll",
+ "_DoubleClick1", "_DoubleClick2", "_DoubleClick3",
+ "_Press1", "_Press2", "_Press3",
+ "_Release1", "_Release2", "_Release3" );
+
+ /** special case key events for focusable integration */
+ addRedirect(thisbox, event, "_KeyPressed", "_KeyReleased" );
+
+ /** redirect frame properties for access */
+ addRedirect(frame, thisbox,
+ "framewidth", "frameheight", "frameicon", "frametitle",
+ "mouse", "distanceto", "width", "height", "x", "y",
+ "ToFront", "ToBack", "RequestFocus", "Maximized", "Minimized");
+
+ // special case Focused, forward only
+ thisbox.Focused ++= function(v) { cascade = v; frame.Focused = v; }
+
+ </ui:Box>
+ <theme.Surface />
+
+ /** access to the theme parameter setting */
+ const getThemeRes = function(themestr) {
+ var themeres = null;
+ if (themestr != null) {
+ var sub = themestr.split('.');
+ var res = vexi[""];
+ for (var i=0; sub.length>i; i++) {
+ res = res[sub[i]];
+ }
+ themeres = res;
+ }
+ // string doesn't resolve
+ if (themeres == null) {
+ vexi.log.debug("Could not resolve '"+themestr+"', looking in
.conf.Theme");
+ if (.conf.Theme[""]!=null) {
+ themeres = .conf.Theme..location;
+ }
+ }
+ if (themeres == null) {
+ vexi.log.debug("No theme found, defaulting to classic");
+ themeres = vexi..org.vexi.theme.classic;
+ }
+ var str = (""+ret);
+ str = str.substring(0, str.indexOf('$'));
+ var themename;
+ try { themename = ret.Settings..themename; } catch(e) { }
+ vexi.log.debug("Using theme "+(themename?" ("+str+")":str));
+ return themeres;
+ }
+
+
+ /** access to the icon parameter setting */
+ const getIconResource = function() {
+ var iconstr = vexi.params["vexi.icon"];
+ var iconres = null;
+ if (iconstr != null) {
+ var sub = iconstr.split('.');
+ var res = vexi[""];
+ for (var i=0; sub.length>i; i++) {
+ res = res[sub[i]];
+ }
+ iconres = res;
+ }
+ if (iconres == null) {
+ if (.conf.Icon[""]!=null) {
+ iconres = .conf.Icon..iconpath?[0];
+ }
+ }
+ if (iconres == null) {
+ try { iconres = .theme.Settings..iconlocation; } catch(e) { }
+ }
+ var str = (""+ret);
+ str = str.substring(0, str.indexOf('$'));
+ vexi.log.debug("Using icon set: "+str);
+ return iconres;
+ }
+
+ static.getIcons = function(){
+ var r = .conf.Icon[""]?.iconpath;
+ if(r==null) return [];
+ return r;
+ };
+
+ /*
+ * THEME HANDLING
+ */
+
+ static.theme ++= function(newtheme) {
+ if (typeof newtheme == "string") {
+ static.theme = getThemeRes(newtheme);
+ return;
+ }
+ if (static.theme) {
+ .theme --= static.theme;
+ }
+ try {
+ .theme ++= newtheme;
+ cascade = newtheme;
+ } catch(e) {
+ vexi.trace("Unable to apply theme");
+ vexi.trace(e);
+ }
+ }
+
+
+ try {
+ const theme = getThemeRes(vexi.params["vexi.theme"]);
+ // theme specified
+ static.theme = theme;
+ } catch(e) {
+ vexi.trace("Unable to establish theme, most widgets will not work");
+ vexi.trace(e);
+ }
+
+ try {
+ var icons = getIconResource();
+ // icons specified
+ if (icons) {
+ .icon ++= icons;
+ }
+ vexi..org.vexi.lib.layout.Icon..iconpath = getIcons();
+ } catch(e) {
+ vexi.trace("Unable to establish icons");
+ vexi.trace(e);
+ }
+
+</vexi>
Copied:
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/TooltipAgent.t
(from rev 4785,
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/tooltipable.t)
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn