Revision: 4821 http://sourceforge.net/p/vexi/code/4821 Author: mkpg2 Date: 2015-10-29 18:27:49 +0000 (Thu, 29 Oct 2015) Log Message: ----------- Refactor/fix timefield. - Fix. Was not triggering value property always. - Fix. Sometimes could set spurious values (e.g. 'now') to the value property. - Change. Timefield by default 24hrs. - Change. No longer supports other types other than string.
Modified Paths: -------------- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/timefield.t branches/vexi3/org.vexi-vexi.widgets/src_main/vexi/conf/settings.t branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/timefield.t Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/timefield.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/timefield.t 2015-10-29 18:22:44 UTC (rev 4820) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/timefield.t 2015-10-29 18:27:49 UTC (rev 4821) @@ -37,49 +37,228 @@ thisbox.v_init = static.init; thisbox.v_textbox = false; - thisbox.use24hours = conf.settings..time_use24hours; - thisbox.period = null; - thisbox.hours = null; - thisbox.mins = null; + thisbox.format = (conf.settings..time_use24hours==false)?"12":"24"; + thisbox.period = null; + thisbox.minsIncrement = 1; + + + // We are using variables since we want to be able to update both components of the value + // without multiple triggers for anything listening to the value. + var _hours = null; + var _mins = null; //thisbox.secs; - thisbox.setTime = function() { + const updateUI = function() { if (format=="12") { $period.display = true; $sep2.display = true; - $period.text = hours>11 and hours!=0?"PM":"AM"; + $period.text = _hours>11 and _hours!=0?"PM":"AM"; } else { $period.display = false; $sep2.display = false; } - if (hours==null or mins==null) { + if (_hours==null or _mins==null) { $period.text = "AM"; $hours.text = "--"; $mins.text = "--"; } else { if (format=="12") { - var h = (hours>12?hours-12:hours); + var h = (_hours>12?_hours-12:_hours); h = h==0?12:h; $hours.text = (h>9?"":"0")+h; } else { - $hours.text = (hours>9?"":"0")+hours; + $hours.text = (_hours>9?"":"0")+_hours; } - $mins.text = (mins>9?"":"0")+mins; + $mins.text = (_mins>9?"":"0")+_mins; } } + var internal = false; + const internalTrigger = function(){ + internal = true; + try{ + thisbox.value = value; + }finally{ + internal = false; + } + }; + + //////// // public properties + thisbox.hours ++= function(){ return _hours; }; + thisbox.hours ++= function(v){ + while (v>23) { + v = v-24; + } + while (0>v) { + v = v+24; + } + + if(_hours!=v){ + _hours = v; + internalTrigger(); + } + }; - thisbox.use24hours ++= static.setTime; - thisbox.hours ++= static.hoursWrite; - thisbox.mins ++= static.minsWrite; - thisbox.period ++= static.periodWrite; - thisbox.value ++= static.valueRead; - thisbox.value ++= static.valueWrite; - thisbox.text ++= static.textRead; - thisbox.text ++= static.textWrite; + thisbox.mins ++= function(){ return _mins; }; + thisbox.mins ++= function(v){ + var h = _hours; + while (v>59) { + v -= 60; + h++; + } + while (0>v) { + v += 60; + h--; + } + + h = h % 24; + + if(_hours!=h or _mins!=v){ + _hours = h; + _mins = v; + internalTrigger(); + } + }; + + thisbox.period ++= function(v){ + if(v=="PM"){ + if(_hours==0) _hours = 12; + if(_hours>11) _hours -=12; + }else if(v=="AM"){ + if(_hours==12) _hours = 0; + if(11>=_hours) _hours +=12; + } + internalTrigger(); + }; + + thisbox.value ++= function(){ + var h = _hours; + var m = _mins; + if (h==null or m==null) { + return null; + } + return (h>9?"":"0")+h+":"+(m>9?"":"0")+m+":00"; + }; + + + // this parses the numbers from the string and set the internal variables, a single trigger is applied at the end + const parseValue = function(s){ + if (s == "") { + // reset the time + _hours = null; + _mins = null; + return; + } + + // string value + var c = s.charCodeAt(0); + if ((c>=65 and 90>=c) or (c>=97 and 122>=c)) { + switch(s.toLowerCase()) { + case "now": + var d = vexi.date(); + _hours = d.getHours(); + _mins = d.getMinutes(); + break; + case "noon": + _hours = 12; + _mins = 0; + break; + case "midnight": + _hours = 0; + _mins = 0; + break; + default: + throw "unsupported time string: '"+s+"'"; + } + return; + } + + // manually parse time string + var i = 0; + var s0 = ""; + var s1 = ""; + //var s2 = ""; + var pm = s.indexOf('p')>=0 or s.indexOf('P')>=0; + try { + for (var c = s.charCodeAt(i); c>57 or 48>c; c = s.charCodeAt(++i)) { /* skip non-numbers */ } + for (var c = s.charCodeAt(i); c>47 and 58>c; c = s.charCodeAt(++i)) s0 = (s0=="0"?"":s0) + s.charAt(i); + for (var c = s.charCodeAt(i); c>57 or 48>c; c = s.charCodeAt(++i)) { /* skip non-numbers */ } + for (var c = s.charCodeAt(i); c>47 and 58>c; c = s.charCodeAt(++i)) s1 = (s1=="0"?"":s1) + s.charAt(i); + //for (var c = s.charCodeAt(i); c>57 or 48>c; c = s.charCodeAt(++i)) { /* skip non-numbers */ } + //for (var c = s.charCodeAt(i); c>47 and 58>c; c = s.charCodeAt(++i)) s2 = (s2=="0"?"":s2) + s.charAt(i); + if (s0 == "" ) { + if (s1 == "") { + throw "rethrow"; + } + s0 = s1; + s1 = ""; + } + + var h,m; + if (s1 == "") { + var l = s0.length; + // shorthand for dealing with 2330 or 11 or 230 or 3pm + h = vexi.string.parseInt(3>l?s0:s0.substring(0,l==3?1:2), 10); + m = 3>l?0:vexi.string.parseInt(s0.substring(l==3?1:2), 10); + } else { + h = vexi.string.parseInt(s0, 10); + m = vexi.string.parseInt(s1, 10); + + while(m>60){ m-=60; h+=1; } + while(h>24){ h-=24; } + + //var s = vexi.string.parseInt(s2, 10); + // sanitize values + if (h==24 or 0>h) h = 0; + if (h>23) h = 23; + if (m>59) m = 59; + if (0>m) m = 0; + //if (s>59) s = 59; + //if (0>s) s = 0; + // assign + //trapee.secs = s; + } + + if (12> h and pm) { + h += 12; + } + _hours = h; + _mins = m; + + + while(_mins % minsIncrement){ + _mins -=1; + } + } catch (e) { throw "unsupported text value for timefield: '"+s+"'"; } + return; + }; + + thisbox.value ++= function(v){ + if(!internal){ + // needed? + if(v=="null" or v=="") { + v = null; + } + + if(v==null){ + _hours = null; + _mins = null; + }else{ + parseValue(v); + internalTrigger(); + } + + } + updateUI(); + }; + + + thisbox.text ++= function(){ return value; } + thisbox.text ++= function(v){ value = v; }; + thisbox.enabled ++= function(v) { cascade = v; $more.enabled = v; @@ -105,22 +284,23 @@ $period.Press1 ++= selectPart; const setDefault = function(){ - if(hours==null and mins==null){ - value = thisbox["default"]?:"now"; + if(_hours==null and _mins==null){ + parseValue(thisbox["default"]?:"now"); + internalTrigger(); }else{ - if (hours==null) { + if (_hours==null) { hours = 0; } - if (mins==null) { + if (_mins==null) { mins = 0; } } + }; - thisbox.minsIncrement = 1; const incrementTrap = function(v){ - if (hours==null or mins==null) { + if (_hours==null or _mins==null) { setDefault(); } else { var part; @@ -134,38 +314,37 @@ if (part == $period) { if(more){ - if (12>hours) { + if (12>_hours) { hours += 12; } }else{ - if (hours>11) { + if (_hours>11) { hours -= 12; } } } else if (part == $hours) { if(more){ - if(loop!=false || 23>hours){ - hours = hours+1; + if(loop!=false || 23>_hours){ + hours = _hours+1; } }else{ - if(loop!=false || hours>0){ - hours = hours-1; + if(loop!=false || _hours>0){ + hours = _hours-1; } } } else if (part == $mins) { if(more){ - if(loop!=false || ((60-minsIncrement)>mins || 23>hours)){ - mins = mins+minsIncrement; + if(loop!=false || ((60-minsIncrement)>_mins || 23>_hours)){ + mins = _mins+minsIncrement; } }else{ - if(loop!=false || hours>0 || mins>=minsIncrement){ - mins = mins-minsIncrement; + if(loop!=false || _hours>0 || _mins>=minsIncrement){ + mins = _mins-minsIncrement; } } } } - value = value; return; }; @@ -179,10 +358,11 @@ var editToValue = function() { try { - value = $edit.v_edit.text; - if (12>hours and $editperiod.text=="PM") { + parseValue($edit.v_edit.text); + if (12>_hours and $editperiod.text=="PM") { hours+=12; } + internalTrigger(); } catch(e) { /* FEATURE: callback */ } finally { $editview.display = false; } } @@ -257,7 +437,7 @@ break; case "enter": if (value==null) { - value = thisbox["default"]?:"now"; + setDefault(); } break; case "back_space": @@ -289,39 +469,9 @@ static.init = { fill : .settings..fill }; - /** trap to invoke setTime */ - static.setTime = function(v) { cascade = v; trapee.setTime(); } - /** constrain hours to 24 */ - static.hoursWrite = function(v) { - while (v>23) { - v = v-24; - } - while (0>v) { - v = v+24; - } - cascade = v; - trapee.setTime(); - } + - /** contrain mins to 60 and adjust hours */ - static.minsWrite = function(v) { - var h = trapee.hours; - while (v>59) { - v -= 60; - h++; - } - while (0>v) { - v += 60; - h--; - } - if (h!=trapee.hours) { - trapee.hours = h; - } - cascade = v; - trapee.setTime(); - } - /** invoke focus/selected visual effect */ static.focusWrite = function(v) { cascade = v; trapee.selected = trapee.selected; } @@ -338,123 +488,8 @@ trapee.selected.selected = trapee.focused; } } + + + - /** returns the time as a string */ - static.textRead = function() { - var h = trapee.hours; - var m = trapee.mins; - var s = trapee.secs; - if (h==null or m==null) { - return ""; - } - return (h>9?"":"0")+h+":"+(m>9?"":"0")+m+":00";//+(s>0?"":"0")+s; - } - - /** for handling writes as a string */ - static.textWrite = function(v) { - if (v == "") { - // reset the time - trapee.value = null; - return; - } - - // string value - var c = v.charCodeAt(0); - if ((c>=65 and 90>=c) or (c>=97 and 122>=c)) { - switch(v.toLowerCase()) { - case "now": - var d = vexi.date(); - trapee.hours = d.getHours(); - trapee.mins = d.getMinutes(); - break; - case "noon": - trapee.hours = 12; - trapee.mins = 0; - break; - case "midnight": - trapee.hours = 0; - trapee.hours = 0; - break; - default: - throw "unsupported time string: '"+v+"'"; - } - return; - } - - // manually parse time string - var i = 0; - var s0 = ""; - var s1 = ""; - //var s2 = ""; - var pm = v.indexOf('p')>=0 or v.indexOf('P')>=0; - try { - for (var c = v.charCodeAt(i); c>57 or 48>c; c = v.charCodeAt(++i)) { /* skip non-numbers */ } - for (var c = v.charCodeAt(i); c>47 and 58>c; c = v.charCodeAt(++i)) s0 = (s0=="0"?"":s0) + v.charAt(i); - for (var c = v.charCodeAt(i); c>57 or 48>c; c = v.charCodeAt(++i)) { /* skip non-numbers */ } - for (var c = v.charCodeAt(i); c>47 and 58>c; c = v.charCodeAt(++i)) s1 = (s1=="0"?"":s1) + v.charAt(i); - //for (var c = v.charCodeAt(i); c>57 or 48>c; c = v.charCodeAt(++i)) { /* skip non-numbers */ } - //for (var c = v.charCodeAt(i); c>47 and 58>c; c = v.charCodeAt(++i)) s2 = (s2=="0"?"":s2) + v.charAt(i); - if (s0 == "" ) { - if (s1 == "") { - throw "rethrow"; - } - s0 = s1; - s1 = ""; - } - if (s1 == "") { - var l = s0.length; - // shorthand for dealing with 2330 or 11 or 230 or 3pm - trapee.hours = vexi.string.parseInt(3>l?s0:s0.substring(0,l==3?1:2), 10); - trapee.mins = 3>l?0:vexi.string.parseInt(s0.substring(l==3?1:2), 10); - if (12>trapee.hours and pm) { - trapee.hours += 12; - } - } else { - var h = vexi.string.parseInt(s0, 10); - var m = vexi.string.parseInt(s1, 10); - //var s = vexi.string.parseInt(s2, 10); - // sanitize values - if (h==24 or 0>h) h = 0; - if (h>23) h = 23; - if (m>59) m = 59; - if (0>m) m = 0; - //if (s>59) s = 59; - //if (0>s) s = 0; - // assign - trapee.hours = h; - trapee.mins = m; - //trapee.secs = s; - } - - while(trapee.mins % trapee.minsIncrement){ - trapee.mins -=1; - } - } catch (e) { throw "unsupported text value for timefield: '"+v+"'"; } - return; - } - - /** returns the time as a string */ - static.valueRead = function() { var t = trapee.text; return t ? t : null; } - - /** sets the time based on the value of v */ - static.valueWrite = function(v) { - switch (typeof(v)) { - case "null": - trapee.hours = null; - trapee.mins = null; - //secs = null; - break; - case "date": - trapee.hours = v.getHours(); - trapee.mins = v.getMinutes(); - break; - case "string": - trapee.text = v; - break; - default: - throw "unsupported value type for timefield: '"+typeof(v)+"'"; - } - return; - } - </vexi> Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/vexi/conf/settings.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/vexi/conf/settings.t 2015-10-29 18:22:44 UTC (rev 4820) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/vexi/conf/settings.t 2015-10-29 18:27:49 UTC (rev 4821) @@ -7,6 +7,6 @@ static.date_textformat = "DDMMYYYY"; static.date_valueformat = "YYYYMMDD"; - static.time_use24hours = false; + static.time_use24hours = true; </vexi> Modified: branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/timefield.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/timefield.t 2015-10-29 18:22:44 UTC (rev 4820) +++ branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/timefield.t 2015-10-29 18:27:49 UTC (rev 4821) @@ -3,11 +3,43 @@ <vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget"> <w:surface /> <ui:box orient="vertical"> - <w:timefield id="time1" /> - <w:timefield id="time2" default="00:00" loop="false"/> - <w:timefield id="time3" default="23:59" loop="false"/> - <w:timefield id="time4" default="02:00" minsIncrement="15" /> + <ui:Box shrink="true"> + <w:timefield id="time1" /> + <ui:Box shrink="true" id="value1"/> + </ui:Box> + <ui:Box shrink="true"> + <w:timefield id="time2" default="00:00" loop="false"/> + <ui:Box shrink="true" id="value2"/> + </ui:Box> + + <ui:Box shrink="true"> + <w:timefield id="time3" default="23:59" loop="false"/> + <ui:Box shrink="true" id="value3"/> + </ui:Box> + + <ui:Box shrink="true"> + <w:timefield id="time4" default="02:00" minsIncrement="15" /> + <ui:Box shrink="true" id="value4"/> + </ui:Box> + + <ui:Box shrink="true"> + <w:timefield id="time5" default="13:00" loop="false" format="12"/> + <ui:Box shrink="true" id="value5"/> + </ui:Box> + + $time1.value ++= function(v){ + trace(new vexi.js.Exception(v)); + cascade = v; $value1.text = v; + }; + $time2.value ++= function(v){ cascade = v; $value2.text = v; }; + $time3.value ++= function(v){ cascade = v; $value3.text = v; }; + $time4.value ++= function(v){ cascade = v; $value4.text = v; }; + $time5.value ++= function(v){ cascade = v; $value5.text = v; }; + + + + vexi.ui.frame = thisbox; </ui:box> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn