Skip to content

Commit

Permalink
Add a basic tutorial player example
Browse files Browse the repository at this point in the history
  • Loading branch information
laffra committed Mar 7, 2024
1 parent fd4fa5b commit 7a6899a
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 2 deletions.
2 changes: 2 additions & 0 deletions examples/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from examples import svg
from examples import table
from examples import tictactoe
from examples import tutorial

items = [
("examples/styling.py", styling.create()),
Expand All @@ -30,4 +31,5 @@
("examples/pydata.py", pydata.create()),
("examples/pizza.py", pizza.create()),
("examples/splits.py", splits.create()),
("examples/tutorial.py", tutorial.create()),
]
2 changes: 1 addition & 1 deletion examples/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ def create():
)
.css("max-height", 800)
.css("overflow-y", "scroll")
.attr("name", "Documentation")
.attr("name", "Docs")
)
106 changes: 106 additions & 0 deletions examples/tutorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# LTK - Copyright 2023 - All Rights Reserved - chrislaffra.com - See LICENSE

import ltk


class Step(ltk.Div):
classes = [ "ltk-bubble" ]

def __init__(self, widget, content):
ltk.Div.__init__(self, content)
self.content = content
self.widget = widget
self.css("font-family", "Arial")
self.css("position", "absolute")
self.css("top", -1000)
self.css("left", -1000)
self.css("background", "lightyellow")
self.css("border", "5px solid gray")
self.css("overflow", "hidden")
self.css("border-radius", 15)
self.css("padding", 5)
self.appendTo(ltk.find("body"))
self.width = self.width()
self.height = self.height()
self.draggable()

def show(self):
self.css("width", 0)
self.css("height", 0)
self.css("top", self.widget.offset().top)
self.css("left", self.widget.offset().left + self.widget.width() + 28)
self.animate(ltk.to_js({
"width": self.width + 5,
"height": self.height,
}))

def hide(self):
self.animate(ltk.to_js({
"width": 0,
"height": 0,
}), 250, ltk.proxy(lambda: self.remove()))

class Tutorial():
def __init__(self, steps):
self.steps = steps
self.index = 0
self.current = None
self.steps = steps

def run(self):
self.index = 0
self.show()

def next(self):
if self.current:
self.current.hide()
self.index += 1
if self.index < len(self.steps):
self.show()

def show(self):
selector, event, content = self.steps[self.index]
widget = ltk.find(selector)
self.current = Step(widget, content)
self.current.show()
widget.on(event, ltk.proxy(lambda *args: self.next()))


def tutorial():
return Tutorial([
(
"#hello-button",
"click",
ltk.Text("First, click the Hello button."),
),
(
"#world-button",
"click",
ltk.Text("Then, click the World button."),
),
])


def create():
return (
ltk.VBox(
ltk.Button("Hello", lambda event: print("hello"))
.css("margin", 20)
.css("font-size", 32)
.css("background", "lightgreen")
.css("border-radius", 10)
.attr("id", "hello-button"),
ltk.Button("World", lambda event: print("world"))
.css("margin", 20)
.css("background", "lightblue")
.css("border-radius", 10)
.css("font-size", 32)
.attr("id", "world-button"),

ltk.Button("start the tutorial", lambda event: tutorial().run())
.css("margin", 20)
.css("margin-top", 60)
)
.css("height", 800)
.attr("name", "Tutorial")
)
1 change: 1 addition & 0 deletions kitchensink.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ files = [
"examples/pubsub.py",
"examples/table.py",
"examples/svg.py",
"examples/tutorial.py",
]
5 changes: 4 additions & 1 deletion ltk/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ def attr(self, name, value=None):
If value is None, this gets the value as a string.
Otherwise, it sets the value, which needs to be a string.
"""
return self.element.attr(name, value) if value != None else self.element.attr(name)
try:
return self.element.attr(name, value) if value != None else self.element.attr(name)
except:
raise ValueError(f"Widget <{self}> does not have attribute {name}")

def prop(self, name, value=None):
"""
Expand Down

0 comments on commit 7a6899a

Please sign in to comment.