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!"]]
22-2797206139365313108

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"}}
 ]
22-873404383870698890

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]
22-5451681266245674562

Its usefulness comes when combined with Dynamic

 inputVar="Change me";
InputField[Dynamic[inputVar,
 Print["Changed!"];inputVar=#;&],String]
22-3974473653961945538
 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]]]
22-7860618826219449006

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]]]
22-4855681135816685350
 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]
  }
 ]
22-395271241287311702

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,
  NoneWith[{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]}
22-5509702874528235278

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]}
22-2781982858912025980

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}]]
22-4991518592214860267

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}]]
22-5678734961258451771
 togglerVar