Revision: 3594
http://vexi.svn.sourceforge.net/vexi/?rev=3594&view=rev
Author: clrg
Date: 2009-08-10 11:24:48 +0000 (Mon, 10 Aug 2009)
Log Message:
-----------
Box clean up + Leave related fixes
- Leave not called when unassigned from parent
- Leave not called when undisplayed
- fixes inconsistent widget states caused by clear(MOUSEINSIDE) without calling
Leave
- need to implement MOUSEINSIDE/Enter checking in place()
- other clean up / comments
Modified Paths:
--------------
trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp
Modified: trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2009-08-10 10:32:26 UTC
(rev 3593)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2009-08-10 11:24:48 UTC
(rev 3594)
@@ -339,7 +339,7 @@
private final void dirtyInPlace(boolean clean) { if (clean) { dirty();
clear(PLACE_CLEAN); } }
private final void dirty() { dirty(0, 0, width, height); }
private final void dirty(int x, int y, int w, int h) {
- for(Box cur = this; cur != null; cur = cur.parent) {
+ for (Box cur = this; cur != null; cur = cur.parent) {
if (!cur.test(DISPLAY)) return;
x = max(x, 0);
y = max(y, 0);
@@ -348,10 +348,13 @@
if (w <= 0 || h <= 0) return;
// get around sub-sampling of enlarged textures
if (cur.texture != null && !cur.test(TILE_IMAGE)) {
- // FIXME: inefficient but otherwise the consistency of
+ // REMARK: inefficient but otherwise the consistency of
// translating enlarged pixels to on-screen coordinates
// can not be guarranteed as it depends upon first
// rendering the image at the full size of its box
+ // FIXME: this is the wrong place to do this - should
+ // prerender enlarged image at time of render and then
+ // just paint the relevant part of the enlarged image
x = 0; y = 0; w = cur.width; h = cur.height;
}
// x and y have a different meaning on the root box
@@ -527,7 +530,7 @@
//#repeat width/height WIDTH/HEIGHT
if (test(CLIP)) {
- if ( newwidth < maxwidth && newwidth < minwidth)
+ if (newwidth < maxwidth && newwidth < minwidth)
set(HAS_WIDTH_SLACK);
else clear(HAS_WIDTH_SLACK);
} else {
@@ -996,9 +999,9 @@
throw new JSExn("Attempt to set minwidth to a value outside the
range 0-"+MAX_DIMENSION);
if (firetraps && test(MINWIDTH_TRAP)) {
Trap t = wtrap(SC_minwidth);
- // FIXME: investigate this
- //if (t==null && test(MINWIDTH_TRAP))
- // System.err.println("Should not happen, MINWIDTH_TRAP set and
t==null");
+ // FIXME: verify / investigate this or delete it if not reported
+ if (t==null && test(MINWIDTH_TRAP))
+ Log.uWarn(this, "Should not happen, MINWIDTH_TRAP set and
t==null");
if (t!=null) {
this.minwidth = JSU.toInt(Main.SCHEDULER.runBeforePut(t,
JSU.N(minwidth)));
Main.SCHEDULER.runAfterPut(null);
@@ -1019,9 +1022,9 @@
throw new JSExn("Attempt to set maxwidth to a value outside the
range 0-"+MAX_DIMENSION);
if (firetraps && test(MAXWIDTH_TRAP)) {
Trap t = wtrap(SC_maxwidth);
- // FIXME: investigate this
- //if (t==null && test(MAXWIDTH_TRAP))
- // System.err.println("Should not happen, MAXWIDTH_TRAP set and
t==null");
+ // FIXME: verify / investigate this or delete it if not reported
+ if (t==null && test(MAXWIDTH_TRAP))
+ Log.uWarn(this, "Should not happen, MAXWIDTH_TRAP set and
t==null");
if (t!=null) {
this.maxwidth = JSU.toInt(Main.SCHEDULER.runBeforePut(t,
JSU.N(maxwidth)));
Main.SCHEDULER.runAfterPut(null);
@@ -1121,10 +1124,14 @@
/** clear flag MOUSEINSIDE on self and descendents and fire Leave traps */
private final void propagateLeave() throws JSExn {
- clear(MOUSEINSIDE);
+ if (!test(MOUSEINSIDE)) return;
int i = treeSize()-1;
for (Box b = getChild(i); b != null; b = getChild(--i))
- if (b.test(MOUSEINSIDE)) b.propagateLeave();
+ b.propagateLeave();
+ // REMARK: clear after calling leave on children because
+ // they may throw an exception which would leave this box
+ // in an inconsistent state (!mouse.inside but no Leave)
+ clear(MOUSEINSIDE);
if (test(LEAVE_TRAP)) justTriggerTraps(SC_Leave, JSU.T);
}
@@ -1139,15 +1146,15 @@
// start with pre-event _Move which preceeds Enter/Leave
if (test(_MOVE_TRAP)) {
if (Interpreter.CASCADE_PREVENTED == justTriggerTraps(SC__Move,
JSU.T)) {
- // _Move cascade prevented induces Leave
- if (test(MOUSEINSIDE)) propagateLeave();
+ // _Move cascade prevention induces Leave
+ propagateLeave();
// propagate cascade prevention
return true;
}
}
// REMARK: anything from here on in is a partial interruption relative
- // to the this box so we can not call propagateLeave directly upon it
+ // to this box so we can not call propagateLeave() directly upon it
int i;
boolean interrupted = false;
@@ -1157,8 +1164,9 @@
int b_mx = mousex-getXInParent(b);
int b_my = mousey-getYInParent(b);
if (!interrupted && b.inside(b_mx, b_my)) {
- if (b.propagateMove(b_mx, b_my)) interrupted = true;
- } else if (b.test(MOUSEINSIDE)) b.propagateLeave();
+ if (b.propagateMove(b_mx, b_my))
+ interrupted = true;
+ } else b.propagateLeave();
}
// packed layout - siblings can not interrupt each other
@@ -1166,9 +1174,10 @@
for (Box b = getChild(i=0); b != null; b = getChild(++i)) {
int b_mx = mousex-b.x;
int b_my = mousey-b.y;
- if (!interrupted && b.inside(b_mx, b_my)) {
- if (b.propagateMove(b_mx, b_my)) interrupted = true;
- } else if (b.test(MOUSEINSIDE)) b.propagateLeave();
+ if (b.inside(b_mx, b_my)) {
+ if (b.propagateMove(b_mx, b_my))
+ interrupted = true;
+ } else b.propagateLeave();
}
}
@@ -1277,18 +1286,18 @@
private class Mouse extends JS.Immutable implements JS.Cloneable {
public JS get(JS key) throws JSExn {
//#switch (JSU.toString(key))
- /*...@page(varname=mouse,humanname=Mouse Object)
- * <p>The Mouse Object, accessed via the Box.mouse property, is
immutable - that is you
- * may not modify or add properties to this object. However
traps can be placed upon
- * the object's properties.</p>
- *
- * <p>Note that every time you access the Box.mouse property,
it creates a different
- * object. </p>
- * */
- /* <em>Read only</em></span> property representing whether the
mouse cursor is within
- * the bounds of the owning box.
- *
- * @type(Boolean) */
+ /*...@page(varname=mouse,humanname=Mouse Object)
+ * <p>The Mouse Object, accessed via the Box.mouse property, is
immutable - that is you
+ * may not modify or add properties to this object. However traps
can be placed upon
+ * the object's properties.</p>
+ *
+ * <p>Note that every time you access the Box.mouse property, it
creates a different
+ * object. </p>
+ * */
+ /* <em>Read only</em></span> property representing whether the
mouse cursor is within
+ * the bounds of the owning box.
+ *
+ * @type(Boolean) */
case "inside": return JSU.B(test(MOUSEINSIDE) && isVisible());
/* <em>Read only</em></span> property representing the mouse's
current x-position/y-position
* relative to the owning box.
@@ -1305,32 +1314,30 @@
/** the distance between two boxes top-left corners */
private class DistanceTo extends JS.Immutable implements JS.Cloneable {
-
-
private Box from;
private Box to;
DistanceTo(Box from, Box to) { this.from = from; this.to = to; }
public JS get(JS key) throws JSExn {
//#switch (JSU.toString(key))
- /*...@page(varname=distanceto,humanname=DistanceTo Object)
- * <p>The DistanceTo Object, returned via the
Box.distanceto(Box) function, is mostly
- * immutable - that is you may not modify or add properties to
this object, with the
- * exception of the properties 'from' and 'to'. However traps
can be placed upon the
- * object's properties.</p>
- *
- * <p>Note that every time you use the Box.distanceto(Box)
function, it creates a
- * different object. </p>
- * */
- /* The originating box. @type(Box) */
+ /*...@page(varname=distanceto,humanname=DistanceTo Object)
+ * <p>The DistanceTo Object, returned via the Box.distanceto(Box)
function, is mostly
+ * immutable - that is you may not modify or add properties to
this object, with the
+ * exception of the properties 'from' and 'to'. However traps can
be placed upon the
+ * object's properties.</p>
+ *
+ * <p>Note that every time you use the Box.distanceto(Box)
function, it creates a
+ * different object. </p>
+ * */
+ /* The originating box. @type(Box) */
case "from": return from;
/* The target box. @type(Box) */
case "to": return to;
/* <em>Read only</em> property representing the horizontal
distance between target
- * box\x92s (0,0) coordinate and the originating box\x92s (0,0)
coordinate.
+ * box�s (0,0) coordinate and the originating box�s (0,0)
coordinate.
* @type(Number) */
case "x": return JSU.N(localToGlobalX(to, 0) -
localToGlobalX(from, 0));
/* <em>Read only</em> property representing the vertical distance
between target
- * box\x92s (0,0) coordinate and the originating box\x92s (0,0)
coordinate.
+ * box�s (0,0) coordinate and the originating box�s (0,0)
coordinate.
* @type(Number) */
case "y": return JSU.N(localToGlobalY(to, 0) -
localToGlobalY(from, 0));
//#end
@@ -1375,9 +1382,13 @@
}
case "indexof":
try {
+ // FIXME: test for numchildren trap on redirects
Box b = (Box)args[0];
- if (b.parent != this)
- return (redirect==null || redirect==this) ?
JSU.N(-1) : redirect.callMethod(null, method, args);
+ Box p = this;
+ while (b.parent != p) {
+ if (p.redirect==null || p.redirect==p) return
JSU.N(-1);
+ p = p.redirect;
+ }
return JSU.N(b.getIndexInParent());
} catch (ClassCastException cce) {
throw new JSExn("Cannot call Box."+method+"() with
non-box argument");
@@ -1442,21 +1453,21 @@
* */
/*****************************************************************************************/
/*...@section(Rendering) The rendering properties affect what the box
looks like visually.*/
- case "fill": if (texture == null) return
JSU.S(Color.colorToString(fillcolor)); return texture.stream;
- /* <p>When an object is written to this property, its stream is
read using the
- * <a href="http://www.freetype.org/" target="_top">freetype2
library</a>, and the
- * resulting font is used to render the box's text.</p>
- *
- * @type(Stream)
- * @initial_value(vexi.ui.font.vera)
- * @nofollow */
- case "font": return text.font.stream;
- /* <p>The size (in points) to render the text.</p>
- *
- * @type(Number)
- * @initial_value(10)
- * */
- case "fontsize": return Text.sizeToJS(text.pointsize);
+ case "fill": if (texture == null) return
JSU.S(Color.colorToString(fillcolor)); return texture.stream;
+ /* <p>When an object is written to this property, its stream is read
using the
+ * <a href="http://www.freetype.org/" target="_top">freetype2
library</a>, and the
+ * resulting font is used to render the box's text.</p>
+ *
+ * @type(Stream)
+ * @initial_value(vexi.ui.font.vera)
+ * @nofollow */
+ case "font": return text.font.stream;
+ /* <p>The size (in points) to render the text.</p>
+ *
+ * @type(Number)
+ * @initial_value(10)
+ * */
+ case "fontsize": return Text.sizeToJS(text.pointsize);
/*
* The text of a box. Visually null renders the same as the text to ""
(i.e as nothing).
*
@@ -1949,6 +1960,7 @@
// force dirty in case parent size/position do not change
dirty();
clear(DISPLAY);
+ propagateLeave();
}
// fire post-cascade visible traps
if (trapchain!=null) trapchain.finishTraps();
@@ -2339,8 +2351,8 @@
if (newparent != null) {
if (i<0) throw new JSExn("Illegal attempt to set the parent of a
box");
}
- // FIXME handle Enter/Leave better
- clear(MOUSEINSIDE);
+ // FIXME: test for Enter (but put where? in place()?)
+ propagateLeave();
final boolean wasvisible = isVisible();
final JS oldsurface = getSurfaceObject(oldparent);
final JS newsurface = getSurfaceObject(newparent);
@@ -2380,8 +2392,8 @@
private void put(int i, JS value) throws JSExn{ put(i,value,true,true); }
/**
- * @param hasNewParent - if a child has a new parent and a previous parent
then
- * it is being moved from the old to the new. In this case we only want to
+ * @param fireTrapsOnRemove - if a child has a new parent and a previous
parent
+ * then it is being moved from the old to the new. In this case we only
want to
* fire visible,surface,enter/leave traps once so it is not the same as
* removing and then adding in discrete steps.
*
@@ -2492,5 +2504,5 @@
// JSArrayLike
public JS getElement(int i) throws JSExn { return get(i); }
public JS[] toArray() throws JSExn { throw new JSExn("Cannot convert box
to an array"); }
- public int length() throws JSExn{ return
JSU.toInt(getAndTriggerTraps(SC_numchildren)); }
+ public int length() throws JSExn { return
JSU.toInt(getAndTriggerTraps(SC_numchildren)); }
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn