About Layout & Group
This time I show you an overview of the layouts and groups.
Layouts are used to place the widgets in your window, so you could say that every window that contains widgets MUST have a layout.
Also for this topic you can find a description of the commands on the original
nuclear documentation page.
Like last time, some functions are marked here for the same reasons as in the
window topic.
Function overview Layout (Plugin - .DLL/.SO)
- LayoutSetMinRowHeight(height as Float)
- LayoutResetMinRowHeight()
- Integer LayoutWidgetBounds()
- Float LayoutRatioFromPixel(pixel_width as Float)
- LayoutRowStatic(height as Float, item_width as Integer, cols as Integer)
- LayoutRowDynamic(height as Float, cols as Integer)
- LayoutRowBegin(format as Integer, height as Float, cols as Integer)
- LayoutRowEnd()
- LayoutRow(format as Integer, height as Float, ratio_sz as String)
- LayoutRowPush(width_ratio as Float)[/*]
- LayoutRowTemplateBegin(height as Float)
- LayoutRowTemplatePushDynamic()[/*]
- LayoutRowTemplatePushVariable(min_width as Float)
- LayoutRowTemplatePushStatic( width as Float)
- LayoutRowTemplateEnd()
- LayoutSpaceBegin(format as Integer, height as Float, count as Integer)
- LayoutSpaceEnd()[/*]
- Integer LayoutSpaceBounds()
- LayoutSpacePush(posx as Float, posy as Float, width as Float, height as Float)
- Integer LayoutSpaceToScreen(posx as Float, posy as Float)
- Integer LayoutSpaceToLocal(posx as Float, posy as Float)
- Integer LayoutSpaceRectToScreen(posx as Float, posy as Float, width as Float, height as Float)
- Integer LayoutSpaceRectToLocal(posx as Float, posy as Float, width as Float, height as Float)
Function overview Group (Plugin - .DLL/.SO)
- Integer GroupBegin(String title, Integer flags)
- Integer GroupBeginTitled(String name, String title, Integer flags)
- GroupEnd()
Parameter Layout (Plugin)
- height
Sets the height of the row.
- pixel_width
Pixel width to convert to window ratio.
- item_width
Holds the pixel width of each widget in the line.
- cols
Number of widgets in the row.
- format
Either NK_DYNAMIC for the window ratio or NK_STATIC for fixed size columns.
- ratio_sz
A JSON string containing float values to split the line into individual columns. The string has the following format "[#.##,#.##,...]".
- width_ratio
Either a window ratio or a fixed width depending on format in the previous LayoutRowBegin call
- min_width
Holds the minimum pixel width, for the next column.
- width
Contains the absolute pixel width value, for the next column.
- count
Number of widgets in the SpaceLayout.
Parameter Group (Plugin)
- title
Holds the title of the group widget.
- flags
These flags are the same as for WindowBegin. See there.
- name
This name is used to identify the group internally. The name should be unique. If the title stands alone without the parameter name, then the title is also the name.
Function overview (AGK-Basic - .AGC)
- nk_rect nkLayoutSpaceBounds()
- nk_rect nkLayoutSpaceRectToScreen(rect ref as nk_rect)
- nkLayoutRow(format as integer, height as float, ratio ref as float[])
- nk_rect nkLayoutWidgetBounds()[/*]
- nkLayoutSpacePush(rect ref as nk_rect)
- nk_vec2 nkLayoutSpaceToScreen(pos ref as nk_vec2)
- nk_vec2 nkLayoutSpaceToLocal(pos ref as nk_vec2)
- nk_rect nkLayoutSpaceRectToLocal(rect ref as nk_rect)
Parameter (AGK-Basic)
- rect
Contains the position and size of an area in an nk_rect UDT.
- format
Either NK_DYNAMIC for the window ratio or NK_STATIC for fixed size columns.
- height
Sets the height of the row.
- ratio
A float array containing the column widths, either as ratios between 0.0 and 1.0 or as absolute numbers greater than 1.0.
- pos
Contains a position in an nk_vec2 UDT
Previous topic (About Windows) ———— Table of contents ———— Next topic (About Menus)
Now an example for using layouts.
#import_plugin Nuklear as nk
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Nuklear Window" )
SetWindowSize( 640, 480, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 640, 480 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 0, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
#insert "../Nuklear.agc"
// basic nuklear initialization
nkInit()
num_columns as integer = 4
ratio as float[3] = [0.15,0.35,0.35,0.15]
do
// pass agk inputs to nuklear
nk.HandleInput()
// open a window
if nk.WindowBegin("Window", 20, 50, 600, 240, NK_WINDOW_BORDER||NK_WINDOW_MOVABLE||NK_WINDOW_TITLE||NK_WINDOW_SCALABLE||NK_WINDOW_MINIMIZABLE||NK_WINDOW_CLOSABLE)
// define the layout. row height of 20 with 1 widget of dynamic width.
nk.LayoutRowDynamic(20,1)
// put a widget in the first row
nk.Label("drawing button grid (F1 - switch through number of columns)", NK_TEXT_CENTERED)
// all next widgets have the same size from the defined layout.
// each row with one widget. so that with each widget the number
// of rows grows.
nk.Label("DYNAMIC", NK_TEXT_LEFT)
// The layout is changed. The line height remains at 20 pixels,
// with a variable number of widgets in the row.
nk.LayoutRowDynamic(20, num_columns)
i as integer
// put twenty buttons in the layout
for i=0 to 11
nk.ButtonLabel("Button "+str(i))
next
// the layout is changed again. as above, except that the buttons
// are arranged statically.
nk.LayoutRowDynamic(20,1)
nk.Label("STATIC", NK_TEXT_LEFT)
nk.LayoutRowStatic(20, 110, num_columns)
for i=0 to 11
nk.ButtonLabel("Button "+str(i))
next
// now a demonstration for ratio layouts.
nk.LayoutRowDynamic(20,1)
nk.Label("drawing a ratio layout (F2 - shuffle ratio)", NK_TEXT_CENTERED)
nkLayoutRow(NK_DYNAMIC, 20, ratio)
for i=0 to 3
nk.ButtonLabel("Button "+str(trunc(ratio[i]*100))+"%")
next i
endif
nk.WindowEnd()
if nk.WindowIsClosed("Window") then exit
// F1 - switch through number of columns
if GetRawKeyPressed(112)
if num_columns >= 4 then num_columns = 1 else inc num_columns,1
endif
// F2 - shuffle ratio
if GetRawKeyPressed(113)
percent as integer = 100
value as integer
value = Random(10, 50)
ratio[0] = value / 100.0
dec percent, value
value = Random(10, (percent-20))
ratio[1] = value / 100.0
dec percent, value
value = Random(10, (percent-10))
ratio[2] = value / 100.0
dec percent, value
ratio[3] = percent / 100.0
endif
nkSync()
loop
Here is another example for the use of space layouts.
#option_explicit
#import_plugin Nuklear as nk
type connector
source_index as integer
dest_index as integer
endtype
type node
name as string
bounds as nk_rect
link_index as integer
endtype
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Nuklear Window" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 0, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
#insert "../Nuklear.agc"
// basic nuklear initialization
nkInit()
// init nodes
global node_array as node[]
global connector_array as connector[]
new_node as node
new_node.name = "component alpha"
new_node.bounds = nk_rect(10,50,150,150)
node_array.insert(new_node)
new_node.name = "component beta"
new_node.bounds = nk_rect(10,250,150,150)
node_array.insert(new_node)
new_node.name = "delta"
new_node.bounds = nk_rect(350,150,150,150)
node_array.insert(new_node)
LinkNode(node_array[0], node_array[2])
LinkNode(node_array[1], node_array[2])
// begin main loop
do
// pass agk inputs to nuklear
nk.HandleInput()
// open a window
if nk.WindowBegin("Window", 20, 50, 600, 540, NK_WINDOW_BORDER||NK_WINDOW_MOVABLE||NK_WINDOW_TITLE||NK_WINDOW_CLOSABLE||NK_WINDOW_NO_SCROLLBAR)
region as nk_rect
// window canvas is stored in slot '0' for later use to draw on
// the window surface.
nk.WindowStoreCanvas(0)
// get the area of the available space of the window.
region = nkWindowGetContentRegion()
// give the layout the entire window area. with a defined number
// of widgets.
nk.LayoutSpaceBegin(NK_STATIC, region.h, node_array.length+1)
// loop all available nodes
i as integer
for i=0 to node_array.length
// give the next widget a defined place on the window/panel.
nk.LayoutSpacePush(node_array[i].bounds.x,node_array[i].bounds.y,node_array[i].bounds.w,node_array[i].bounds.h)
// now a widget, in this case a group is packed into the
// layout. In this group more widgets can be placed.
if nk.GroupBegin(node_array[i].name, NK_WINDOW_MOVABLE||NK_WINDOW_NO_SCROLLBAR||NK_WINDOW_BORDER||NK_WINDOW_TITLE)
// store group-window panel for later use.
nk.WindowStorePanel(1)
// give the next widget (label) a place.
nk.LayoutRowDynamic(25, 1)
nk.Label("pos:"+str(trunc(node_array[i].bounds.x))+","+str(trunc(node_array[i].bounds.y)), NK_TEXT_CENTERED)
// give each group an end mark, but only if it was opened.
nk.GroupEnd()
endif
// here we get the new stored group-window panel bounds
bound0 as nk_rect
bound0 = nkLayoutSpaceRectToLocal(nkWindowGetStoredPanelBounds(1))
// copy the new position to the node description.
node_array[i].bounds.x = bound0.x
node_array[i].bounds.y = bound0.y
next
// now draw all connectors
for i=0 to connector_array.length
DrawConnection(node_array[connector_array[i].source_index], node_array[connector_array[i].dest_index])
next
nk.LayoutSpaceEnd()
endif
nk.WindowEnd()
if nk.WindowIsClosed("Window") then exit
nkSync()
loop
function LinkNode(src ref as node, dst ref as node)
new_link as connector
new_link.source_index = node_array.find(src.name)
new_link.dest_index = node_array.find(dst.name)
connector_array.insert(new_link)
src.link_index = connector_array.length
endfunction
function DrawConnection(src as node, dst as node)
pos0 as nk_vec2
pos1 as nk_vec2
pos0.x = src.bounds.x + src.bounds.w
pos0.y = src.bounds.y + src.bounds.h/2
pos1.x = dst.bounds.x
pos1.y = dst.bounds.y + dst.bounds.h/2
pos0 = nkLayoutSpaceToScreen(pos0)
pos1 = nkLayoutSpaceToScreen(pos1)
nk.StrokeCurve(0, pos0.x,pos0.y, pos0.x+50,pos0.y, pos1.x-50,pos1.y, pos1.x,pos1.y, 1.5, 0xffff00ff)
endfunction