1
0
Fork 0

Merge branch 'master' of gitorious.org:fg/fgdata

This commit is contained in:
Hal V. Engel 2014-06-25 21:19:31 -07:00
commit 0f692bf89c
11 changed files with 765 additions and 269 deletions

View file

@ -550,6 +550,7 @@ var Map = {
layer.update();
}
printlog(_MP_dbg_lvl, "Took "~((systime()-t)*1000)~"ms to update map()");
me.setBool("update", 1); # update any coordinates that changed, to avoid floating labels etc.
return me;
},
};

View file

@ -1,7 +1,14 @@
var gui = {
widgets: {},
focused_window: nil,
region_highlight: nil
region_highlight: nil,
# Window/dialog stacking order
STACK_INDEX: {
"default": 0,
"always-on-top": 1,
"tooltip": 2
}
};
var gui_dir = getprop("/sim/fg-root") ~ "/Nasal/canvas/gui/";
@ -226,7 +233,7 @@ var Window = {
{
# on writing the z-index the window always is moved to the top of all other
# windows with the same z-index.
me.setInt("z-index", me.get("z-index", 0));
me.setInt("z-index", me.get("z-index", gui.STACK_INDEX["default"]));
me.setFocus();
},

View file

@ -122,7 +122,11 @@ gui.Widget = {
},
# protected:
_MAX_SIZE: 32768, # size for "no size-limit"
_onStateChange: func {},
_onStateChange: func
{
if( me._view != nil and me._view.update != nil )
me._view.update(me);
},
_setView: func(view)
{
me._view = view;

View file

@ -117,7 +117,7 @@ var MessageBox = {
vbox.addSpacing(MARGIN);
var w = vbox.sizeHint()[0];
var w = math.max(300, vbox.sizeHint()[0]);
dlg.setSize(w, math.max(130, vbox.heightForWidth(w)));
return me;

View file

@ -203,22 +203,28 @@ DefaultStyle.widgets.label = {
}
me._createElement("text", "text")
.set("text", text)
.set("fill", "black");
.set("text", text);
var hfw_func = nil;
var min_width = me._text.maxWidth() + 4;
var width_hint = min_width;
if( model._cfg.get("wordWrap", 0) )
{
var m = me;
model.setHeightForWidthFunc(func(w) m.heightForWidth(w));
}
else
{
var min_width = me._text.maxWidth() + 4;
model.setMinimumSize([min_width, 14]);
model.setSizeHint([min_width, 24]);
hfw_func = func(w) m.heightForWidth(w);
min_width = math.min(32, min_width);
# prefer approximately quadratic text blocks
if( width_hint > 24 )
width_hint = int(math.sqrt(width_hint * 24));
}
return me;
model.setHeightForWidthFunc(hfw_func);
model.setMinimumSize([min_width, 14]);
model.setSizeHint([width_hint, 24]);
return me.update(model);
},
setImage: func(model, img)
{
@ -250,6 +256,14 @@ DefaultStyle.widgets.label = {
return math.max(14, me._text.heightForWidth(w - 4));
},
update: func(model)
{
if( me['_text'] != nil )
{
var color_name = model._windowFocus() ? "fg_color" : "backdrop_fg_color";
me._text.set("fill", me._style.getColor(color_name));
}
},
# protected:
_createElement: func(name, type)
{
@ -303,14 +317,16 @@ DefaultStyle.widgets["scroll-area"] = {
me.horiz.reset();
if( model._max_scroll[0] > 1 )
# only show scroll bar if horizontally scrollable
me.horiz.moveTo(model._scroll_pos[0], model._size[1] - 2)
.horiz(model._size[0] - model._max_scroll[0]);
me.horiz.moveTo( model._scroller_offset[0] + model._scroller_pos[0],
model._size[1] - 2 )
.horiz(model._scroller_size[0]);
me.vert.reset();
if( model._max_scroll[1] > 1 )
# only show scroll bar if vertically scrollable
me.vert.moveTo(model._size[0] - 2, model._scroll_pos[1])
.vert(model._size[1] - model._max_scroll[1]);
me.vert.moveTo( model._size[0] - 2,
model._scroller_offset[1] + model._scroller_pos[1] )
.vert(model._scroller_size[1]);
me._bg.reset()
.rect(0, 0, model._size[0], model._size[1]);
@ -325,5 +341,23 @@ DefaultStyle.widgets["scroll-area"] = {
return el.createChild("path", "scroll-" ~ orient)
.set("stroke", "#f07845")
.set("stroke-width", 4);
},
# Calculate size and limits of scroller
#
# @param model
# @param dir 0 for horizontal, 1 for vertical
# @return [scroller_size, min_pos, max_pos]
_updateScrollMetrics: func(model, dir)
{
if( model._content_size[dir] <= model._size[dir] )
return;
model._scroller_size[dir] =
math.max(
12,
model._size[dir] * (model._size[dir] / model._content_size[dir])
);
model._scroller_offset[dir] = 0;
model._scroller_delta[dir] = model._size[dir] - model._scroller_size[dir];
}
};

View file

@ -54,11 +54,6 @@ gui.widgets.Button = {
return me;
},
# protected:
_onStateChange: func
{
if( me._view != nil )
me._view.update(me);
},
_setView: func(view)
{
var el = view._root;

View file

@ -4,9 +4,9 @@ gui.widgets.ScrollArea = {
var cfg = Config.new(cfg);
var m = gui.Widget.new(gui.widgets.ScrollArea);
m._focus_policy = m.NoFocus;
m._scroll_pos = [0,0];
m._content_pos = [0, 0];
m._scroller_pos = [0, 0];
m._max_scroll = [0, 0];
m._content_size = [0, 0];
m._layout = nil;
if( style != nil )
@ -49,73 +49,58 @@ gui.widgets.ScrollArea = {
if( me._layout != nil )
me._layout.setGeometry(me._layout.geometry());
},
# Move the scrollbars to the coordinates x,y (or as far as possible) and
# update.
# Move contents to the coordinates x,y (or as far as possible)
#
# @param x The x coordinate (positive is right)
# @param y The y coordinate (positive is down)
moveTo: func(x, y)
scrollTo: func(x, y)
{
var bb = me._updateBB();
me._scroll_pos[0] = math.max(0, math.min(x, me._max_scroll[0]));
me._scroll_pos[1] = math.max(0, math.min(y, me._max_scroll[1]));
me.update(bb);
},
# Move the scrollable area to the top-most position and update.
moveToTop: func()
{
me._scroll_pos[1] = 0;
me._content_pos[0] = x;
me._content_pos[1] = y;
me.update();
},
# Move the scrollable area to the bottom-most position and update.
moveToBottom: func()
# Move the scrollable area to the top-most position
scrollToTop: func me.scrollTo( me._content_pos[0], 0 ),
# Move the scrollable area to the bottom-most position
scrollToBottom: func me.scrollTo( me._content_pos[0], me._max_scroll[1] ),
# Move the scrollable area to the left-most position
scrollToLeft: func me.scrollTo( 0, me._content_pos[1] ),
# Move the scrollable area to the right-most position
scrollToRight: func me.scrollTo( me._max_scroll[0], me._content_pos[1] ),
# Move content by given delta
scrollBy: func(x, y)
{
var bb = me._updateBB();
me._scroll_pos[1] = me._max_scroll[1];
me.update(bb);
return me.scrollTo( me._content_pos[0] + x,
me._content_pos[1] + y );
},
# Move the scrollable area to the left-most position and update.
moveToLeft: func()
# Set horizontal scrollbar position
horizScrollBarTo: func(x)
{
me._scroll_pos[0] = 0;
if( me._scroller_delta[0] < 1 )
return me;
me.update();
me.scrollTo( me._max_scroll[0] * (x / me._scroller_delta[0]),
me._content_pos[1] );
},
# Move the scrollable area to the right-most position and update.
moveToRight: func()
# Set vertical scrollbar position
vertScrollBarTo: func(y)
{
var bb = me._updateBB();
if( me._scroller_delta[1] < 1 )
return me;
me._scroll_pos[0] = me._max_scroll[0];
me.update(bb);
me.scrollTo( me._content_pos[0],
me._max_scroll[1] * (y / me._scroller_delta[1]) );
},
# Get position of scrollable content
getContentPosition: func()
# Move horizontal scrollbar by given offset
horizScrollBarBy: func(dx)
{
var pos = [0, 0];
if( me._max_scroll[0] > 1 )
pos[0] = (me._scroll_pos[0] / me._max_scroll[0])
* (me._content_size[0] - me._size[0]);
if( me._max_scroll[1] > 1 )
pos[1] = (me._scroll_pos[1] / me._max_scroll[1])
* (me._content_size[1] - me._size[1]);
return pos;
me.horizScrollBarTo(me._scroller_pos[0] + dx);
},
# Move content to the given position
moveContentTo: func(x, y)
# Move vertical scrollbar by given offset
vertScrollBarBy: func(dy)
{
var scroll_x = x / (me._content_size[0] - me._size[0]) * me._max_scroll[0];
var scroll_y = y / (me._content_size[1] - me._size[1]) * me._max_scroll[1];
return me.moveTo(scroll_x, scroll_y);
me.vertScrollBarTo(me._scroller_pos[1] + dy);
},
# Update scroll bar and content area.
#
@ -125,9 +110,8 @@ gui.widgets.ScrollArea = {
if (bb == nil) bb = me._updateBB();
if (bb == nil) return me;
var pos = me.getContentPosition();
var offset = [ me._content_offset[0] - pos[0],
me._content_offset[1] - pos[1] ];
var offset = [ me._content_offset[0] - me._content_pos[0],
me._content_offset[1] - me._content_pos[1] ];
me.getContent().setTranslation(offset);
me._view.update(me);
@ -142,9 +126,8 @@ gui.widgets.ScrollArea = {
view.horiz.addEventListener("mousedown", func(e) me._dragStart(e));
view._root.addEventListener("mousedown", func(e)
{
var pos = me.getContentPosition();
me._drag_offsetX = pos[0] + e.clientX;
me._drag_offsetY = pos[1] + e.clientY;
me._drag_offsetX = me._content_pos[0] + e.clientX;
me._drag_offsetY = me._content_pos[1] + e.clientY;
});
view.vert.addEventListener
@ -155,7 +138,7 @@ gui.widgets.ScrollArea = {
if( !me._enabled )
return;
me.moveTo(me._scroll_pos[0], me._drag_offsetY + e.clientY);
me.vertScrollBarTo(me._drag_offsetY + e.clientY);
e.stopPropagation();
}
);
@ -167,7 +150,7 @@ gui.widgets.ScrollArea = {
if( !me._enabled )
return;
me.moveTo(me._drag_offsetX + e.clientX, me._scroll_pos[1]);
me.horizScrollBarTo(me._drag_offsetX + e.clientX);
e.stopPropagation();
}
);
@ -180,8 +163,8 @@ gui.widgets.ScrollArea = {
if( !me._enabled )
return;
me.moveContentTo( me._drag_offsetX - e.clientX,
me._drag_offsetY - e.clientY );
me.scrollTo( me._drag_offsetX - e.clientX,
me._drag_offsetY - e.clientY );
e.stopPropagation();
}
);
@ -193,7 +176,7 @@ gui.widgets.ScrollArea = {
if( !me._enabled )
return;
me.moveTo(me._scroll_pos[0], me._scroll_pos[1] - e.deltaY);
me.scrollBy(0, 30 * -e.deltaY); # TODO make step size configurable
e.stopPropagation();
}
);
@ -202,8 +185,8 @@ gui.widgets.ScrollArea = {
},
_dragStart: func(e)
{
me._drag_offsetX = me._scroll_pos[0] - e.clientX;
me._drag_offsetY = me._scroll_pos[1] - e.clientY;
me._drag_offsetX = me._scroller_pos[0] - e.clientX;
me._drag_offsetY = me._scroller_pos[1] - e.clientY;
e.stopPropagation();
},
_updateBB: func()
@ -238,23 +221,34 @@ gui.widgets.ScrollArea = {
me._content_offset = [0, 0];
}
if( w > me._size[0] )
{
var scroller_size = math.max(12, me._size[0] * (me._size[0] / w));
me._max_scroll[0] = me._size[0] - scroller_size;
}
else
me._max_scroll[0] = 0;
me._max_scroll[0] = math.max(0, w - me._size[0]);
me._max_scroll[1] = math.max(0, h - me._size[1]);
me._content_size = [w, h];
if( h > me._size[1] )
{
var scroller_size = math.max(12, me._size[1] * (me._size[1] / h));
me._max_scroll[1] = me._size[1] - scroller_size;
}
else
me._max_scroll[1] = 0;
# keep position within limit and only integer (to prevent artifacts on text,
# lines, etc. not alligned with pixel grid)
me._content_pos[0] =
math.max(0, math.min( math.round(me._content_pos[0]), me._max_scroll[0]));
me._content_pos[1] =
math.max(0, math.min( math.round(me._content_pos[1]), me._max_scroll[1]));
me._content_size[0] = w;
me._content_size[1] = h;
me._scroller_size = [0, 0]; # scroller size
me._scroller_offset = [0, 0]; # scroller minimum pos (eg. add offset for
# scrolling with buttons)
me._scroller_delta = [0, 0]; # scroller max travel distance
# update scroller size/offset/max delta
me._view._updateScrollMetrics(me, 0);
me._view._updateScrollMetrics(me, 1);
# update current scrollbar positions
me._scroller_pos[0] =
me._max_scroll[0] > 0
? (me._content_pos[0] / me._max_scroll[0]) * me._scroller_delta[0]
: 0;
me._scroller_pos[1] =
me._max_scroll[1] > 0
? (me._content_pos[1] / me._max_scroll[1]) * me._scroller_delta[1]
: 0;
}
};

View file

@ -15,7 +15,7 @@
id="svg14394"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="ifragrupados.svg.2014_05_08_22_51_22.0.svg">
sodipodi:docname="ifragrupados.svg">
<defs
id="defs14396">
<pattern
@ -159,9 +159,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.22627419"
inkscape:cx="-952.08538"
inkscape:cy="-1556.6103"
inkscape:zoom="1.2800001"
inkscape:cx="388.15373"
inkscape:cy="-4014.0798"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@ -219,7 +219,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -248295,5 +248295,436 @@
width="1291.364"
id="rect33552"
style="color:#000000;fill:none;stroke:#000000;stroke-width:2.10591412;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
transform="matrix(2.063556,0,0,2.063556,-328.70951,-28619.917)"
id="g37580"
inkscape:export-filename="/home/michat/Documentos/TRABAJOS/FGMapSymbols/IFR/missionsamples/vfrbarcelona.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<g
id="g37582">
<path
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccc"
inkscape:connector-curvature="0"
id="path37584"
d="m 104.64348,15345.672 -2.45152,-1.073 -2.757963,-1.072 -0.536272,-0.766 -0.229828,-1.379 2.374913,-11.108 -3.141014,-1.839 0,-0.192 1.45559,-0.153 0.727794,0 0.19153,-0.383 -0.15322,-0.421 -0.383053,-0.23 -1.915252,0.04 -0.766101,-4.712 0.153222,4.865 -0.919322,0.422 -0.497965,0.459 -0.574575,0.881 -0.03833,0.69 0.229828,0.804 0.459662,0.422 0.881015,0.421 0.842711,0.153 0.363899,1.475 1.647116,-1.092 -2.857121,12.318 1.300115,0.406 1.273027,0.434 1.435554,0.433 1.30011,0.244 2.01383,0 c 0.32112,-0.02 0.23111,0.05 0.57162,-0.06 z"
style="fill:none;stroke:#000000;stroke-width:0.52600002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37586"
d="m 97.079256,15328.57 -0.796766,0.975 -0.05901,0.235 0.383628,0.468 0.383632,0.234 0.442647,0 0.05901,-0.742 z"
style="fill:none;stroke:#000000;stroke-width:0.15787433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path37588"
d="m 97.841263,15329.177 0.02628,1.232 0.210384,0.177 1.534928,-0.05 c -0.275064,-0.513 -0.995772,-0.941 -1.771592,-1.359 z"
style="fill:none;stroke:#000000;stroke-width:0.34508607;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path37590"
d="m 97.949597,15331.539 c 0.0394,0.587 0.01345,1.039 -0.04105,1.432 l 1.773594,-1.217 0.07067,-0.444 -0.572207,0.208 -0.553965,0.05 z"
style="fill:none;stroke:#000000;stroke-width:0.36161014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37592"
d="m 97.890676,15330.354 0.03832,1.398 z"
style="fill:none;stroke:#000000;stroke-width:0.226;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path37595"
d="m 97.758069,15331.531 c -0.288811,-0.704 -0.565757,-3.754 -0.122442,-2.827 0.167994,-0.103 0.160683,1.874 0.122442,2.827 z"
style="fill:none;stroke:#000000;stroke-width:0.75297028;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37597"
d="m 97.155535,15328.477 0.744857,-0.257 z"
style="fill:none;stroke:#000000;stroke-width:0.52600002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37599"
d="m 96.99302,15328.639 0.203145,-0.176 z"
style="fill:none;stroke:#000000;stroke-width:0.52600002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37601"
d="m 97.087822,15328.571 0.446915,0.244 1.625141,0.935 0.501087,0.487 0.297947,0.569 0.08126,0.502 -0.04062,0.582 -1.801202,7.909 -0.05417,0.623 -0.02706,0.853 0.189598,0.717 0.474004,0.867 0.636514,0.678 -0.648748,-0.69 -0.462053,-0.855 -0.189133,-0.715 0.02631,-0.877 0.05268,-0.606 1.802729,-7.902 0.03832,-0.604 -0.0814,-0.488 -0.292076,-0.558 -0.502752,-0.49 z"
style="fill:none;stroke:#000000;stroke-width:0.126;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="ccccccccccccc"
inkscape:connector-curvature="0"
id="path37603"
d="m 96.197221,15329.478 -0.07661,0.144 -0.0096,0.259 0.08619,0.239 0.220258,0.259 0.287288,0.172 0.411777,0.173 0.325591,0.04 0.124495,0.01 0.206196,-2.181 -0.704161,-0.02 -0.794828,0.7 z"
style="fill:none;stroke:#000000;stroke-width:0.52600002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path37605"
d="m 98.07417,15330.743 1.570504,-0.03 0.05746,0.402 -0.03833,0.201 0.01916,-0.211 -0.06703,-0.382 z"
style="fill:none;stroke:#000000;stroke-width:0.52600002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path37607"
d="m 97.57882,15327.419 -0.190916,-1.008 z"
style="fill:none;stroke:#000000;stroke-width:0.67407686px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path37609"
sodipodi:cx="348.73691"
sodipodi:cy="9472.8633"
sodipodi:rx="7.2593026"
sodipodi:ry="4.3555818"
d="m 354.17614,9469.9788 c 2.65512,1.8024 2.37229,4.5549 -0.63171,6.148 -3.004,1.5931 -7.59163,1.4234 -10.24675,-0.379 -2.65512,-1.8024 -2.3723,-4.555 0.6317,-6.1481 0.0511,-0.027 0.10289,-0.054 0.15526,-0.08"
transform="matrix(1.0696545,-0.07480177,0.08048802,1.150967,-1034.7489,4467.7039)"
sodipodi:start="5.5593584"
sodipodi:end="10.299944"
sodipodi:open="true" />
<path
style="fill:#000000;stroke:#000000;stroke-width:0.14088933;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 106.46576,15345.303 1.74444,0.19 0.15352,0.416 -4.25711,0 c 0.39112,-0.137 0.70586,-0.28 0.68943,-0.358 z"
id="path37611"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="fill:#000000;stroke:none"
d="m 106.67842,15341.149 c 1.68567,3.701 -5.33965,2.441 -7.304531,2.188 2.635691,0.973 4.991151,2.899 8.060761,2.396 l 0.2838,0.287 0.35581,-0.857 0.13684,-1.13 -0.10948,-0.701 -0.41054,-1.13 -0.84845,-1.091 z"
id="path37613"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
<g
transform="translate(-204.40669,-1173.5333)"
id="g20678">
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path11857"
d="m 352.48043,4613.7447 65.19326,-66.6085 0.0914,11.9183 -65.10458,54.5759 65.10458,-54.5759 11.7018,0.064 z"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path11869"
d="m 418.3313,4559.3777 -58.58902,48.8005 69.34449,-48.777 z"
style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g12725"
transform="translate(-244.35826,-1173.5333)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 392.43196,4541.6198 65.19326,-66.6085 0.0943,11.8876 -65.10744,54.6066 65.10172,-54.5451 11.70466,0.033 z"
id="path12663"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<rect
y="4477.8525"
x="454.3161"
height="11.490223"
width="1"
id="rect12665"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12667"
width="1"
height="11.004086"
x="451.39093"
y="4480.769" />
<rect
y="4483.6646"
x="448.46576"
height="10.650534"
width="1"
id="rect12669-5"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12671-5"
width="1"
height="9.9434271"
x="445.54059"
y="4486.6694" />
<rect
y="4489.6748"
x="442.61542"
height="9.4572916"
width="1"
id="rect12674"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12676"
width="1"
height="8.8827667"
x="439.69025"
y="4492.6802" />
<rect
y="4495.73"
x="436.76508"
height="8.3082428"
width="1"
id="rect12678"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12680"
width="1"
height="7.7779126"
x="433.8399"
y="4498.647" />
<rect
y="4501.7847"
x="430.91473"
height="7.3801651"
width="1"
id="rect12682"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12684"
width="1"
height="6.6288638"
x="427.98953"
y="4504.79" />
<rect
y="4507.5742"
x="425.06436"
height="6.363699"
width="1"
id="rect12686"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12688"
width="1"
height="5.6565924"
x="422.13919"
y="4510.7124" />
<rect
y="4513.6738"
x="419.21402"
height="5.1262627"
width="1"
id="rect12690"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12692"
width="1"
height="4.5075436"
x="416.28885"
y="4516.7671" />
<rect
y="4519.6978"
x="413.36368"
height="4.0214076"
width="1"
id="rect12694"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12696"
width="1"
height="3.4026892"
x="410.43851"
y="4522.7803" />
<rect
y="4525.7314"
x="407.51334"
height="2.9607475"
width="1"
id="rect12698"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12700"
width="1"
height="2.4746118"
x="404.58817"
y="4528.6577" />
<rect
y="4531.4575"
x="401.66299"
height="2.0371118"
width="1"
id="rect12723-1"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 213.3584,3446.3963 11.7018,0.064 -76.9865,54.6264 65.1933,-66.6085 0.091,11.9183 z m -21.2634,17.8508 -43.8412,36.7251 43.8412,-36.7251"
id="path12749"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<g
id="g28854"
transform="translate(-835.93743,19.531248)">
<path
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 996.6018,5070.9763 65.1933,-66.6085 0.091,11.9183 -65.10462,54.5759 65.10462,-54.5759 11.7018,0.064 z"
id="path28757"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:#ffffff;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 1062.4527,5016.6093 -58.5891,48.8005 69.3445,-48.777 z"
id="path28759"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<g
id="g28830"
transform="translate(-852.39505,33.974268)">
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path28764"
d="m 996.60176,4998.8514 65.19324,-66.6085 0.094,11.8876 -65.10742,54.6066 65.10172,-54.5451 11.7047,0.033 z"
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28766"
width="1"
height="11.490223"
x="1058.486"
y="4935.084" />
<rect
y="4938.0005"
x="1055.5608"
height="11.004086"
width="1"
id="rect28768"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28771"
width="1"
height="10.650534"
x="1052.6356"
y="4940.896" />
<rect
y="4943.9009"
x="1049.7104"
height="9.9434271"
width="1"
id="rect28773"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28775"
width="1"
height="9.4572916"
x="1046.7853"
y="4946.9062" />
<rect
y="4949.9116"
x="1043.8601"
height="8.8827667"
width="1"
id="rect28777"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28779"
width="1"
height="8.3082428"
x="1040.9349"
y="4952.9614" />
<rect
y="4955.8784"
x="1038.0098"
height="7.7779126"
width="1"
id="rect28781"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28783"
width="1"
height="7.3801651"
x="1035.0846"
y="4959.0161" />
<rect
y="4962.0215"
x="1032.1593"
height="6.6288638"
width="1"
id="rect28785"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28787"
width="1"
height="6.363699"
x="1029.2341"
y="4964.8057" />
<rect
y="4967.9438"
x="1026.309"
height="5.6565924"
width="1"
id="rect28789"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28791"
width="1"
height="5.1262627"
x="1023.3839"
y="4970.9053" />
<rect
y="4973.9985"
x="1020.4587"
height="4.5075436"
width="1"
id="rect28793"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28795"
width="1"
height="4.0214076"
x="1017.5335"
y="4976.9292" />
<rect
y="4980.0117"
x="1014.6083"
height="3.4026892"
width="1"
id="rect28797"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28799"
width="1"
height="2.9607475"
x="1011.6832"
y="4982.9629" />
<rect
y="4985.8892"
x="1008.758"
height="2.4746118"
width="1"
id="rect28801"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect28803"
width="1"
height="2.0371118"
x="1005.8328"
y="4988.689" />
</g>
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path28808"
d="m 223.60532,5092.7862 11.7018,0.064 -76.98654,54.6264 65.19334,-66.6085 0.091,11.9183 z m -21.2634,17.8508 -43.84124,36.7251 43.84124,-36.7251"
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 15 MiB

After

Width:  |  Height:  |  Size: 15 MiB

View file

@ -25,6 +25,7 @@ var Tooltip = {
m.setInt("size[0]", size[0]);
m.setInt("size[1]", size[1]);
m.setBool("visible", 0);
m.setInt("z-index", gui.STACK_INDEX["tooltip"]);
m._hideTimer = maketimer(m.DELAY, m, Tooltip._hideTimeout);
m._hideTimer.singleShot = 1;

View file

@ -1,12 +1,3 @@
var nocolor = {
start: func {
me.prev = (string.color("1", "2") != "2");
string.setcolors(0);
}, end: func() {
string.setcolors(me.prev);
},
};
var _REPL_dbg_level = "debug";
#var _REPL_dbg_level = "alert";
@ -21,7 +12,7 @@ var REPL = {
operators_binary_unary: [
"~", "+", "-", "*", "/",
"!", "?", ":", ".", ",",
"<", ">", "="
"<", ">", "=", "|", "&", "^"
],
brackets: {
"(":")",
@ -100,96 +91,100 @@ var REPL = {
return 0;
},
get_input: func() {
var line = me.placement.get_line();
if (line == nil or string.trim(line) == "") return me.df_status;
var len = size(line);
if (me.current == nil)
me.current = {
line: [],
brackets: [],
level: [],
statement: nil,
statement_level: nil,
last_operator: nil,
};
for (var i=0; i<len; i+=1) {
if (string.isxspace(line[i])) continue;
if (size(me.current.level) and me._is_str_char(me.current.level[-1])) {
me.current.last_operator = nil;
if (line[i] == `\\`) {
i += 1; # skip the next character
printlog(_REPL_dbg_level, " skip backslash");
} elsif (line[i] == me.current.level[-1][0]) {
printlog(_REPL_dbg_level, "< out of string with "~me.current.level[-1]);
pop(me.current.level);
var lines = me.placement.get_line();
if (lines == nil or string.trim(lines) == "") return me.df_status;
var ls = split("\n", lines); var lines = [];
foreach (var l; ls) lines ~= split("\r", l);
foreach (var line; lines) {
var len = size(line);
if (me.current == nil)
me.current = {
line: [],
brackets: [],
level: [],
statement: nil,
statement_level: nil,
last_operator: nil,
};
for (var i=0; i<len; i+=1) {
if (string.isxspace(line[i])) continue;
if (size(me.current.level) and me._is_str_char(me.current.level[-1])) {
me.current.last_operator = nil;
if (line[i] == `\\`) {
i += 1; # skip the next character
printlog(_REPL_dbg_level, " skip backslash");
} elsif (line[i] == me.current.level[-1][0]) {
printlog(_REPL_dbg_level, "< out of string with "~me.current.level[-1]);
pop(me.current.level);
}
continue;
}
continue;
}
if (line[i] == `#`) {
while(i<len and line[i] != `\n` and line[i] != `\r`) i+=1;
continue;
}
if (me.current.statement != nil) {
me.current.last_operator = nil;
if (me.current.statement_level == size(me.current.level) and
(line[i] == `;` or line[i] == `,`)) {
printlog(_REPL_dbg_level, "statement ended by ;/,");
me.current.statement = nil;
me.current.statement_level = nil;
if (line[i] == `#`) {
while(i<len and line[i] != `\n` and line[i] != `\r`) i+=1;
continue;
}
if (me.current.statement != nil) {
me.current.last_operator = nil;
if (me.current.statement_level == size(me.current.level) and
(line[i] == `;` or line[i] == `,`)) {
printlog(_REPL_dbg_level, "statement ended by ;/,");
me.current.statement = nil;
me.current.statement_level = nil;
} else {
var ret = me._handle_level(me.current.level, chr(line[i]), size(me.current.line)+1);
if (ret == nil) {# error
me.current = nil;
return 0;
} elsif (me.current.statement_level > size(me.current.level)) {
printlog(_REPL_dbg_level, "statement ended by level below");
# cancel out of statement
me.current.statement = nil;
me.current.statement_level = nil;
} elsif (line[i] == `{`) {
# cancel out of looking for `;`, because we have a real block here
printlog(_REPL_dbg_level, "statement ended by braces");
me.current.statement = nil;
me.current.statement_level = nil;
}
}
continue;
} elsif (string.isalpha(line[i])) {
me.current.last_operator = nil;
foreach (var stmt; me.statement_types) {
if (substr(line, i, size(stmt)) == stmt and
(i+size(stmt) >= len
or !string.isalnum(line[i+size(stmt)])
and line[i+size(stmt)] != `_`)) {
printlog(_REPL_dbg_level, "found: "~stmt);
me.current.statement = stmt;
me.current.statement_level = size(me.current.level);
i += size(stmt)-1;
break;
}
}
} elsif (me._is_str_char(line[i])) {
me.current.last_operator = nil;
append(me.current.level, chr(line[i]));
printlog(_REPL_dbg_level, "> into string with "~me.current.level[-1]);
} else {
var ret = me._handle_level(me.current.level, chr(line[i]), size(me.current.line)+1);
if (ret == nil) {# error
me.current = nil;
me.current.last_operator = nil;
if (ret == nil) # error
return 0;
} elsif (me.current.statement_level > size(me.current.level)) {
printlog(_REPL_dbg_level, "statement ended by level below");
# cancel out of statement
me.current.statement = nil;
me.current.statement_level = nil;
} elsif (line[i] == `{`) {
# cancel out of looking for `;`, because we have a real block here
printlog(_REPL_dbg_level, "statement ended by braces");
me.current.statement = nil;
me.current.statement_level = nil;
elsif (ret == 0) {
foreach (var o; me.operators_binary_unary)
if (line[i] == o[0])
{ me.current.last_operator = o; printlog(_REPL_dbg_level, "found operator "~o); break }
}
}
continue;
} elsif (string.isalpha(line[i])) {
me.current.last_operator = nil;
foreach (var stmt; me.statement_types) {
if (substr(line, i, size(stmt)) == stmt and
(i+size(stmt) >= len
or !string.isalnum(line[i+size(stmt)])
and line[i+size(stmt)] != `_`)) {
printlog(_REPL_dbg_level, "found: "~stmt);
me.current.statement = stmt;
me.current.statement_level = size(me.current.level);
i += size(stmt)-1;
break;
}
}
} elsif (me._is_str_char(line[i])) {
me.current.last_operator = nil;
append(me.current.level, chr(line[i]));
printlog(_REPL_dbg_level, "> into string with "~me.current.level[-1]);
} else {
var ret = me._handle_level(me.current.level, chr(line[i]), size(me.current.line)+1);
me.current.last_operator = nil;
if (ret == nil) # error
return 0;
elsif (ret == 0) {
foreach (var o; me.operators_binary_unary)
if (line[i] == o[0])
{ me.current.last_operator = o; printlog(_REPL_dbg_level, "found operator "~o); break }
}
}
append(me.current.line, line);
if (me.keep_history)
append(me.history, {
type: "input",
line: line,
});
}
append(me.current.line, line);
if (me.keep_history)
append(me.history, {
type: "input",
line: line,
});
var execute = (me.current.statement == nil and me.current.last_operator == nil and !size(me.current.level));
if (execute) {
me.df_status = 0;
@ -316,8 +311,8 @@ var CanvasPlacement = {
lines_of_text: [],
history: [],
curr: 0,
coloring: {parents:[nocolor]},
completion_pos: 0,
#tabs: [], # TODO: support multiple tabs
};
m.window.set("title", "Nasal REPL Interpreter");
#debug.dump(m.window._node);
@ -327,24 +322,16 @@ var CanvasPlacement = {
m.window = nil;
m.del();
};
if (m.window_style != nil) {
m.window.setBool("resize", 1);
m.window.onResize = func() {
call(canvas.Window.onResize, nil, me);
var sz = [nil,nil];
for (var i=0; i<2; i+=1)
sz[i] = me.get("content-size[" ~ i ~ "]");
m.scroll.setSize(sz);
};
}
if (m.window_style != nil) m.window.setBool("resize", 1);
m.canvas = m.window.createCanvas()
.setColorBackground(m.colors.background);
m.group = m.canvas.createGroup("content");
m.vbox = canvas.VBoxLayout.new();
m.window.setLayout(m.vbox);
m.scroll = canvas.gui.widgets
. ScrollArea.new(m.group, canvas.style, {"size":m.size})
.move(0, 0);
.ScrollArea.new(m.group, canvas.style, {});
m.scroll.setColorBackground(m.colors.background);
m.window.addWidget(m.scroll);
m.vbox.addItem(m.scroll);
m.group = m.scroll.getContent();
m.create_msg();
m.text_group = m.group.createChild("group", "text-display");
@ -353,8 +340,10 @@ var CanvasPlacement = {
.moveTo(0, -m.padding)
.lineTo(0, -11-m.padding)
.setStrokeLineWidth(2)
.setColor(m.colors.text);
.setColor(m.colors.text)
.hide();
m.repl = REPL.new(placement:m, name:name);
# XXX: keyboard hack, needs proper GUI-integrated design
append(m.listeners, setlistener("/devices/status/keyboard/event", func(event) {
if (!event.getNode("pressed").getValue())
return;
@ -363,7 +352,6 @@ var CanvasPlacement = {
if (m.handle_key(key, event.getNode("modifier").getValues()))
keyN.setValue(-1); # drop key event
}));
m.scroll.update(); # initialize ScrollArea._max_scroll member
m.update();
append(CanvasPlacement.instances, m);
return m;
@ -374,50 +362,86 @@ var CanvasPlacement = {
foreach (var l; me.listeners)
removelistener(l);
setsize(me.listeners, 0);
forindex (var i; CanvasPlacement.instances)
if (CanvasPlacement.instances[i] == me) {
CanvasPlacement.instances[i] = CanvasPlacement.instances[-1];
pop(CanvasPlacement.instances);
break;
}
},
add_char: func(char) {
add_char: func(char, reset_view=0) {
me.reset_input_from_history();
me.input ~= chr(char);
me.text.appendText(chr(char));
if (reset_view) me.reset_view();
return nil;
},
add_text: func(text) {
add_text: func(text, reset_view=0) {
me.reset_input_from_history();
me.input ~= text;
me.text.appendText(text);
if (reset_view) me.reset_view();
return nil;
},
remove_char: func() {
remove_char: func(reset_view=0) {
me.reset_input_from_history();
me.input = substr(me.input, 0, size(me.input) - 1);
var t = me.text.get("text");
if (size(t) <= me.text.stop) return nil;
me.text.setText(substr(t, 0, size(t)-1));
if (reset_view) me.reset_view();
return t[-1];
},
clear_input: func() {
clear_input: func(reset_view=0) {
me.reset_input_from_history();
var ret = me.input;
me.input = "";
var t = me.text.get("text");
me.text.setText(substr(t, 0, me.text.stop));
if (reset_view) me.reset_view();
return ret;
},
replace_line: func(replacement, replace_input=1) {
replace_line: func(replacement, replace_input=1, reset_view=0) {
if (replace_input) me.input = replacement;
var t = me.text.get("text");
me.text.setText(substr(t, 0, me.text.stop)~replacement);
if (reset_view) me.reset_view();
return nil;
},
add_line: func(text) {
me.create_line();
add_line: func(text, reset_text=1, reset_view=0) {
me.create_line(reset_text);
me.text.appendText(text);
if (reset_view) me.reset_view();
},
new_prompt: func() {
me.add_line(">>> ");
me.text.stop = size(me.text.get("text"));
},
continue_line: func(reset_text=1) {
me.add_line("... ", reset_text);
me.text.stop = size(me.text.get("text"));
},
reset_input_from_history: func(reset_view=0) {
if (me.curr < size(me.history)) {
me.input = me.history[me.curr];
me.curr = size(me.history);
}
if (reset_view) me.reset_view();
},
reset_view: func() {
me.group.update();
me.scroll.scrollToLeft().scrollToBottom();
},
set_line_color: func(color) {
if (me.separate_lines)
# Only change colors if this is its own line
me.text.setColor(color);
},
set_line_font: func(font) {
if (me.separate_lines)
# Only change font if this is its own line
me.text.setFont(font);
},
clear: func() {
me.text.del();
foreach (var t; me.lines_of_text)
@ -427,6 +451,7 @@ var CanvasPlacement = {
me.input = "";
me.text = nil;
setsize(me.lines_of_text, 0);
me.reset_view();
},
create_msg: func() {
# Text drawing mode: text and maybe a bounding box
@ -441,7 +466,7 @@ var CanvasPlacement = {
.setColor(me.colors.text)
.setDrawMode(draw_mode)
.setMaxWidth(me.window.get("content-size[0]") - me.padding)
.setText(me.translations["help"]);
.setText(me.gettranslation("help"));
if (me.colors.text_fill != nil)
me.msg.text.setColorFill(me.colors.text_fill);
me.msg.text.update();
@ -474,16 +499,16 @@ var CanvasPlacement = {
for (var i=0; i<size(me.keys); i+=2) {
if (i) me.msg.right_col.appendText("\n");
desc = me.keys[i+1];
if (desc == nil) desc = me.translations["key-not-mapped"];
if (desc == nil) desc = me.gettranslation("key-not-mapped");
elsif (desc[-1] != `.`) desc ~= ".";
me.msg.right_col.appendText(desc);
}
},
create_line: func() {
create_line: func(reset_text=1) {
# c.f. above, in me.create_msg()
var draw_mode = canvas.Text.TEXT + (me.colors.text_fill != nil ? canvas.Text.FILLEDBOUNDINGBOX : 0);
me.input = "";
if (reset_text) me.input = "";
# If we only use one line, and one exists, things are simple:
if (!me.separate_lines and me.text != nil) {
me.text.appendText("\n");
@ -514,36 +539,13 @@ var CanvasPlacement = {
},
update: func() {
#debug.dump(me.text.getTransformedBounds());
if (me.state == "startup") return;
me.cursor.setTranslation(
me.text.getTransformedBounds()[2] + 6,
me.text.getTransformedBounds()[3] + 5
);
if (me.state != "startup")
me.cursor.setTranslation(
me.text.getTransformedBounds()[2] + 6,
me.text.getTransformedBounds()[3] + 5
).show();
me.scroll.update();
},
new_line: func() {
me.create_line();
me.text.appendText(">>> ");
me.text.stop = size(me.text.get("text"));
me.reset_view();
},
continue_line: func() {
me.create_line();
me.text.appendText("... ");
me.text.stop = size(me.text.get("text"));
me.reset_view();
},
reset_input_from_history: func() {
if (me.curr < size(me.history)) {
me.input = me.history[me.curr];
me.curr = size(me.history);
}
me.reset_view();
},
reset_view: func() {
me.group.update();
me.scroll.moveToLeft().moveToBottom();
},
handle_key: func(key, modifiers) {
var modifier_str = "";
foreach (var m; keys(modifiers)) {
@ -552,7 +554,7 @@ var CanvasPlacement = {
}
if (me.state == "startup") {
me.msg.del(); me.msg = nil;
me.new_line(); # initialize a new line
me.new_prompt(); # initialize a new line
me.text.stop = size(me.text.get("text"));
me.state = "accepting input";
@ -574,13 +576,26 @@ var CanvasPlacement = {
var input = clipboard.getText();
printlog(_REPL_dbg_level, "ctrl+v: "~debug.string(input));
me.reset_input_from_history();
for (var i=0; i<size(input); i+=1) {
if (input[i] == `\t`) {
var abnormal = func string.iscntrl(input[j]) or (string.isxspace(input[j]) and input[j] != ` `) or !string.isascii(input[j]);
var i=0;
while (i<size(input)) {
for (var j=i; j<size(input); j+=1)
if (abnormal()) break;
if (j != i) me.add_text(substr(input, i, j-i));
while (j<size(input) and abnormal()) {
# replace tabs with spaces
me.handle_key(` `, {shift:0, ctrl:0});
} elsif (string.isascii(input[i])) {
me.handle_key(input[i], {shift:0, ctrl:0});
if (input[j] == `\t`)
me.add_char(` `);
# handle newlines like they're shift+space, i.e. continue don't evaluate
elsif (input[j] == `\n` or input[j] == `\r`) {
if (j<size(input)-1 and input[j+1] == `\n`)
j+=1;
me.input ~= "\n"; me.continue_line(reset_text:0);
}
# skip other non-ascii characters
j += 1;
}
i=j;
}
} elsif (key == 4) { # ctrl-D/EOF
printlog(_REPL_dbg_level, "EOF");
@ -591,9 +606,11 @@ var CanvasPlacement = {
} elsif (key == `\n` or key == `\r`) {
printlog(_REPL_dbg_level, "return (key: "~key~", shift: "~modifiers.shift~")");
me.reset_input_from_history();
var reset_text = 1;
if (modifiers.shift) {
var res = -1;
me.input ~= "\n";
reset_text = 0;
} else {
if (size(string.trim(me.input))) {
append(me.history, me.input);
@ -606,8 +623,8 @@ var CanvasPlacement = {
printlog(_REPL_dbg_level, "return code: "~debug.string(res));
}
if (res == -1)
me.continue_line();
else me.new_line();
me.continue_line(reset_text:reset_text);
else me.new_prompt();
} elsif (key == 8) { # backspace
printlog(_REPL_dbg_level, "back");
@ -655,7 +672,6 @@ var CanvasPlacement = {
} else {
printlog(_REPL_dbg_level, "key: "~key~" (`"~chr(key)~"`)");
me.reset_input_from_history();
me.add_char(key);
me.completion_pos = -1;
}
@ -663,6 +679,7 @@ var CanvasPlacement = {
#printlog(_REPL_dbg_level, " -> "~me.input);
me.update();
me.reset_view();
return 1; # discard key event
},
@ -671,16 +688,14 @@ var CanvasPlacement = {
},
display_result: func(res=nil) {
if (res == nil) return 1; # don't display NULL results
me.coloring.start();
var res = call(debug.string, [res], var err=[]);
var res = call(debug.string, [res, 0], var err=[]);
if (size(err)) {
me.add_line(me.translations["bad-result"] or die("no translation"));
me.add_line(me.gettranslation("bad-result"));
me.set_line_color(me.colors.error);
if (me.font_file == "LiberationFonts/LiberationMono-Bold.ttf")
me.text.setFont("LiberationFonts/LiberationMono-BoldItalic.ttf");
me.set_line_font("LiberationFonts/LiberationMono-BoldItalic.ttf");
return 1;
}
me.coloring.end();
if (size(res) > me.max_output_chars)
res = substr(res, 0, me.max_output_chars-5)~". . .";
me.add_line(res);
@ -699,6 +714,7 @@ var CanvasPlacement = {
me.add_line("Parse error: "~msg~" on line "~line~" in "~file);
me.set_line_color(me.colors.error);
},
gettranslation: func(k) me.translations[k] or "[Error: no translation for key "~k~"]",
};
var print2 = func(i) {

View file

@ -281,6 +281,19 @@ var nodeList = func {
return list;
}
##
# Compiles a <condition> property branch according to the rules
# set out in $FG_ROOT/Docs/README.conditions into a Condition object.
# The 'test' method of the returend object can be used to evaluate
# the condition.
# The function returns nil on error.
#
var compileCondition = func(p) {
if(p == nil) return nil;
if(!isa(p, Node)) p = props.globals.getNode(p);
return _createCondition(p._g);
}
##
# Evaluates a <condition> property branch according to the rules
# set out in $FG_ROOT/Docs/README.conditions. Undefined conditions