User:Joe Bogner/QtLayout

From J Wiki
Jump to navigation Jump to search

This essay is written in response to http://jsoftware.com/pipermail/beta/2015-October/008316.html

Methods of laying out controls in jqt

This essay will explore 3 different methods of laying out controls in a jqt form.

  1. Grid cell - pros: more control in exact placement. cons: rearranging or inserting requires changing indices
  2. Grid razed - pros: minimal syntax, fluid, adapts to display. cons: exact placement may be challenging
  3. bins - pros: limitless flexibility. cons: may be tedious and difficult to comprehend

Desired result

Based on the forum post, the goal is to create an interface that looks like this:

Cmd 1: _____________ [Button 1]
Cmd 2 : _____________ [Button 2]

Output 1:
__________
__________

Output 2:
__________
__________


Plot Cmd 1: ___________ [Plot Button 1]
Plot Cmd 2: ___________ [Plot Button 2]

+-------------------------------+
|                                |
|           PLOT 1               |
|                                |
+-------------------------------+

+-------------------------------+
|                                |
|           PLOT 2               |
|                                |
+-------------------------------+


NOTE: This example does not put a plot control on the form. That is outside the scope of the article as is wiring up the control.s

Grid Cell

The grid cell method will instruct jqt to place controls at precise cell locations in a grid. The grid size will automatically be determined based upon the cells that are added. It is typical to specify the text for a control at the same time as creating the control. Controls also require IDs. The ID of the control can be user specified. The ID might be considered a system concern and not a programmer concern. A small helper is provided to combine creating and setting the text into a single call and returns the id of the new control - in case it is needed in the future.


idUI =: 0

addUI =: 4 : 0
   pos=: x
   if. 2=(#y) do. 'type text' =. y end.
   if. 3=(#y) do. 'type text cellwh' =. y end.
   id =. 'ux', ": idUI
   wd 'grid cell  ', pos
   NB. maxwh needs to be called before cc but on the cell
   if. 3=(#y) do. wd cellwh end.
   wd 'cc ', id , ' ',type   
   if. (#text) > 0 do. wd 'set ', id , ' text ', text end.
   idUI=:idUI+1
   id
)

NB. =========================================================
grid=: 3 : 0
wd 'pc grid'
'1 1' addUI 'static';'Cmd 1'
'1 2' addUI 'edit';''
'1 3' addUI 'button';'Run Cmd 1'

'2 1' addUI 'static';'Cmd 2'
'2 2' addUI 'edit';''
'2 3' addUI 'button';'Run Cmd 2'

'3 1' addUI 'static';'Output 1'
NB. make editm smaller than default
'4 1 1 3' addUI 'editm';'Output 1';'maxwh 1000 75'

'5 1' addUI 'static';'Output 2'
'6 1 1 3' addUI 'editm';'Output 2';'maxwh 1000 75'

'7 1' addUI 'static';'Plot Cmd 1'
'7 2' addUI 'edit';''
'7 3' addUI 'button';'Run Cmd 1'

'8 1' addUI 'static';'Plot Cmd 2'
'8 2' addUI 'edit';''
'8 3' addUI 'button';'Run Cmd 2'

'9 1 1 3' addUI 'isigraph';'';'minwh 500 100'
'10 1 1 3' addUI 'isigraph';'';'minwh 500 100'

wd 'pshow'
)

NB. =========================================================
grid_close=: 3 : 0
wd 'pclose'
)

NB. =========================================================
grid''

Jqt (Windows)
Layout-grid-cell.PNG
Jqt (Android)
Android-layout.png

Android-layout-landscape.png

Grid Razed (w/bin)

Razed grids allow controls to be added in sequential order and rearranged without specifying the exact row/column. This style may require the use of bins if all controls don't fit into a NxN grid. The desired layout above has the structure of:

3 controls
3 controls
1 control
1 control
1 control
1 control
3 controls
3 controls
1 control
1 control

As such, this layout cannot be supported purely by using a razed grid since rowspan/colspan cannot be specified. The solution mixes bins and grids

idUI =: 0

addUI =: 3 : 0
   if. 2=(#y) do. 'type text' =. y end.
   if. 3=(#y) do. 'type text cellwh' =. y end.
   id =. 'ux', ": idUI
   NB. grid cell can't be called in razed grid
   NB. wd 'grid cell  ', pos
   NB. maxwh needs to be called before cc but on the cell
   if. 3=(#y) do. wd cellwh end.
   wd 'cc ', id , ' ',type   
   if. (#text) > 0 do. wd 'set ', id , ' text ', text end.
   idUI=:idUI+1
   id
)

NB. =========================================================
grid=: 3 : 0
wd 'pc grid'
wd 'grid size 3 3'

NB. optional to show how columns widths can be specified
wd 'grid colwidth 0 100'
wd 'grid colwidth 2 100'

addUI 'static';'Cmd 1'
addUI 'edit';'Grid/Bin Layout'
addUI 'button';'Run Cmd 1'

addUI 'static';'Cmd 2'
addUI 'edit';''
addUI 'button';'Run Cmd 2'

NB. need to end previous grid and start a vertical bin
wd 'bin zv'
addUI 'static';'Output 1'
addUI 'editm';'Output 1';'maxwh 1000 75'
addUI 'static';'Output 2'
addUI 'editm';'Output 2';'maxwh 1000 75'

NB. stop previous vertical bin and create new vertical grid
wd 'bin zvg'
wd 'grid size 3 3'
wd 'grid colwidth 0 100'
wd 'grid colwidth 2 100'

addUI 'static';'Plot Cmd 1'
addUI 'edit';''
addUI 'button';'Run Cmd 1'

addUI 'static';'Plot Cmd 2'
addUI 'edit';''
addUI 'button';'Run Cmd 2'

NB. need to end previous grid and start a vertical bin
wd 'bin zv'
addUI 'isigraph';'';'minwh 500 100'
addUI 'isigraph';'';'minwh 500 100'

wd 'pshow'
)

NB. =========================================================
grid_close=: 3 : 0
wd 'pclose'
)

NB. =========================================================
grid''

The result is nearly identical to the first


Layout-grid-razed.PNG


JHS

JHS does not use the same layout engine as jqt, but one can be emulated. That same emulation can allow the jqt wd commands, wrapped in addUI, to be called on jhs.

Save this file somewhere (e.g. ~Projects/layout.ijs) and load from JHS using

load '~Projects/layout.ijs'

Then browse to http://127.0.0.1:65001/layout

coclass'layout'
coinsert'jhs'

CURRENTCOL=:1
GRIDCOLS=:0

NB. helper to add controls
addUI =: 3 : 0
    css=.''
    if. 2=(#y) do. 'type text' =. y end.
    if. 3=(#y) do.
        'type text cellwh' =. y
        parts=. ' ' cut cellwh
        if. (0{parts) -: (<'maxwh') do.
            css=. ' style="height: ', (> {: parts), 'px"'
        end.
    end.


    CURRENTCOL=:CURRENTCOL + 1
    HTML=: HTML, '<div class="field">'
    if. type -: 'static' do.
        HTML=:HTML,'<label>',text,'</label></div>',LF
    elseif. type -: 'edit' do.
        HTML=:HTML,'<input type="text" value="',text,'"',css,'>',LF
    elseif. type -: 'button' do.
        HTML=:HTML,'<input type="button" value="',text,'"',css,'>',LF
    elseif. type -: 'editm' do.
        HTML=:HTML,'<textarea',css,'>',text,'</textarea>',LF
    end.
    HTML=: HTML,'</div>'

    if. CURRENTCOL >: (GRIDCOLS+1) do.
        CURRENTCOL=:1
        HTML=:HTML,'<br style="clear:both">'
    end.
    HTML
)

NB. stub to allow jqt code to pass through
wd =: 3 : 0
 params=. ' ' cut y
 if. ((0{params) -: (<'grid')) *. ((1{params) -: (<'size'))  do.
     GRIDCOLS =: ". > {: params
     CURRENTCOL=: 1
     smoutput GRIDCOLS
 elseif. ((0{params) -: (<'bin')) *. ((1{params) -: (<'zv'))  do.
     GRIDCOLS=: 0
 end.
)

NB. css for the form
CSS=: 0 : 0
    div.field { float: left;margin-bottom:10px }
    body { padding: 20px; }
)

NB. executed on GET request
jev_get=: 3 : 0
'layout test'jhr''
)


NB. build the html
HBS=: 0 : 0
HTML=:''
grid''
)

NB. commands to build the grid/form
grid =: 3 : 0
    wd 'pc grid'
    wd 'grid size 3 3'

    addUI 'static';'Cmd 1'
    addUI 'edit';'Grid/Bin Layout'
    addUI 'button';'Run Cmd 1'

    addUI 'static';'Cmd 2'
    addUI 'edit';''
    addUI 'button';'Run Cmd 2'

    NB. need to end previous grid and start a vertical bin
    wd 'bin zv'
    addUI 'static';'Output 1'
    addUI 'editm';'Output 1';'maxwh 1000 75'
    addUI 'static';'Output 2'
    addUI 'editm';'Output 2';'maxwh 1000 75'

    NB. stop previous vertical bin and create new vertical grid
    wd 'bin zvg'
    wd 'grid size 3 3'

    addUI 'static';'Plot Cmd 1'
    addUI 'edit';''
    addUI 'button';'Run Cmd 1'

    addUI 'static';'Plot Cmd 2'
    addUI 'edit';''
    addUI 'button';'Run Cmd 2'

    NB. need to end previous grid and start a vertical bin
    wd 'bin zv'
    addUI 'isigraph';'';'minwh 500 100'
    addUI 'isigraph';'';'minwh 500 100'

)

Layout-grid-jhs.PNG

Summary

There is no right answer on how to lay out a form. The grid/bin approach has a steeper learning curve but is worth learning. Study http://code.jsoftware.com/wiki/Guides/Window_Driver/Layout for further examples.