Mathematica Programming » Higher-Level Functionality
Interfaces
Button
Button
is as simple as they come. It’s just a button. It has an expression it puts on the button and it runs a command and that’s it:
Button[
MouseAppearance["Click Me",
Style["?",Large,Bold]
],
Print["Ouch!"]]
It’s got some nice formatting options:
Row@Table[
With[{a=a},
Button[
MouseAppearance["Click Me",
Style["?",Large,Bold]
],
Print[a],
Appearancea]
],
{a,{Automatic,"Frameless","Palette","AbuttingRight","AbuttingLeft"}}
]
And you can change its basic styling:
Button[
Mouseover["You deserve a break",
Style["Relax and click here","HyperlinkActive"]
],
SystemOpen@"https://www.youtube.com/watch?v=cMdiYuzHVZ4",
BaseStyle"Hyperlink",
Appearance"Frameless"
]
["You deserve a break"](#"You deserve a break")
InputField
An InputField
is pretty self-explanatory:
InputField["Hi there",String]
Its usefulness comes when combined with Dynamic
inputVar="Change me";
InputField[Dynamic[inputVar,
Print["Changed!"];inputVar=#;&],String]
inputVar
It of course has many useful styling and usage options but these are generally pretty well documented so there is no pressing need to discuss them here.
PopupMenu
A PopupMenu
just selects a value from a list:
PopupMenu["",Prepend[Names["*Data"],""Style["Choose a data type",Italic,Gray]]]
Once again we can also set a variable this way:
Dynamic@popupVar;
PopupMenu[Dynamic@popupVar,Prepend[Names["*Data"],""->Style["Choose a data type",Italic,Gray]]]
popupVar
EventHandler
EventHandler
isn’t really an interface element so much as an extension for them. It catches front end events -- mouse clicks, keyboard input, etc. and routes them through a set of rules. It’s powerful, but can be a little tough to use.
Mathematica, unlike a more usual front-end system like tkinter, has no rich event syntax, instead it depends on the user querying the front end about global state, such as how one catches a double click event:
youDidIt=False;
nowClickPrinted=False;
wellDonePrinted=False;
EventHandler[
MouseAppearance[
Panel["Double click here"],
"Arrow"],{
"MouseEntered":>
If[!(youDidIt//TrueQ)&&!(nowClickPrinted//TrueQ),Print["Now click"];
nowClickPrinted=True],
"MouseClicked":>
If[CurrentValue@"MouseClickCount"==2,
If[!(youDidIt//TrueQ),
Print["You did it!"];
youDidIt=True
]
],
"MouseExited":>If[
youDidIt&&!(wellDonePrinted//TrueQ),
Print["Well done"];
wellDonePrinted=True]
}
]
This is an undeniably poor way to do things with myriad pitfalls, but it is one of the restrictions of the system, unfortunately.
The full list of events that EventHandler
can use isn’t completely clear, but the most common use cases are on its doc page. Others can be found by -hash-!!!9122545809131262370!!!-hash-
.
One class of events to know about is the class of "MenuCommand"
events. These look like {"MenuCommand", token}
and of these particularly crucial are the tokens "HandleShiftReturn"
and "EvaluateCells"
. These prevent Shift-Return or Keypad-Enter from evaluating and creating a new cell. Here’s a way to use this:
HandlerInputField[sym:_Dynamic|None:None,handlerFunction_,ops___]:=
With[{dynSym=Replace[sym,
None⧴With[{u=Unique@"handlerInputFieldValue$"},u=Null;Dynamic@u]
]},
EventHandler[InputField[dynSym,ops],{
{"MenuCommand","HandleShiftReturn"}⧴
Replace[
dynSym,
Verbatim[Dynamic][s_,___]⧴(
handlerFunction@s;
s=""
)
],
{"MenuCommand","EvaluateCells"}⧴
Replace[
dynSym,
Verbatim[Dynamic][s_,___]⧴(
handlerFunction@s;
s=""
)
],
"ReturnKeyDown"⧴NotebookWrite[EvaluationNotebook[],"\n"]
}
]
]
This creates and input field wrapped in an event handler. Now we’ll make an interface that can log the most common words we type. Type normally and return with Shift-Return.
wordLog={};
Column[{
HandlerInputField[
(wordLog=Join[wordLog,
ToLowerCase/@StringSplit@StringReplace[#,Except[WordCharacter|"'"]->" "]
])&,
String
],
Dynamic[
With[{a=Counts@wordLog},
BarChart[Values@a,
ChartLabels->Keys@a]
]
]
},
Dividers->{ {},{2->Gray}}
]
OpenerView and Toggler
OpenerView
is a particularly nice formatting element which let’s expressions be hidden but a title displayed:
OpenerView@{"Updating dynamic thing",
Dynamic[
Pause[.5];
Graphics@{RandomColor[],Disk[]},
UpdateInterval1]}
It’s really a subclass of Toggler
(well it’s parent function Opener
is) but worth mentioning because of how useful it is. A nice way to add underlines is to use Column
:
OpenerView@{
Column[
{"Updating dynamic thing"},
Dividers{ {},{2Gray}}
],
Dynamic[
Pause[.5];
Graphics@{RandomColor[],Disk[]},
UpdateInterval1]}
Toggler
just toggles between expressions when clicked
Toggler[1,Table[iFramed[
Style[i,FontColorIf[i<5,White,Black]],
RoundingRadius5,
FrameStyleNone,
BackgroundGrayLevel[i/10]],{i,10}]]
And Toggler
can similarly be used as a variable setter:
togglerVar=1;
Toggler[Dynamic@togglerVar,Table[i->Framed[
Style[i,FontColor->If[i<5,White,Black]],
RoundingRadius->5,
FrameStyle->None,
Background->GrayLevel[i/10]],{i,10}]]
togglerVar