I want to know how to write clean code of a big DynamicModul for a complex GUI which should be deployed as a CDF. I want to split the dynamic module into several smaller DynamicModuls and Functions.
Here is an example package:
(* ::Package:: *)
ClearAll["test`*", "test`*`*"]
BeginPackage["test`"];
testgui::usage="testing gui with package";
Begin["`Private`"];
guicolor = ColorData[3];
topcolor = Red;
topcoloractive = ColorData["GrayTones"][0.4];
guitextcolor = White;
guifont = FontFamily -> "Helvetica Neue";
buttoncolor = guicolor[5];
view1 = DynamicModule[{var1 = 1}, Column[{Button["var1 =10", var1 = 10], Dynamic@var1}], InheritScope -> True];
view2 = DynamicModule[{var1 = 1}, Column[{Button["var1 =20", var1 = 20], Dynamic@var1}], InheritScope -> True];
testgui := Framed@DynamicModule[{stream, viewbutton, view = 1, toprow, mainview, var1 = 1},
Column[{Dynamic@toprow,
Dynamic@mainview[view]
}],
Initialization :> (
mainview = <|1 -> view1, 2 -> view2|>;
viewbutton[text_, viewnumber_] := Button[Style[text, guitextcolor, guifont,
FontWeight -> Dynamic[If[view == viewnumber, Bold]]],
Dynamic[view = viewnumber], Background -> Dynamic[If[view == viewnumber, topcoloractive, topcolor]],
FrameMargins -> Medium, ContentPadding -> True, Method -> "Queued", Appearance -> None, ImageSize -> 100];
toprow = Grid[{{Dynamic@viewbutton["View 1", 1], Dynamic@viewbutton["View 2", 2]}}, Spacings -> {0, Automatic}];
)
]
End[];
EndPackage[ ];
I saved this package code as "test.wl" and use Get to test it:
packagepath = NotebookDirectory[] <> "test.wl"
Get[packagepath]
testgui
The GUI looks like this and works as expected:
My specific questions are:
1.) How can I move the function viewbutton out from Initialization?
Simply copying the function outside of Initialization does not work. Also when it is wrapped inside another DynamicModule with InheritScope -> True.
2.) In general, what is the best way to organise projects with complex custom GUIs inside a package? With the aim to have small individual parts which can be tested and developed individually.
I am thinking about making view1 and view2 also modular and containing several smaller DynamicModules and use functions similar to the viewbutton function inside view1 and view2.
viewbutton
and define it asviewbutton[text_, viewnumber_, Dynamic[view_], ...]
$\endgroup$DownValues
. The only real thing to watch out isHoldPattern
. $\endgroup$