# comment
whitespace has no meaning except single spaces used to separate important things
@ is an identifier
() means button of some sort
[__] means text entry of some sort (except checkbox)
{} means image
- means line
X means selected
~ means disabled
... means there is a submenu
> indicates the nesting level
import ezui
class Demo(ezui.WindowController):
def build(self):
pass
def started(self):
pass
def destroy(self):
pass
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
This is a label.
——X—— @slider
(Hello) @button
"""
descriptionData=dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
Demo()
Notes:
- Explain that anything unrecognizable falls back to being a label.
- I now arrange kwargs (and other important wide lines) vertically for easier reading.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
——X—— @slider
(Hello) @button
"""
descriptionData=dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def buttonCallback(self, sender):
print("Hello world!”)
Demo()
Notes:
- These can be wired manually. It’s possible to do pretty much everything manually if that’s what you want.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
——X—— @slider
(Hello) @button
"""
descriptionData = dict(
slider=dict(
minValue=0,
maxValue=10,
value=0
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def buttonCallback(self, sender):
print("Hello world!”)
Demo()
Notes:
- If an unknown key is in a description, the traceback will try to help you see what is wrong and how to fix it.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
[X] One @checkbox1
[ ] Two @checkbox2
——X—— @slider
(Hello World) @button
"""
descriptionData = dict(
slider=dict(
minValue=0,
maxValue=10,
value=0
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def buttonCallback(self, sender):
print("Hello world!”)
print(self.w.getItemValues())
values = dict(
checkbox1=False,
checkbox2=True,
slider=5
)
self.w.setItemValues(values)
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
[X] One @checkbox1
[ ] Two @checkbox2
——X—— @slider
(Hello World) @button
"""
descriptionData = dict(
slider=dict(
minValue=0,
maxValue=10,
value=0
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def buttonCallback(self, sender):
print("Hello world!”)
slider = self.w.getItem("slider")
print(slider.get())
Demo()
Show storing a reference to an item instead of asking for it repeatedly.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
Label @label
(PushButton) @pushButton
[ ] Checkbox @checkbox
( ) Radio 1 @radioButtons
( ) Radio 2
---X---------- @slider
[_TextField _] @textField
-----------------
(PopUpButton ...) @popUpButton
"""
descriptionData = dict(
popUpButton=dict(
popUpButton=dict(
items=["A", "B", "C"]
)
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
---X--- 123
---X--- [_123_]
[_123_](÷)
Before [_ABC_] After
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, "auto")
)
def started(self):
self.w.open()
Demo()
(Go through these quickly just to show that the type support is built in.)
import ezui
class DemoController(ezui.WindowController):
def build(self):
content = """
[_String. _] @stringTextField
[_List of strings._] @stringListTextField
[_1 _] @numberTextField
[_1 2.3 4 _] @numberListTextField
[_1 _] @integerTextField
[_1.2 _] @floatTextField
[_1.2 3.4 5.6 _] @floatListTextField
-----
Leading text. [______] Trailing text.
-----
{hare.fill} [______] {tortoise.fill}
"""
descriptionData = dict(
stringTextField=dict(
placeholder="Enter a string.",
valueType="string"
),
stringListTextField=dict(
placeholder="Enter a list of strings.",
valueType="stringList"
),
numberTextField=dict(
placeholder="Enter a number.",
valueType="number"
),
numberListTextField=dict(
placeholder="Enter a list of numbers.",
valueType="numberList"
),
integerTextField=dict(
placeholder="Enter an integer.",
valueType="integer"
),
floatTextField=dict(
placeholder="Enter a float.",
valueType="float"
),
floatListTextField = dict(
placeholder="Enter a list of floats.",
valueType="floatList"
)
)
self.w = ezui.EZWindow(
title="Demo",
size=(300, "auto"),
content=content,
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def stringTextFieldCallback(self, sender):
print(f"stringTextField: {sender.get()} {type(sender.get())}")
def stringListTextFieldCallback(self, sender):
print(f"stringListTextField: {sender.get()} {type(sender.get())}")
def numberTextFieldCallback(self, sender):
print(f"numberTextField: {sender.get()} {type(sender.get())}")
def numberListTextFieldCallback(self, sender):
print(f"numberListTextField: {sender.get()} {type(sender.get())}")
def integerTextFieldCallback(self, sender):
print(f"integerTextField: {sender.get()} {type(sender.get())}")
def integerListTextFieldCallback(self, sender):
print(f"integerListTextField: {sender.get()} {type(sender.get())}")
def floatTextFieldCallback(self, sender):
print(f"floatTextField: {sender.get()} {type(sender.get())}")
def floatListTextFieldCallback(self, sender):
print(f"floatListTextField: {sender.get()} {type(sender.get())}")
DemoController()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-----| @table
| |
|-----|
"""
descriptionData = dict(
table=dict(
items=[
"A",
"B",
"C"
]
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
Demo()
Notes:
- This is vanilla.List2 with more convenience.
- There are multiple table types depending on where the table is placed in a window. AppKit chooses automatically.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-----| @table
> (+-) @addRemoveButton
> (Hi...) @popUpButton
"""
descriptionData = dict(
table=dict(
items=[
"A",
"B",
"C"
]
),
popUpButton=dict(
items=[
"X",
"Y",
"Z"
]
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
def addRemoveButtonAddCallback(self, sender):
table = self.w.getItem("table")
popUpButton = self.w.getItem("popUpButton")
value = popUpButton.getItems()[popUpButton.get()]
items = table.get()
items.append(value)
table.set(items)
def addRemoveButtonRemoveCallback(self, sender):
table = self.w.getItem("table")
items = table.get()
for index in reversed(table.getSelectedIndexes()):
del items[index]
table.set(items)
Demo()
Notes:
- We don’t interact with the table contents via the table anymore.
- I may add some support for common actions (add, remove, duplicate, etc.) so that we don’t have to keep repeating this code.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-----------| @table
| One | Two |
|-----------|
| |
|-----------|
"""
descriptionData = dict(
table=dict(
columnDescriptions=[
dict(
identifier="one",
title="One"
),
dict(
identifier="two",
title="Two"
)
],
items=[
dict(one="A", two="B"),
dict(one="B", two="C"),
dict(one="C", two="D")
]
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(300, 200)
)
def started(self):
self.w.open()
Demo()
Notes:
- List2 allows for other item value types than dict. You can put a glyph or font in the list and have specific attributes or methods used for getting/setting values.
- Drag and drop is significantly improved and more powerful. This is also advanced.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-----------| @table
| One | Two |
|-----------|
| |
|-----------|
> (+-) @addRemoveButton
"""
descriptionData = dict(
table=dict(
columnDescriptions=[
dict(
identifier="one",
title="One"
),
dict(
identifier="two",
title="Two"
)
],
items=[
dict(one="A", two="B"),
dict(one="B", two="C"),
dict(one="C", two="D")
],
itemPrototype=dict(one="N", two="O")
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(300, 200)
)
def started(self):
self.w.open()
def addRemoveButtonAddCallback(self, sender):
table = self.w.getItem("table")
item = table.makeItem(one="Y", two="Z")
items = table.get()
items.append(item)
table.set(items)
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-------------------| @table
| One | Two | Three |
|-------------------|
| [_] | CCC | X---- |
|-------------------|
"""
descriptionData = dict(
table=dict(
columnDescriptions=[
dict(
identifier="one",
title="One",
cellDescription=dict(
cellType="TextField",
valueType="integer",
valueFallback=0
),
editable=True
),
dict(
identifier="two",
title="Two",
cellDescription=dict(
cellType="ColorWell"
),
editable=True
),
dict(
identifier="three",
title="Three",
cellDescription=dict(
cellType="Slider",
cellClassArguments=dict(
minValue=0,
maxValue=100
)
),
editable=True
)
],
items=[
dict(one=1, two=(1, 0, 0, 1), three=0),
dict(one=2, two=(0, 1, 0, 1), three=50),
dict(one=3, two=(0, 0, 1, 1), three=100),
]
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(400, 200)
)
def started(self):
self.w.open()
def tableEditCallback(self, sender):
print("tableEditCallback")
items = self.w.getItemValue("table")
for item in items:
print(item)
print("")
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|-----| @table
| |
|-----|
"""
items = []
items.append(ezui.TableGroupRow(text="Uppercase"))
items += list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
items.append(ezui.TableGroupRow(text="Lowercase"))
items += list("abcdefghijklmnopqrstuvwxyz")
items.append(ezui.TableGroupRow(text="Numbers"))
items += list("0123456789")
descriptionData = dict(
table=dict(
items=items,
allowsGroupRows=True
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
Demo()
Notes:
- Group rows can be styled.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
|------| @table
| |
|------|
(Select) @button
"""
descriptionData = dict(
table=dict(
items=[
"A",
"B",
"C"
]
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
def tableSelectionCallback(self, sender):
print("tableSelectionCallback")
table = sender
print(table.getSelectedIndexes())
print(table.getSelectedItems())
print("")
def buttonCallback(self, sender):
table = self.w.getItem("table")
table.setSelectedIndexes([0, 2])
Demo()
Colors can be (r, g, b, a)
or NSColor
. Using NSColor
is useful because the colors automatically change to support dark/light mode, accessibility and vibrancy.
https://developer.apple.com/design/human-interface-guidelines/foundations/color https://developer.apple.com/documentation/appkit/nscolor/standard_colors?language=objc
import AppKit
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* Box @box1
* Box @box2
"""
descriptionData = dict(
box1=dict(
backgroundColor=(1, 0, 0, 1),
borderColor=(0, 0, 0, 0),
height=100
),
box2=dict(
backgroundColor=AppKit.NSColor.systemRedColor(),
borderColor=(0, 0, 0, 0),
height=100
),
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, "auto")
)
def started(self):
self.w.open()
Demo()
We should be using SF Symbols whenever possible. Ezui supports these within EZML {name}
. Get the SF Symbols app to see what is available.
https://developer.apple.com/sf-symbols/
Symbols can be colored, have multiple colors, have variations within their contents, match weights, match text styles and more.
import pprint
import AppKit
import ezui
class SymbolDemo(ezui.WindowController):
def build(self):
content = """
= HorizontalStack
* OneColumnForm @configurationForm
> : variableValue:
> ---X--- X @variableValue
> : style:
> (Style ...) @style
> : pointSize:
> [_50_](÷) @pointSize
> : weight:
> (Weight ...) @weight
> : scale:
> (Scale ...) @scale
* VerticalStack
> default:
> * Image @imageDefault
* VerticalStack
> monochrome
> * Image @imageMonochrome
* VerticalStack
> hierarchical
> * Image @imageHierarchical
* VerticalStack
> palette
> * Image @imagePalette
* VerticalStack
> multicolor
> * Image @imageMulticolor
"""
imageWidth = 120
imageHeight = 120
descriptionData = dict(
configurationForm=dict(
width=150
),
variableValue=dict(
tickMarks=11,
minValue=0,
maxValue=1.0,
value=0.5,
stopOnTickMarks=True
),
style=dict(
width="fill",
items=[
"None",
"largeTitle",
"title1",
"title2",
"title3",
"headline",
"subheadline",
"body",
"callout",
"footnote",
"caption1",
"caption2"
]
),
pointSize=dict(
value=50,
minValue=5,
maxValue=100,
increment=1,
valueType="integer"
),
weight=dict(
width="fill",
items=[
"None",
"ultraLight",
"thin",
"light",
"regular",
"medium",
"semibold",
"bold",
"heavy",
"black"
]
),
scale=dict(
width="fill",
items=[
"None",
"small",
"medium",
"large"
]
),
imageDefault=dict(
width=imageWidth,
height=imageHeight
),
imageMonochrome=dict(
width=imageWidth,
height=imageHeight,
),
imageHierarchical=dict(
width=imageWidth,
height=imageHeight,
),
imageMulticolor=dict(
width=imageWidth,
height=imageHeight,
),
imagePalette=dict(
width=imageWidth,
height=imageHeight,
),
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
# size=(500, 500),
# minSize=(200, 200),
# maxSize=(800, 800),
controller=self
)
self.imageDefault = self.w.getItem("imageDefault")
self.imageMonochrome = self.w.getItem("imageMonochrome")
self.imageHierarchical = self.w.getItem("imageHierarchical")
self.imageMulticolor = self.w.getItem("imageMulticolor")
self.imagePalette = self.w.getItem("imagePalette")
self.populateImages()
def started(self):
self.w.open()
def configurationFormCallback(self, sender):
self.populateImages()
def populateImages(self):
configuration = self.w.getItem("configurationForm").getItemValues()
# variableValue
variableValue = configuration["variableValue"]
# style
style = configuration["style"]
style = self.w.getItem("style").getItems()[style]
if style == "None":
style = None
# pointSize
pointSize = configuration["pointSize"]
# weight
weight = configuration["weight"]
weight = self.w.getItem("weight").getItems()[weight]
if weight == "None":
weight = None
# scale
scale = configuration["scale"]
scale = self.w.getItem("scale").getItems()[scale]
if scale == "None":
scale = None
configuration = dict(
style=style,
pointSize=pointSize,
weight=weight,
scale=scale
)
def config(mode=None):
config = dict(configuration)
config["renderingMode"] = mode
if mode == "hierarchical":
config["colors"] = [(1, 0, 0, 1)]
elif mode == "palette":
config["colors"] = [(0, 0, 1, 1), (0, 1, 0, 1)]
elif mode == "monochrome":
config["colors"] = [(1, 0, 0, 1)]
return config
image = ezui.makeImage(
symbolName="chart.bar.doc.horizontal.fill",
variableValue=variableValue
)
multicolorImage = ezui.makeImage(
symbolName="pc",
variableValue=variableValue
)
self.imageDefault.setImage(imageObject=image)
self.imageMonochrome.setImage(imageObject=image)
self.imageHierarchical.setImage(imageObject=image)
self.imageMulticolor.setImage(imageObject=multicolorImage)
self.imagePalette.setImage(imageObject=image)
self.imageDefault.setSymbolConfiguration(**config(None))
self.imageMonochrome.setSymbolConfiguration(**config("monochrome"))
self.imageHierarchical.setSymbolConfiguration(**config("hierarchical"))
self.imageMulticolor.setSymbolConfiguration(**config("multicolor"))
self.imagePalette.setSymbolConfiguration(**config("palette"))
SymbolDemo()
There are fallbacks for older OS versions if you are concerned about that.
Eventually I’ll add support for custom symbols.
This is really complex and, honestly, there are not many good reasons to deviate from the HIG so, change fonts with caution. Use ezui.makeFont
if you must do something outside of TextEditor
.
Containers are defined in EZML with * ContainerTypeName @identifier
. Always give your container an identifier. >
is used to indicate items should be placed in the active container.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* Box
> (Button)
> [ ] Checkbox
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size="auto"
)
def started(self):
self.w.open()
Demo()
Notes:
- Don’t use Box like this except for testing.
The default content type for every container is VerticalStack. It’s sometimes useful to declare it for clarity.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* VerticalStack @stack
> * Box @box1
>> Box 1
> * Box @box2
>> Box 2
> * Box @box3
>> Box 3
"""
descriptionData = dict(
box1=dict(
backgroundColor=(1, 0, 0, 1),
borderColor=(0, 0, 0, 0),
height=150
),
box2=dict(
backgroundColor=(0, 1, 0, 1),
borderColor=(0, 0, 0, 0),
height=100
),
box3=dict(
backgroundColor=(0, 0, 1, 1),
borderColor=(0, 0, 0, 0),
height=50
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, "auto")
)
def started(self):
self.w.open()
Demo()
Notes:
- There are a lot of options for how things fit into stacks, the spacing, alignment, etc. See the documentation.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* HorizontalStack @stack
> * Box @box1
>> Box 1
> * Box @box2
>> Box 2
> * Box @box3
>> Box 3
"""
descriptionData = dict(
box1=dict(
backgroundColor=(1, 0, 0, 1),
borderColor=(0, 0, 0, 0),
width=200,
height=100
),
box2=dict(
backgroundColor=(0, 1, 0, 1),
borderColor=(0, 0, 0, 0),
width=150,
height=100
),
box3=dict(
backgroundColor=(0, 0, 1, 1),
borderColor=(0, 0, 0, 0),
width=100,
height=100
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size="auto"
)
def started(self):
self.w.open()
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* Tabs
> * Tab: One @tab1
>> This is tab 1.
> * Tab: Two @tab2
>> This is tab 2.
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
Demo()
If a container is the only item side of another container, change the top container type with =
.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
= Tabs
* Tab: One @tab1
> This is tab 1.
* Tab: Two @tab2
> This is tab 2.
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200)
)
def started(self):
self.w.open()
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
= HorizontalStack
* Box @box1
* Box @box2 = VerticalStack
> * Box @box2a
> * Box @box2b = HorizontalStack
>> * Box @box2b1
>> * Box @box2b2
> * Box @box2c
* Box @box3
"""
descriptionData = dict(
box1=dict(
backgroundColor=(1, 0, 0, 1),
borderColor=(0, 0, 0, 0),
width=100
),
box2=dict(
backgroundColor=(0, 1, 0, 1),
borderColor=(0, 0, 0, 0),
width=200
),
box3=dict(
backgroundColor=(0, 0, 1, 1),
borderColor=(0, 0, 0, 0),
width=300
),
box2a=dict(
backgroundColor=(1, 1, 1, 1),
borderColor=(0, 0, 0, 0),
height=100
),
box2b=dict(
backgroundColor=(0.5, 0.5, 0.5, 1),
borderColor=(0, 0, 0, 0),
height=100
),
box2c=dict(
backgroundColor=(0, 0, 0, 1),
borderColor=(0, 0, 0, 0),
height=100
),
box2b1=dict(
backgroundColor=(1, 1, 0, 1),
borderColor=(0, 0, 0, 0)
),
box2b2=dict(
backgroundColor=(0, 1, 1, 1),
borderColor=(0, 0, 0, 0)
),
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size="auto"
)
def started(self):
self.w.open()
Demo()
Forms are structured ways to make the most common UI combinations. These can stand on their own or be part of a larger UI.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* OneColumnForm @form
> !§ Section 1
> : Slider Label:
> ---X--- @slider
> : Radio Label:
> (X) One @radios
> ( ) Two
> : Checkboxes Label:
> [ ] Checkbox 1 @checkbox1
> [ ] Checkbox 2 @checkbox2
> !§ Section 2
> : TextEditor Label:
> [[__]] @textEditor
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size="auto"
)
def started(self):
self.w.open()
def formCallback(self, sender):
import pprint
pprint.pprint(sender.getItemValues())
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
* TwoColumnForm @form
> !§ Section 1
> : Slider Label:
> ---X--- @slider
> : Radio Label:
> (X) One @radios
> ( ) Two
> : Checkboxes Label:
> [ ] Checkbox 1 @checkbox1
> [ ] Checkbox 2 @checkbox2
> !§ Section 2
> : TextEditor Label:
> [[__]] @textEditor
"""
descriptionData = dict(
form=dict(
titleColumnWidth=125,
itemColumnWidth=200
),
textEditor=dict(
height=100
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size="auto"
)
def started(self):
self.w.open()
def formCallback(self, sender):
import pprint
pprint.pprint(sender.getItemValues())
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
Hello.
"""
descriptionData = dict(
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200),
title="Demo"
)
def started(self):
self.w.open()
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
Hello.
"""
descriptionData = dict(
)
self.w = ezui.EZPanel(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200),
title="Demo"
)
def started(self):
self.w.open()
Demo()
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
(Hello) @helloButton
"""
descriptionData = dict(
helloButton=dict(
width=200
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, "auto"),
title="Demo"
)
def started(self):
self.w.open()
def helloButtonCallback(self, sender):
DemoSheet(self.w)
class DemoSheet(ezui.WindowController):
def build(self, parent):
content = """
Hello.
"""
descriptionData=dict(
)
self.w = ezui.EZSheet(
content=content,
descriptionData=descriptionData,
controller=self,
parent=parent
)
def started(self):
self.w.open()
Demo()
You can specify a footer. If you do, the close button will go away.
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
(Hello) @helloButton
"""
descriptionData = dict(
helloButton=dict(
width=200
)
)
self.w = ezui.EZWindow(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, "auto"),
title="Demo"
)
def started(self):
self.w.open()
def helloButtonCallback(self, sender):
DemoSheet(self)
class DemoSheet(ezui.WindowController):
def build(self, parent):
content = """
Hello.
======
(Nope) @nopeButton
(Done) @doneButton
"""
descriptionData=dict(
)
self.w = ezui.EZSheet(
content=content,
descriptionData=descriptionData,
controller=self,
parent=parent.w
)
def started(self):
self.w.open()
def doneButtonCallback(self, sender):
self.w.close()
Demo()
from mojo.UI import CurrentGlyphWindow
import ezui
class Demo(ezui.WindowController):
def build(self):
content = """
Hello.
"""
descriptionData = dict(
)
self.w = ezui.EZPopUp(
content=content,
descriptionData=descriptionData,
controller=self,
size=(200, 200),
parent=CurrentGlyphWindow().w
)
def started(self):
self.w.open()
Demo()
These behave like the defconAppKit window controller. They may gain more features in the future.
from mojo.subscriber import Subscriber
from mojo.roboFont import CurrentGlyph
import ezui
class Demo(Subscriber, ezui.WindowController):
debug = True
def build(self):
content = """
The current glyph is: ? @label
"""
descriptionData = dict(
label=dict(
width="fill"
)
)
self.w = ezui.EZPanel(
content=content,
descriptionData=descriptionData,
controller=self,
size=(300, "auto")
)
def started(self):
self.updateText()
self.w.open()
def updateText(self):
glyph = CurrentGlyph()
if glyph is None:
name = "<none>"
else:
name = glyph.name
text = f"The current glyph is: {name}"
self.w.setItemValues(dict(label=text))
def roboFontDidSwitchCurrentGlyph(self, info):
self.updateText()
Demo()