| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- /*
- EvaLayoutManager without third party dependencies.
- Originally derived from
- EvaLayout, Lay it be!
- (http://www.codeproject.com/Articles/13891/EvaLayout-Lay-it-be)
- Copyright (c) 2014, Domingo Alvarez Duarte - mingodad[at]gmail[dot]com
-
- Released under the MIT LICENSE or GNU LESSER GENERAL PUBLIC LICENSE Version 3
- at your choice, permission to release under this licenses was obtained from the
- original author Alejandro Xalabarder ales[at]elxala[dot]de
-
- */
- const HEADER_ADAPT = "A";
- const HEADER_EXPAND = "X";
- const EXPAND_HORIZONTAL = "-";
- const EXPAND_VERTICAL = "+";
- local function max(a, b)
- {
- return a >= b ? a : b;
- }
-
- class WidgetInfo
- {
- name = null; // name of the component in the layout array
- widgetId = null; // component window handle
- isLaidOut = null; // if the component has been found in the layout array
- // and therefore if indxPos is a valid calculated field
- indxPos = null; // place in the layout array mesured in array indices
- // left = column index
- // right = last column index
- // top = row index
- // right = last row index
- iniRect = null; // initial pos and size of the component
- constructor(wname, theHandle, originalRect)
- {
- name = wname;
- widgetId = theHandle;
- isLaidOut = false;
- iniRect = originalRect;
- indxPos = {left : 0, right : 0, top : 0, bottom : 0};
- }
- }
- class EvaLayoutManager
- {
- isPrecalculated = null;
- Hmargin = null;
- Vmargin = null;
- Hgap = null;
- Vgap = null;
- fijoH = null;
- fijoV = null;
-
- Hpos = null;
- Hdim = null;
- HextraPos = null;
-
- Vdim = null;
- Vpos = null;
- VextraPos = null;
-
- columnsReparto = null;
- rowsReparto = null;
-
- componentArray = null;
- componentArrayIdx = null;
- evaLayout = null;
-
- constructor()
- {
- isPrecalculated = false;
- Hmargin = 0;
- Vmargin = 0;
- Hgap = 0;
- Vgap = 0;
- fijoH = 0;
- fijoV = 0;
-
- Hpos = [];
- Hdim = [];
- HextraPos = [];
-
- Vdim = [];
- Vpos = [];
- VextraPos = [];
-
- columnsReparto = [];
- rowsReparto = [];
-
- componentArray = [];
- componentArrayIdx = {};
- evaLayout = null;
- }
-
- function setLayout (layoutInfo)
- {
- if(type(layoutInfo) == "string")
- {
- var linfo = [];
- var lines = layoutInfo.split('\n');
- var lines_len = lines.len();
- var maxcols = 0;
- for(var i=0; i < lines_len; ++i)
- {
- var rec = lines[i].split(',');
- var rec_len = rec.len();
- if(rec_len == 1) continue; //ignore blank lines
- for(var j=0; j < rec_len; ++j)
- {
- rec[j] = rec[j].strip();
- }
- if(rec_len > maxcols)
- {
- maxcols = rec_len;
- }
- linfo.push(rec);
- }
- for(var i=0, len=linfo.len(); i < len; ++i)
- {
- var rec = linfo[i];
- var rec_len = rec.len();
- if(rec_len < maxcols)
- {
- for(var j=rec_len; j < maxcols; ++j)
- {
- rec.push("");
- }
- }
- }
- evaLayout = linfo;
- //console.log(linfo);
- } else { //assume an array
- evaLayout = layoutInfo;
- }
- isPrecalculated = false;
- }
-
- function getComponentRect(compWinHandle, rect)
- {
- rect.left <- math.random(5, 380);
- rect.top <- math.random(5, 380);
- rect.right <- math.random(rect.left + 6, 360);
- rect.bottom <- rect.top + 20;
- }
-
- function addComponent (componentName, compWinHandle)
- {
- var rect = {};
- getComponentRect (compWinHandle, rect);
- // add the component to the arrayand index it
- componentArrayIdx[componentName] <- componentArray.len();
- // add the component to the array
- componentArray.push (new WidgetInfo(componentName, compWinHandle, rect));
- isPrecalculated = false;
- }
-
- function hideShowComponentsInLayout ()
- {
- var compIds = getLayoutWidgetIds ();
- for(var i=0, len=componentArray.len(); i < len; ++i)
- {
- var wi = componentArray[i];
- hideShowComponent (wi.widgetId, !compIds[wi.widgetId]);
- }
- };
-
- function hideShowComponent (theId, bHide)
- {
- };
-
- function removeComponents ()
- {
- componentArray.clear ();
- componentArrayIdx.clear();
- isPrecalculated = false;
- }
-
- function showComponent(cId, bShowHide)
- {
- print("show", cId, bShowHide);
- }
-
- function moveComponent (cId, x, y, dx, dy, bShowHide)
- {
- print("move", cId, x, y, dx, dy, bShowHide);
- }
-
- function distributeWeight (aryExtraPos, aryReparto, HVdim, totalReparto, nrcsize)
- {
- for (var ii = 0, len=aryExtraPos.len(); ii < len; ii ++) aryExtraPos[ii] = 0;
- var arsize = aryReparto.len();
- var totalWeight = 0;
- for (var ii = 0; ii < arsize; ii ++) totalWeight += aryReparto[ii][1];
- var repartHV = totalReparto / ((totalWeight == 0) ? 1 : totalWeight);
- for (var ii = 0; ii < arsize; ii ++)
- {
- var colAry = aryReparto[ii];
- var indx = colAry[0];
- var indxExpandHV = repartHV * colAry[1];
- HVdim[indx] = indxExpandHV;
- for (var res = indx+1; res < nrcsize; res ++)
- {
- aryExtraPos[res] += indxExpandHV;
- }
- }
- };
-
- function doLayout (totWidth, totHeight)
- {
- precalculateAll ();
- // repartir H
- distributeWeight(HextraPos, columnsReparto, Hdim, (totWidth - fijoH), nColumns());
- // repartir V
- distributeWeight(VextraPos, rowsReparto, Vdim, (totHeight - fijoV), nRows());
- for (var ii = 0, len = componentArray.len(); ii < len; ii ++)
- {
- var wi = componentArray[ii];
- showComponent (wi.widgetId, (wi.isLaidOut) ? true : false);
- if (! wi.isLaidOut) continue;
- var indxPos = wi.indxPos;
- var indxPosLeft = indxPos.left;
- var indxPosTop = indxPos.top;
- var indxPosRight = indxPos.right;
- var indxPosBottom = indxPos.bottom;
- var x = Hpos[indxPosLeft] + HextraPos[indxPosLeft];
- var y = Vpos[indxPosTop] + VextraPos[indxPosTop];
- var dx = 0;
- var dy = 0;
- var mm;
- for (mm = indxPosLeft; mm <= indxPosRight; mm ++)
- {
- if (mm != indxPosLeft) dx += Hgap;
- dx += Hdim[mm];
- }
- for (mm = indxPosTop; mm <= indxPosBottom; mm ++)
- {
- if (mm != indxPosTop) dy += Vgap;
- dy += Vdim[mm];
- }
- //here we have a problem when the number become negative
- //the widget is not managed
- if (x < 0 || y < 0 || dx < 0 || dy < 0) //continue;
- {
- var elmRect = {};
- var elm = getComponentRect(wi.widgetId, elmRect);
- if(x < 0) x = elmRect.left;
- if(dx < 0) dx = elmRect.right - elmRect.left;
- if(y < 0) y = elmRect.top;
- if(dy < 0) dy = elmRect.bottom - elmRect.top;
- }
- moveComponent (wi.widgetId, x, y, dx, dy, true);
- //InvalidateRect(hControl, NULL, TRUE);
- }
- };
- function getWidgets (vecNames)
- {
- var ncsize = nColumns();
- for (var rr = 0, rlen = nRows(); rr < rlen; rr ++)
- {
- for (var cc = 0; cc < ncsize; cc ++)
- {
- var name = widgetAt (rr, cc);
- if (name.len() > 0 && name != EXPAND_HORIZONTAL && name != EXPAND_VERTICAL)
- {
- vecNames.push (name);
- }
- }
- }
- }
-
- function nColumns ()
- {
- return max (0, evaLayout[1].len() - 1);
- }
-
- function nRows ()
- {
- return max (0, evaLayout.len() - 2);
- }
-
- function widgetAt (nrow, ncol)
- {
- var theRow = nrow+2;
- if(evaLayout.len() > theRow)
- {
- var theCol = ncol + 1;
- theRow = evaLayout[theRow];
- if(theRow.len() > theCol)
- {
- return theRow[theCol];
- }
- }
- return null;
- }
-
- //private
- function getLayoutWidgetIds ()
- {
- var widgetIds = {};
- var ncols = nColumns();
- for(var row=0, rlen=nRows(); row<rlen; ++row)
- {
- for(var col=0; col < ncols; ++col)
- {
- var wi = widgetAt(row, col);
- var found = widgetIds[wi.widgetId];
- widgetIds[wi.widgetId] = found ? found+1 : 1;
- }
- }
- return widgetIds;
- };
-
- //private
-
- function isExpandWeight (headStr, aryToStore, idxToStore)
- {
- var strLen = headStr.len() ;
- if (strLen && headStr[0] == HEADER_EXPAND[0])
- {
- var weight = 1;
- if(strLen > 1)
- {
- weight = headStr.slice(1).tointeger();
- }
- aryToStore.push ([idxToStore, weight]); // compute later
- return true;
- }
- return false;
- };
-
- function computeVHDim (nrcsize, getHeader, VHmargin, VHgap, VHdim,
- VHpos, VHextraPos, aryReparto, getMinOf)
- {
- var fijoHV = VHmargin;
- for (var rr = 0; rr < nrcsize; rr ++)
- {
- var heaStr = getHeader(rr);
- var gap = (rr == 0) ? 0 : VHgap;
- VHdim.push (0);
- VHpos.push (0);
- VHextraPos.push (0);
- if (!isExpandWeight(heaStr, aryReparto, rr))
- {
- if (heaStr == "" || heaStr == HEADER_ADAPT)
- {
- VHdim[rr] = getMinOf(rr); // maximum-minimum of the row
- }
- else
- {
- VHdim[rr] = heaStr.tointeger(); // indicated size
- }
- }
- VHpos[rr] = fijoHV + gap;
- fijoHV += VHdim[rr];
- fijoHV += gap;
- }
- return fijoHV + VHmargin;
- };
-
- function precalculateAll ()
- {
- if (isPrecalculated) return;
- var el_row = evaLayout[0];
- Hmargin = max(0, el_row[1].tointeger() );
- Vmargin = max(0, el_row[2].tointeger() );
- Hgap = max(0, el_row[3].tointeger() );
- Vgap = max(0, el_row[4].tointeger() );
- Hdim.clear ();
- Hpos.clear ();
- Vdim.clear ();
- Vpos.clear ();
- columnsReparto.clear ();
- rowsReparto.clear ();
- for (var ii = 0, len = componentArray.len(); ii < len; ii ++)
- {
- componentArray[ii].isLaidOut = false;
- }
- //var cc;
- //var rr;
- var nrsize = nRows();
- var ncsize = nColumns();
- // compute Vdim
- fijoV = computeVHDim(nrsize, rowHeader, Vmargin, Vgap, Vdim,
- Vpos, VextraPos, rowsReparto, minHeightOfRow);
- // compute Hdim
- fijoH = computeVHDim(ncsize, columnHeader, Hmargin, Hgap, Hdim,
- Hpos, HextraPos, columnsReparto, minWidthOfColumn);
- // finding all components in the layout array
- for (var cc = 0; cc < ncsize; cc ++)
- {
- for (var rr = 0; rr < nrsize; rr ++)
- {
- var name = widgetAt(rr, cc);
- var indx = indxComponent (name);
- if (indx == -1) continue;
- var wid = componentArray[indx];
- var indxPos = wid.indxPos;
- // set position x,y
- indxPos.left = cc;
- indxPos.top = rr;
- // set position x2,y2
- var ava = cc;
- while (ava+1 < ncsize && widgetAt(rr, ava+1) == EXPAND_HORIZONTAL) ava ++;
- indxPos.right = ava;
- ava = rr;
- while (ava+1 < nrsize && widgetAt(ava+1, cc) == EXPAND_VERTICAL) ava ++;
- indxPos.bottom = ava;
- wid.isLaidOut = true;
- }
- }
- isPrecalculated = true;
- };
- function columnHeader (ncol)
- {
- return evaLayout[1][ncol + 1];
- }
-
- function rowHeader (nrow)
- {
- return evaLayout[2 + nrow][0];
- }
-
- function minHeightOfRow (nrow)
- {
- // el componente mas alto de la columna
- var maxheight = 0;
- for (var cc = 0, len = nColumns(); cc < len; cc ++)
- {
- var name = widgetAt (nrow, cc);
- var indx = indxComponent (name);
- if (indx == -1) continue;
- // if the widget occupies more than one row do not compute it
- if (widgetAt (nrow+1, cc) == EXPAND_VERTICAL) continue;
- var wid = componentArray[indx];
- var height = wid.iniRect.bottom - wid.iniRect.top;
- maxheight = max (maxheight, height);
- }
- return maxheight;
- }
-
- function minWidthOfColumn (ncol)
- {
- // el componente mas ancho de la columna
- var maxwidth = 0;
- for (var rr = 0, len = nRows(); rr < len; rr ++)
- {
- var name = widgetAt (rr, ncol);
- var indx = indxComponent (name);
- if (indx == -1) continue;
- // if the widget occupies more than one column do not compute it
- if (widgetAt (rr, ncol+1) == EXPAND_HORIZONTAL) continue;
- var wid = componentArray[indx];
- var width = wid.iniRect.right - wid.iniRect.left;
- maxwidth = max (maxwidth, width);
- }
- return maxwidth;
- }
-
- function indxComponent (compName)
- {
- return table_rawget(componentArrayIdx, compName, -1);
- };
- }
- class FltkEvaLayoutManager extends EvaLayoutManager {
- function showComponent(cId, bShowHide)
- {
- //print("show", cId, bShowHide);
- }
-
- function getComponentRect(cId, rect)
- {
- rect.left <- cId.x();
- rect.top <- cId.y();
- rect.right <- cId.w();
- rect.bottom <- rect.top + cId.h();
- }
-
- function moveComponent (cId, x, y, dx, dy, bShowHide)
- {
- //print(format([==[document.getElementById("%s").setAttribute("style", "position:absolute;left:%dpx;top:%dpx;right:%dpx;bottom:%dpx;");]==], cId, x, y, dx, dy, bShowHide));
- cId.resize(x, y, dx, dy);
- }
- }
- var layInfo = [
- ["EvaLayout", "10", "10", "5", "5"],
- ["grid" , "75" , "X" , "A" ],
- [ "A" , "boton1" , "memo" , "-" ],
- [ "A" , "boton2" , "+" , "" ],
- [ "A" , "boton3" , "+" , "" ],
- [ "X" , "" , "+" , "" ],
- [ "A" , "edit1" , "-" , "boton4" ],
- ];
- var manager = new FltkEvaLayoutManager();
- manager.setLayout(layInfo);
- class EvaWindow extends Fl_Window {
- boton1 = null;
- boton2 = null;
- boton3 = null;
- boton4 = null;
- memo = null;
- edit1 = null;
-
- constructor() {
- base.constructor(10, 50, 300, 280, "EvaWindow");
- begin();
-
- boton1 = new Fl_Button(0, 0, 35, 25,"button1");
- boton1->labelsize(16);
- boton2 = new Fl_Button(0, 0, 35, 25,"button2");
- boton2->labelsize(16);
- boton3 = new Fl_Button(0, 0, 35, 25,"button3");
- boton3->labelsize(16);
- boton4 = new Fl_Button(0, 0, 105, 25,"button4");
- boton4->labelsize(16);
- memo = new Fl_Input(0, 0, 35, 25,"memo");
- memo->labelsize(16);
- edit1 = new Fl_Input(0, 0, 35, 25,"edit1");
- edit1->labelsize(16);
-
- end();
- }
- }
- local win = new EvaWindow();
- win->resizable(win);
- win->show_main();
- manager.addComponent("memo", win.memo);
- manager.addComponent("boton1", win.boton1);
- manager.addComponent("boton2", win.boton2);
- manager.addComponent("boton3", win.boton3);
- manager.addComponent("boton4", win.boton4);
- manager.addComponent("edit1", win.edit1);
- manager.doLayout(win.w(), win.h());
- //Fl:scheme("plastic");
- Fl.scheme("gtk+");
- //use partial match to find verdana font
- Fl.visual(FL_RGB);
- //allow arrow keys navigation
- Fl.option(Fl.OPTION_ARROW_FOCUS, true);
- Fl.run();
- /*
- manager.addComponent("memo", "memo");
- manager.addComponent("boton1", "boton1");
- manager.addComponent("boton2", "boton2");
- manager.addComponent("boton3", "boton3");
- manager.addComponent("boton4", "boton4");
- manager.addComponent("edit1", "edit1");
- print(manager.nRows(), manager.nColumns());
- manager.doLayout(300, 400);
- manager.doLayout(400, 300);
- manager.doLayout(500, 600);
- manager.doLayout(600, 500);
- */
|