Skip to content

Commit

Permalink
improved example
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-morel committed Aug 29, 2024
1 parent 6be1bfe commit a2c2c54
Show file tree
Hide file tree
Showing 18 changed files with 236 additions and 57 deletions.
8 changes: 7 additions & 1 deletion examples/todoapp/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
from todoapp import Application
import sys

Application().run()
entry = "/todos"

if len(sys.argv) > 1:
entry = sys.argv[1]

Application().redirect_to_singleton(entry)
21 changes: 16 additions & 5 deletions examples/todoapp/todoapp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import sys
from urllib.request import urlopen

from . import pages
from pathlib import Path
from taktk.application import Application
from taktk.component import Component
from taktk.component import Component
from taktk.dictionary import Dictionary
from taktk.media import get_media
from taktk.menu import Menu
from taktk.writeable import Writeable
from taktk.dictionary import Dictionary

from .admin import DIR, User, Todo
from .admin import DIR
from .admin import Todo
from .admin import User
from taktk.notification import Notification

recent_files = ["ama.py", "test.py", "ttkbootstrap.py", "label.py"]
Expand All @@ -26,6 +31,7 @@ def func():


class Application(Application):
icon = "@icon"
pages = pages
dictionaries = DIR / "dictionaries"
media = DIR / "media"
Expand All @@ -34,6 +40,7 @@ class Application(Application):
minsize=(800, 400),
)
destroy_cache = 5
address = ('', 56789)
menu = Menu(
{
"@file": {
Expand Down Expand Up @@ -103,11 +110,12 @@ def update_language(self):
class Layout(Component):
r"""
\frame weight:x='0: 10' weight:y='1: 10, 2: 10'
\frame padding=5 weight:y='2:10' weight:x='3:10' pos:grid=0,0 pos:sticky='nsew'
\frame padding=5 weight:y='2:10' weight:x='4:10' pos:grid=0,0 pos:sticky='nsew'
\button command={back} image=img:@backward{width: 20} pos:grid=0,0 pos:sticky='w' bootstyle='dark outline'
\button command={gt_users} image=img:@users-between-lines{height: 20} pos:grid=1,0 pos:sticky='w' bootstyle='dark outline'
\label text={f'logged in as: {User.current().name}' if User.current() else "not logged in!"} pos:grid=2,0
\button command={forward} image=img:@forward{width: 20} pos:grid=4,0 pos:sticky='e' bootstyle='dark outline'
\button command={gt_todos} image=img:@check-double{height: 20} pos:grid=2,0 pos:sticky='w' bootstyle='dark outline'
\label text={f'logged in as: {User.current().name}' if User.current() else "not logged in!"} pos:grid=3,0
\button command={forward} image=img:@forward{width: 20} pos:grid=5,0 pos:sticky='e' bootstyle='dark outline'
\frame:outlet pos:grid=0,1
"""

Expand All @@ -126,4 +134,7 @@ def forward(self):
def gt_users(self):
self.app("users")

def gt_todos(self):
self.app("todos")

User = User
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/todoapp/todoapp/media/img/check-double.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/todoapp/todoapp/media/img/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/todoapp/todoapp/media/img/rmbg.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ def rmbg(


for x in Path(".").glob("*.png"):
rmbg(x, color=(0, 0, 0), replace=(50, 50, 70))
rmbg(x, color=(255, 255, 255), replace=(255, 255, 255, 0))
Binary file modified examples/todoapp/todoapp/media/img/users-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/todoapp/todoapp/media/img/users-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/todoapp/todoapp/media/img/users-between-lines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/todoapp/todoapp/media/img/users.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions examples/todoapp/todoapp/pages/todos.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ def add_todo(self, *_):
return Notification(
"Empty field",
"Please, enter an item",
icon=r"C:\taktk\images\example-simple.png",
duration=10000,
duration=1000,
bootstyle="warning",
source="todo-empty-notification",
).show()
Expand Down
30 changes: 27 additions & 3 deletions examples/todoapp/todoapp/store.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"language": "French",
"theme": "journal",
"language": "English",
"theme": "darkly",
"__pageStore_todoapp.admin__": {
"users": [
{
Expand Down Expand Up @@ -56,11 +56,35 @@
"author_id": "d23acc8d-6577-11ef-82f6-28b2bda8b9ca",
"desc": "kenpd",
"done": true
},
{
"uuid": "00bbcaed-65f2-11ef-a2f7-28d244ed9304",
"author_id": "d23acc8d-6577-11ef-82f6-28b2bda8b9ca",
"desc": "I love python!",
"done": false
},
{
"uuid": "07ca2fd9-65f2-11ef-b1d9-28d244ed9304",
"author_id": "d23acc8d-6577-11ef-82f6-28b2bda8b9ca",
"desc": "I love tkinter!",
"done": true
},
{
"uuid": "0afbe6e3-65f2-11ef-8b72-28d244ed9304",
"author_id": "d23acc8d-6577-11ef-82f6-28b2bda8b9ca",
"desc": "I love Tk!",
"done": false
},
{
"uuid": "346f294e-65f2-11ef-825c-28d244ed9304",
"author_id": "d23acc8d-6577-11ef-82f6-28b2bda8b9ca",
"desc": "kkkdmc",
"done": false
}
]
},
"__pageStore_todoapp.pages.todos__": {
"entry:ama": "",
"entry:ken-morel": "Notez ici"
}
}
}
38 changes: 34 additions & 4 deletions src/taktk/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
from tempfile import NamedTemporaryFile
from .store import Store
from .media import get_media, get_image
from logging import getLogger
from . import ON_CREATE_HANDLERS

Expand All @@ -17,6 +18,8 @@ class Application:
layout = None
destroy_cache: int = 5
store = (None, {})
address = None
icon = None

def __init__(self):
import taktk
Expand Down Expand Up @@ -52,7 +55,11 @@ def setup_taktk(self):

media.MEDIA_DIR = Path(self.media)


def create(self):
if self.icon is not None:
self.icon = get_image(self.icon)
self.params['iconphoto'] = self.icon.full_path
self.root = root = Window(**self.params)
root.columnconfigure(0, weight=10)
root.rowconfigure(0, weight=10)
Expand All @@ -71,18 +78,41 @@ def run(self, entry="/"):
self.init()
for handler in ON_CREATE_HANDLERS:
handler(self)
if self.address is not None:
self.listen_at(self.address)
self.view = PageView(root, self.pages, self, self.destroy_cache)
self.view.geometry()
self.view.url(entry)
self.root.mainloop()

def __call__(self, module, function=None, /, **params):
self.view(module, function, params)
def __call__(self, module, function=None, redirect=True, /, **params):
try:
self.view(module, function, params)
except Redirect as e:
target = e.url
if redirect:
self.view.url(target)
else:
raise
self.layout.update()

def url(self, url):
return self.view.url(url)

def exit(self):
self.root.destroy()

def listen_at(self, port):
def listen_at(self, address):
from .application_server import ApplicationServer
ApplicationServer(self).thread_serve()
ApplicationServer(self, address).thread_serve()

def redirect_to_singleton(self, url=""):
from urllib.request import urlopen
try:
urlopen(f"http://localhost:{self.address[1]}/!current")
except Exception as e:
self.run(url)
return True
else:
urlopen(f"http://localhost:{self.address[1]}/" + url.lstrip('/'))
return False
45 changes: 45 additions & 0 deletions src/taktk/application_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from http.server import HTTPServer, SimpleHTTPRequestHandler
from threading import Thread
import json
from .page import Error404, Redirect


class ApplicationServer(HTTPServer):
class RequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
try:
_, response = self.server.app.url(self.path)
except Error404:
self.send_response(404)
self.send_header(
'Content-Type', 'application/x-json',
)
self.end_headers()
return self.wfile.write(json.dumps({
"ok": False,
"status": 404,
}).encode())
else:
self.send_response(200)
self.send_header(
'Content-Type', 'application/x-json',
)
self.end_headers()
return self.wfile.write(json.dumps(response or {
"ok": True,
"status": 200,
}).encode())


def __init__(self, app, address):
self.app = app
super().__init__(address, self.RequestHandler)

def thread_serve(self):
self.thread = Thread(
target=self.serve_forever,
)
self.thread.setDaemon(True)
self.thread.start()
# self.app.on_close(self.thread.kill)
return self.thread
16 changes: 12 additions & 4 deletions src/taktk/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_media(spec):
spec, props = parse_media_spec(spec)
assert (
n := spec.count(":")
) == 1, f"media spec should include one ':', has: {n}"
) >= 1, f"media spec should include one ':', has: {n}"
match tuple(spec.split(":", 1)):
case ("img", path):
if path[0] == "@":
Expand All @@ -41,6 +41,10 @@ def get_media(spec):
case wrong:
raise ValueError(f"Unrecognised media {spec!r}")

def get_image(spec):
if not spec.startswith('img:'):
spec = 'img:' + spec
return get_media(spec)

class Resource:
pass
Expand All @@ -49,7 +53,7 @@ class Resource:
class Image(Resource):
@cached_property
def image(self):
image = PIL.Image.open(self.path)
image = PIL.Image.open(self.full_path)
iw, ih = image.size
width, height = self.props.get("width"), self.props.get("height")
if width == height == None:
Expand All @@ -65,13 +69,13 @@ def tk(self):
return PIL.ImageTk.PhotoImage(self.image)

def get(self):
print(self, self.tk)
return self.tk

def __init__(self, path, props):
if not "." in path:
path += ".png"
self.path = path
self.full_path = path
self.props = props


Expand All @@ -80,7 +84,7 @@ class MediaImage(Resource):
def image(self):
if MEDIA_DIR is None:
raise RuntimeError("Media directory not set")
image = PIL.Image.open(MEDIA_DIR / "img" / self.path)
image = PIL.Image.open(self.full_path)
iw, ih = image.size
width, height = self.props.get("width"), self.props.get("height")
if width == height == None:
Expand All @@ -91,6 +95,10 @@ def image(self):
height = width / iw * ih
return image.resize((int(width), int(height)))

@property
def full_path(self):
return MEDIA_DIR / "img" / self.path

@cached_property
def tk(self):
return PIL.ImageTk.PhotoImage(self.image)
Expand Down
Loading

0 comments on commit a2c2c54

Please sign in to comment.