var pageClass = { new : func (d) { var m = { parents : [pageClass] }; m.page = d.display.display.createGroup().set('z-index', 100); m.window = {}; m.state = {}; m.selected = ''; return m; }, del : func (id = nil) { if (id != nil and typeof(id) == 'scalar') { delete(me.state, id); var _id = id ~ '-'; id = []; foreach (var w; keys(me.window)) if (find(_id, w) == 0) append(id, w); } else { foreach (var s; keys(me.state)) delete(me.state, s); id = keys(me.window); } foreach (var w; id) { me.window[w] .hide() .del(); delete(me.window, w); } }, _selected_text : func (id, text, x, y) { me.selected = id; me.window[id] .setFontSize(16) .setFont('LiberationFonts/LiberationMono-Regular.ttf') .setTranslation(x, y) .setDrawMode(0x01 + 0x04) .setText(text) .setColorFill(0,1,1) .setColor(0,0,0); }, _editable_text : func (id, text, x, y) { me.window[id] .setFontSize(16) .setFont('LiberationFonts/LiberationMono-Regular.ttf') .setTranslation(x, y) .setText(text) .setColorFill(0,0,0) .setColor(0,1,1); }, _normal_text : func (id, text, x, y) { me.window[id] .setFontSize(16) .setFont('LiberationFonts/LiberationMono-Regular.ttf') .setTranslation(x, y) .setText(text) .setColorFill(0,0,0) .setColor(1,1,1); }, _title_text : func (id, text, x, y) { me.window[id] .setFontSize(16) .setFont('LiberationFonts/LiberationMono-Regular.ttf') .setTranslation(x, y) .setAlignment('center-center') .setText(text) .setColorFill(0,0,0) .setColor(0,1,1); }, fill : func (id, scroll = nil) { var state = me.state[id]; state.scroll = { offset : 0, # offset between canvas element and state element last : 9999, # last scrollgroup begin: -9999, # first canvas element of the scrolling area end: 9999, # last canvas element of the scrolling area upper: -9999, # group printed on the top of the scrolling area lower: 9999, # group printed at the bottom of the scrolling area lines : scroll != nil ? scroll.lines : 0, # number of lines for the scrolling area columns : scroll != nil ? scroll.columns : 0, # number of objects on each scrolling lines }; var scrollgroup = {}; forindex (var line; state.objects) { if (find('separator', state.objects[line].type) > -1) { me.window[id ~ '-' ~ (line - state.scroll.offset)] = me.page.createChild('path') .setStrokeLineWidth(1) .moveTo(state.x_base, state.geometry.y - 12) .horiz(state.geometry.w - 20) .setColor(1,1,1); state.geometry.x = state.x_base; state.geometry.y += 8; } else { if (contains(state.objects[line], 'scrollgroup')) { state.scroll.last = state.objects[line].scrollgroup; scrollgroup[state.objects[line].scrollgroup] = 1; if (state.scroll.begin == -9999) { state.scroll.begin = line; state.scroll.upper = state.objects[line].scrollgroup; } if (size(keys(scrollgroup)) > state.scroll.lines) { if (state.scroll.end == 9999) { state.scroll.end = line - 1; state.scroll.lower = state.objects[line - 1].scrollgroup; } else state.scroll.last = state.objects[line].scrollgroup; state.scroll.offset += 1; continue; } } me.window[id ~ '-' ~ (line - state.scroll.offset)] = me.page.createChild('text'); if (find('selected', state.objects[line].type) > -1) me._selected_text( id ~ '-' ~ (line - state.scroll.offset), state.objects[line].text, state.geometry.x, state.geometry.y, ); elsif (find('editable', state.objects[line].type) > -1 or find('highlighted', state.objects[line].type) > -1) me._editable_text( id ~ '-' ~ (line - state.scroll.offset), state.objects[line].text, state.geometry.x, state.geometry.y, ); elsif (find('title', state.objects[line].type) > -1) me._title_text( id ~ '-' ~ (line - state.scroll.offset), state.objects[line].text, state.x_base - 10 + state.geometry.w / 2, state.geometry.y ); else me._normal_text( id ~ '-' ~ (line - state.scroll.offset), state.objects[line].text, state.geometry.x, state.geometry.y, ); if (find('end-of-line', state.objects[line].type) > -1 or find('title', state.objects[line].type) > -1) { state.geometry.x = state.x_base; state.geometry.y += 24; } else state.geometry.x += size(state.objects[line].text) * 10 + 8; } } # reset the scrolling offset before the first move state.scroll.offset = 0; }, draw : func (id, geometry, objects, scroll = nil) { if (contains(me.window, id ~ '-bg')) { logprint(LOG_DEBUG, 'objet ' ~ id ~ ' already exists'); return; } if (!contains(geometry, 'sep')) geometry.sep = 0; if (contains(geometry, 'autogeom') and geometry.autogeom) { # 1024x768 display # - let 10 from the border # - plus other 10 from the window border and the text # - font size tends to be 10x24 # - let 8+8 around the separator var textWidth = 200; var lines = 0; forindex (var o; objects) { if (contains(objects[o], 'text')) { var l = size(objects[o].text) * 10; if (l > textWidth) textWidth = l; lines += 1; } if (contains(objects[o], 'type') and objects[o].type == 'separator') geometry.sep += 1; } geometry.l = lines; if (contains(geometry, 'x')) geometry.x -= textWidth; else geometry.x = 1014 - textWidth; if (contains(geometry, 'y')) geometry.y -= lines * 24 + 72; # 72 = offset from bottom to let... else geometry.y = 758 - (lines * 24) - 72; # ... softkeys display and margin if (!contains(geometry, 'w')) geometry.w = textWidth; } if (!contains(geometry, 'h') and !contains(geometry, 'l')) { logprint(LOG_DEBUG, 'missing parameter l or h'); return; } var save_x = geometry.x; var save_y = geometry.y; if (!geometry.sep) geometry.sep = 1; me.state[id] = { objects: objects, geometry: geometry, x_base : geometry.x + 10, h_max : contains(geometry, 'h') ? h : geometry.l * 24 + 8 + geometry.sep * 16, }; logprint(LOG_DEBUG, sprintf('geom id: %s, x: %d, y: %d, w: %d, h: %d, l: %d, sep: %d', id, geometry.x, geometry.y, geometry.w, me.state[id].h_max, geometry.l, geometry.sep)); me.state[id].y_max = me.state[id].h_max + me.state[id].geometry.y; me.window[id ~ '-bg'] = me.page.createChild('path'); me.window[id ~ '-bg'] .rect(geometry.x, geometry.y, geometry.w, me.state[id].h_max) .setColor(1,1,1) .setColorFill(0,0,0); me.state[id].geometry.x += 10; me.state[id].geometry.y += 16; me.fill(id, scroll); geometry.x = save_x; geometry.y = save_y; }, };