Controllers
Controllers do the work of converting ezui instructions into user-facing objects.
To use ezui, your ezui content must be defined in a subclass of one of these controllers. The controller classes will make the connections between your code and the user-facing objects. You implement your interface construction and deconstruction in a standard series of methods:
build
This will be called when it is time to build the interface components. This method is required.started
This will be called when the interface is presented to the user. This method is optional.destroy
This will be called when the interface is destroyed. This method is optional.
The controllers listed here are fully compatible with Subscriber
defined in mojo.subscriber
. When using these controllers with Subscriber
, you must use the class order Subscriber, OneOfTheControllerClasses
. If the order is flipped, the Subscriber
initialization will not be done properly and your subscription methods will not be called when events take place.
WindowController
- class ezui.WindowController(*args, **kwargs)
A controller for windows.
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (Button) @button [_Text_] @textField """ self.w = ezui.EZWindow( title="Demo", content=content, controller=self ) def started(self): self.w.open() def buttonCallback(self, sender): print("The button was pushed.") def textFieldCallback(self, sender): print("The text field was edited.") DemoController()
- startProgress(text=None, maxValue=None, parent=None)
Start a progress bar. This returns an instance of
ProgressWindow
.text
Text to show. Optional.maxValue
The maximum value for the bar. If this isNone
the bar will show a looping animation.parent
A parent window to attach the progress window to. Optional.import AppKit import ezui class DemoController(ezui.WindowController): def build(self): content = """ (startProgress) @startProgressButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.startProgressButtonCallback(None) def startProgressButtonCallback(self, sender): self.progressWindow = self.startProgress( text="Optional text.", maxValue=20, parent=self.getWindow() ) self.progressCount = 0 self.timer = AppKit.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 0.25, self, "_incrementProgressBar:", None, True ) def _incrementProgressBar_(self, timer): if self.progressCount == 20: self.timer.invalidate() self.progressWindow.close() self.progressWindow = None else: self.progressWindow.increment() self.progressCount += 1 DemoController()
- showMessage(messageText, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a message.
messageText
A short message.informativeText
A complete description. Optional.alertStyle
The style for the alert. Optional. Options:"informational"
"critical"
callback
A function to be called when the message is closed.icon
ANSImage
to display instead of the default icon. Optional.helpCallback
A callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showMessage) @showMessageButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showMessageButtonCallback(None) def showMessageButtonCallback(self, sender): self.showMessage( messageText="This is message text.", informativeText="This is optional informative text.", helpCallback=self.helpButtonCallback ) def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showAsk(messageText, buttonTitles, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a dialog with options for the user to choose from.
messageText
A short message.buttonTitles
A list of button titles. These are formatted as dicts with the following structure:{ "title" : "Text to be displayed.", "returnCode" : "Value to be returned by the button." }
informativeText
A complete description. Optional.alertStyle
The style for the alert. Optional. Options:"informational"
"critical"
callback
A function to be called when the message is closed.icon
ANSImage
to display instead of the default icon. Optional.helpCallback
A callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showAsk) @showAskButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showAskButtonCallback(None) def showAskButtonCallback(self, sender): self.showAsk( messageText="This is message text.", informativeText="This is optional informative text.", buttonTitles=[ dict(title="A?", returnCode="A"), dict(title="B?", returnCode="B"), dict(title="C?", returnCode="C") ], callback=self.showAskResultCallback, helpCallback=self.helpButtonCallback ) def showAskResultCallback(self, value): print(f"showAsk result: {value}") def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showAskYesNo(messageText, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a dialog with options “Yes” and “No” options for the user to choose from.
messageText
A short message.informativeText
A complete description. Optional.alertStyle
The style for the alert. Optional. Options:"informational"
"critical"
callback
A function to be called when the message is closed.icon
ANSImage
to display instead of the default icon. Optional.helpCallback
A callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showAskYesNo) @showAskYesNoButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showAskYesNoButtonCallback(None) def showAskYesNoButtonCallback(self, sender): self.showAskYesNo( messageText="This is message text.", informativeText="This is optional informative text.", callback=self.showAskYesNoResultCallback, helpCallback=self.helpButtonCallback ) def showAskYesNoResultCallback(self, value): print(f"showAskYesNo result: {value}") def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showGetFolder(callback, messageText=None, directory=None, allowsMultipleSelection=False, accessoryView=None, descriptionData={})
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showGetFolder) @showGetFolderButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showGetFolderButtonCallback(None) def showGetFolderButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @getFolderLetterPopUpButton : Number: (X) 0 @getFolderNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( getFolderLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.getFolderLetter = "A" self.getFolderNumber = 0 self.showGetFolder( messageText="This is the message text.", allowsMultipleSelection=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showGetFolderResultCallback ) def getFolderLetterPopUpButtonCallback(self, sender): i = sender.get() self.getFolderLetter = sender.getItems()[i] def getFolderNumberRadioButtonsCallback(self, sender): self.getFolderNumber = sender.get() def showGetFolderResultCallback(self, result): print(f"Path: {result} Letter: {self.getFolderLetter} Number: {self.getFolderNumber}") DemoController()
- showGetFile(callback, fileTypes=[], allowsMultipleSelection=False, messageText=None, directory=None, accessoryView=None, descriptionData={})
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showGetFile) @showGetFileButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showGetFileButtonCallback(None) def showGetFileButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @getFileLetterPopUpButton : Number: (X) 0 @getFileNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( getFileLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.getFileLetter = "A" self.getFileNumber = 0 self.showGetFile( messageText="This is the message text.", fileTypes=["txt", "py"], allowsMultipleSelection=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showGetFileResultCallback ) def getFileLetterPopUpButtonCallback(self, sender): i = sender.get() self.getFileLetter = sender.getItems()[i] def getFileNumberRadioButtonsCallback(self, sender): self.getFileNumber = sender.get() def showGetFileResultCallback(self, result): print(f"Path: {result} Letter: {self.getFileLetter} Number: {self.getFileNumber}") DemoController()
- showPutFile(callback, fileTypes=[], fileName=None, directory=None, accessoryView=None, descriptionData={}, messageText=None, canCreateDirectories=True)
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showPutFile) @showPutFileButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showPutFileButtonCallback(None) def showPutFileButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @putFileLetterPopUpButton : Number: (X) 0 @putFileNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( putFileLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.putFileLetter = "A" self.putFileNumber = 0 self.showPutFile( messageText="This is the message text.", fileTypes=["abc", "xyz"], fileName="Demo.abc", canCreateDirectories=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showPutFileResultCallback ) def putFileLetterPopUpButtonCallback(self, sender): i = sender.get() self.putFileLetter = sender.getItems()[i] def putFileNumberRadioButtonsCallback(self, sender): self.putFileNumber = sender.get() def showPutFileResultCallback(self, result): print(f"Path: {result} Letter: {self.putFileLetter} Number: {self.putFileNumber}") DemoController()
- getWindow()
Get the window this controller controls.
Subclasses must override this if their window is not located at
self.w
.
- build()
This will be called when the controller is initialized. Subclasses should override this to build the window that this controller controls. The window must not be opened while this method is executing. Open the window in the
started
method.
- started()
This will be called after the build process is completed. Subclasses should override this to open the window that this controller controls and do any other work that can’t be completed in the
build
method.
- destroy()
This will be called when the window is closed. Subclasses may override to tear down anything necessary.
ContainerController
- class ezui.ContainerController(*args, **kwargs)
A container controller. This isn’t intended for use on its own. It primarily serves as a superclass for
GlyphEditorContainerController
andInspectorItemContainerController
.- addToParent(parent, position=(0, 0), width=None, height=None, identifier=None)
Add the container this controller controls to
parent
.parent
A Vanilla object capable of containing views.position
The position of the container withinparent
. For the time being, position must be expressed in Vanilla style coordinates. Optional.width
The desired width of the container. Optional.height
The desired height of the container. Optional.identifier
A unique identifier for the container. This is currently only used by GlyphEditorContainerController. Optional.
- removeFromParent()
Remove the container from the parent.
- getContainer()
Get the container this controller controls.
Subclasses must override this if their window is not located at
self.v
.
- build()
This will be called when the controller is initialized. Subclasses should override this to build the container that this controller controls. The container must not be added to the parent view while this method is executing. Do this in the
started
method.
- started()
This will be called after the build process is completed. Subclasses should override this to add the container that this controller controls to the parent view and do any other work that can’t be completed in the
build
method.
- destroy()
This will be called when the container is destroyed. Subclasses may override to tear down anything necessary.
GlyphEditorContainerController
- class ezui.GlyphEditorContainerController(*args, **kwargs)
A controller for containers displayed in the Glyph Editor.
class GlyphEditorTest(Subscriber, GlyphEditorContainerController): debug = True def build(self): contents = """ EZUI in glyph editor. (This is a button) @button ---X-------------- @slider (X) One @radioButtons ( ) Two ( ) Three |----------------| @table | | |----------------| """ descriptionData = dict( slider=dict( minValue=0, maxValue=100, value=75 ), table=dict( height=100, items=[ "this", "is", "a", "table" ] ) ) self.v = ezui.VerticalStack( contents=contents, descriptionData=descriptionData, controller=self ) def started(self): editor = self.getGlyphEditor() self.addToGlyphEditor( "com.typesupply.ezuiContainerControllerTest.GlyphEditor", position=(50, 50), width=150 ) def sliderCallback(self, sender): print("glyph editor sliderCallback", sender.get()) registerGlyphEditorSubscriber(GlyphEditorTest)
- addToGlyphEditor(identifier, position=(0, 0), width=None, height=None)
Add the container this controller controls to the glyph editor assigned to this
Subscriber
.parent
A Vanilla object capable of containing views.position
The position of the container within the glyph editor. For the time being, position must be expressed in Vanilla style coordinates. Optional.width
The desired width of the container. Optional.height
The desired height of the container. Optional.identifier
A unique identifier for the container.
InspectorItemContainerController
- class ezui.InspectorItemContainerController(*args, **kwargs)
A controller for Inspector items.
To control the initial appearance of your item, you may define a
inspectorItemData
dictionary in youtbuild
method. If you need to override the default behavior, use these keys:title
The desired title of the section in Inspector.index
The index at which you want the item inserted into the Inspector. Default is last.insertBefore
The title of the specific section in Inspector you would like your panel to precede. Default is last. This will overwriteindex
.minSize
The minimum size for the item.collapsed
If the item is initially collapsed.canResize
If the item can be resized by the user.
You do not add the item to the Inspector directly. This will be handled automatically for you.
class InspectorTest(Subscriber, InspectorItemContainerController): debug = True def build(self): contents = """ EZUI in an inspector. view (This is a button) @button ---X-------------- @slider (X) One @radioButtons ( ) Two ( ) Three |----------------| @table | | |----------------| """ descriptionData = dict( slider=dict( minValue=0, maxValue=100, value=75 ), table=dict( height=100, items=[ "this", "is", "a", "table" ] ) ) self.v = ezui.VerticalStack( contents=contents, descriptionData=descriptionData, controller=self ) self.inspectorItemData = dict( title=Test, collapsed=False ) def sliderCallback(self, sender): print("inspector sliderCallback", sender.get()) registerRoboFontSubscriber(InspectorTest)