Made startup logic consistent across platforms.
This means that underlying widgets aren't created in the constructor; they're created in _startup(). It also means windows know which app they are associated with, and widgets know which window (and app) they're associated with.
This commit is contained in:
parent
0f1c156d23
commit
844fa1f448
20 changed files with 325 additions and 118 deletions
|
|
@ -49,14 +49,49 @@ class Widget(WidgetBase):
|
|||
class Container(Widget):
|
||||
def __init__(self):
|
||||
super(Container, self).__init__()
|
||||
self.children = []
|
||||
self.constraints = {}
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
self._layout_manager = LayoutManager(self._bounding_box)
|
||||
self._impl = self._create_container()
|
||||
|
||||
for child in self.children:
|
||||
self._add(child)
|
||||
|
||||
for constraint, impl in ((c, i) for c, i in self.constraints.items() if i is None):
|
||||
self._constrain(constraint)
|
||||
|
||||
def add(self, widget):
|
||||
self._impl.add(widget._impl)
|
||||
self.children.append(widget)
|
||||
print("Add widget to container")
|
||||
|
||||
if self._impl:
|
||||
self._add(widget)
|
||||
|
||||
def _add(self, widget):
|
||||
# Assign the widget to the same app and window as the container.
|
||||
# This initiates startup logic.
|
||||
widget.window = self.window
|
||||
widget.app = self.app
|
||||
self._layout_manager.add_widget(widget)
|
||||
self._impl.add(widget._impl)
|
||||
|
||||
def constrain(self, constraint):
|
||||
"Add the given constraint to the widget."
|
||||
if constraint in self.constraints:
|
||||
return
|
||||
|
||||
if self._impl:
|
||||
print ("Add constraint")
|
||||
self._constrain(constraint)
|
||||
|
||||
else:
|
||||
print("Defer constraint until later")
|
||||
self.constraints[constraint] = None
|
||||
|
||||
def _constrain(self, constraint):
|
||||
widget = constraint.attr.widget
|
||||
identifier = constraint.attr.identifier
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,15 @@ class MainWindow(Window):
|
|||
class App(object):
|
||||
|
||||
def __init__(self, name, app_id):
|
||||
self._impl = NSApplication.sharedApplication()
|
||||
self._impl.setActivationPolicy_(NSApplicationActivationPolicyRegular)
|
||||
self.name = name
|
||||
self.app_id = app_id
|
||||
|
||||
self.main_window = MainWindow()
|
||||
|
||||
def _startup(self):
|
||||
self._impl = NSApplication.sharedApplication()
|
||||
self._impl.setActivationPolicy_(NSApplicationActivationPolicyRegular)
|
||||
|
||||
app_name = sys.argv[0]
|
||||
|
||||
self.menu = NSMenu.alloc().initWithTitle_(get_NSString('MainMenu'))
|
||||
|
|
@ -78,6 +82,8 @@ class App(object):
|
|||
self._impl.setMainMenu_(self.menu)
|
||||
|
||||
def main_loop(self):
|
||||
self._startup()
|
||||
self.main_window.app = self
|
||||
self.main_window.show()
|
||||
self._impl.activateIgnoringOtherApps_(True)
|
||||
self._impl.run()
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@ class Button(Widget):
|
|||
super(Button, self).__init__()
|
||||
|
||||
self.on_press = on_press
|
||||
self.label = label
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
self._impl = ButtonImpl.alloc().init()
|
||||
self._impl.interface = self
|
||||
|
||||
self._impl.setBezelStyle_(NSRoundedBezelStyle)
|
||||
self._impl.setButtonType_(NSMomentaryPushInButton)
|
||||
self._impl.setTitle_(get_NSString(label))
|
||||
self._impl.setTitle_(get_NSString(self.label))
|
||||
self._impl.setTarget_(self._impl)
|
||||
self._impl.setAction_(get_selector('onPress:'))
|
||||
self._impl.setTranslatesAutoresizingMaskIntoConstraints_(False)
|
||||
|
|
|
|||
|
|
@ -31,12 +31,28 @@ class Container(Widget):
|
|||
|
||||
def __init__(self):
|
||||
super(Container, self).__init__()
|
||||
self._impl = NSView.alloc().init()
|
||||
self.children = []
|
||||
self.constraints = {}
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
self._impl = NSView.alloc().init()
|
||||
|
||||
for child in self.children:
|
||||
self._add(child)
|
||||
|
||||
for constraint, impl in ((c, i) for c, i in self.constraints.items() if i is None):
|
||||
self._constrain(constraint)
|
||||
|
||||
def add(self, widget):
|
||||
self.children.append(widget)
|
||||
if self._impl:
|
||||
self._add(widget)
|
||||
|
||||
def _add(self, widget):
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
widget.app = self.app
|
||||
self._impl.addSubview_(widget._impl)
|
||||
|
||||
def constrain(self, constraint):
|
||||
|
|
@ -44,6 +60,15 @@ class Container(Widget):
|
|||
if constraint in self.constraints:
|
||||
return
|
||||
|
||||
if self._impl:
|
||||
print ("Add constraint")
|
||||
self._constrain(constraint)
|
||||
|
||||
else:
|
||||
print("Defer constraint until later")
|
||||
self.constraints[constraint] = None
|
||||
|
||||
def _constrain(self, constraint):
|
||||
widget = constraint.attr.widget._impl
|
||||
identifier = constraint.attr.identifier
|
||||
|
||||
|
|
@ -69,5 +94,4 @@ class Container(Widget):
|
|||
)
|
||||
|
||||
self._impl.addConstraint_(constraint._impl)
|
||||
|
||||
self.constraints[constraint] = constraint._impl
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class SplitView(Widget):
|
|||
def __init__(self, direction=VERTICAL):
|
||||
super(SplitView, self).__init__()
|
||||
self.direction = direction
|
||||
|
||||
self._impl = NSSplitView.alloc().init()
|
||||
self._impl.setVertical_(direction)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,14 @@ WindowDelegate = ObjCClass('WindowDelegate')
|
|||
|
||||
class Window(object):
|
||||
def __init__(self, position=(100, 100), size=(640, 480)):
|
||||
self.position = position
|
||||
self.size = size
|
||||
self._impl = None
|
||||
self._app = None
|
||||
|
||||
def _startup(self):
|
||||
self._impl = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
|
||||
NSMakeRect(position[0], position[1], size[0], size[1]),
|
||||
NSMakeRect(self.position[0], self.position[1], self.size[0], self.size[1]),
|
||||
NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask,
|
||||
NSBackingStoreBuffered,
|
||||
False)
|
||||
|
|
@ -29,6 +35,27 @@ class Window(object):
|
|||
|
||||
self._impl.setDelegate_(self._delegate)
|
||||
|
||||
self.on_startup()
|
||||
|
||||
if self.content:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
self.content.app = self.app
|
||||
|
||||
self._impl.setContentView_(self._content._impl)
|
||||
|
||||
@property
|
||||
def app(self):
|
||||
return self._app
|
||||
|
||||
@app.setter
|
||||
def app(self, app):
|
||||
if self._app:
|
||||
raise Exception("Window is already associated with an App")
|
||||
|
||||
self._app = app
|
||||
self._startup()
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
return self._content
|
||||
|
|
@ -36,11 +63,20 @@ class Window(object):
|
|||
@content.setter
|
||||
def content(self, widget):
|
||||
self._content = widget
|
||||
self._impl.setContentView_(self._content._impl)
|
||||
self._content.window = self
|
||||
if self._impl:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
widget.app = self.app
|
||||
|
||||
self._impl.setContentView_(self._content._impl)
|
||||
|
||||
def show(self):
|
||||
self._impl.makeKeyAndOrderFront_(None)
|
||||
# self._impl.visualizeConstraints_(self._impl.contentView().constraints())
|
||||
|
||||
def on_startup(self):
|
||||
pass
|
||||
|
||||
def on_close(self):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -17,17 +17,19 @@ class App(object):
|
|||
# GLib.set_application_name(name.encode('ascii'))
|
||||
self._impl = Gtk.Application(application_id=app_id, flags=Gio.ApplicationFlags.FLAGS_NONE)
|
||||
|
||||
self.main_window = MainWindow(self)
|
||||
self.main_window = MainWindow()
|
||||
|
||||
self._impl.connect('startup', self._startup)
|
||||
self._impl.connect('activate', self._activate)
|
||||
self._impl.connect('shutdown', self._shutdown)
|
||||
|
||||
def _startup(self, data=None):
|
||||
self.main_window.app = self
|
||||
|
||||
self._impl.add_window(self.main_window._impl)
|
||||
|
||||
action = Gio.SimpleAction.new('stuff', None)
|
||||
action.connect('activate', self._on_quit)
|
||||
action.connect('activate', self._quit)
|
||||
self._impl.add_action(action)
|
||||
|
||||
app_name = sys.argv[0]
|
||||
|
|
@ -71,18 +73,28 @@ class App(object):
|
|||
self._impl.set_menubar(self.menu_bar)
|
||||
|
||||
self.main_window.show()
|
||||
self.on_startup()
|
||||
|
||||
def on_startup(self):
|
||||
pass
|
||||
|
||||
def _activate(self, data=None):
|
||||
self.on_activate()
|
||||
|
||||
def on_activate(self):
|
||||
pass
|
||||
|
||||
def _shutdown(self, data=None):
|
||||
self.on_shutdown()
|
||||
|
||||
def on_shutdown(self):
|
||||
pass
|
||||
|
||||
def main_loop(self):
|
||||
self._impl.run(None)
|
||||
|
||||
def _on_quit(self, widget, data=None):
|
||||
self.quit()
|
||||
def _quit(self, widget, data=None):
|
||||
self.on_quit()
|
||||
|
||||
def quit(self):
|
||||
def on_quit(self):
|
||||
self._impl.quit()
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@ def wrapped_handler(widget, handler):
|
|||
class Button(Widget):
|
||||
def __init__(self, label, on_press=None):
|
||||
super(Button, self).__init__()
|
||||
self.label = label
|
||||
self.on_press = on_press
|
||||
# Buttons have a fixed drawn height. If their space allocation is
|
||||
# greater than what is provided, center the button vertically.
|
||||
self._expand_vertical = False
|
||||
|
||||
self.on_press = on_press
|
||||
|
||||
self._impl = Gtk.Button(label=label)
|
||||
def _startup(self):
|
||||
self._impl = Gtk.Button(label=self.label)
|
||||
self._impl.connect("clicked", wrapped_handler(self, self.on_press))
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class GtkContainer(Gtk.Fixed):
|
|||
with self.layout_manager.layout(allocation.width, allocation.height):
|
||||
|
||||
for widget in self.layout_manager.children:
|
||||
print(widget, widget._bounding_box)
|
||||
# print(widget, widget._bounding_box)
|
||||
if not widget._impl.get_visible():
|
||||
print("CHILD NOT VISIBLE")
|
||||
else:
|
||||
|
|
@ -64,11 +64,9 @@ class GtkContainer(Gtk.Fixed):
|
|||
class Container(CassowaryContainer):
|
||||
def __init__(self):
|
||||
super(Container, self).__init__()
|
||||
self._impl = GtkContainer(self._layout_manager)
|
||||
|
||||
def add(self, widget):
|
||||
self._impl.add(widget._impl)
|
||||
self._layout_manager.add_widget(widget)
|
||||
def _create_container(self):
|
||||
return GtkContainer(self._layout_manager)
|
||||
|
||||
@property
|
||||
def _width_hint(self):
|
||||
|
|
|
|||
|
|
@ -7,8 +7,32 @@ class Window(object):
|
|||
_IMPL_CLASS = Gtk.Window
|
||||
|
||||
def __init__(self, position=(100, 100), size=(640, 480)):
|
||||
self._app = None
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
self._impl = self._IMPL_CLASS()
|
||||
self._impl.connect("delete-event", self._on_close)
|
||||
self.on_startup()
|
||||
|
||||
if self.content:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
self.content.app = self.app
|
||||
|
||||
self._impl.add(self.content._impl)
|
||||
|
||||
@property
|
||||
def app(self):
|
||||
return self._app
|
||||
|
||||
@app.setter
|
||||
def app(self, app):
|
||||
if self._app:
|
||||
raise Exception("Window is already associated with an App")
|
||||
|
||||
self._app = app
|
||||
self._startup()
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
|
|
@ -17,11 +41,20 @@ class Window(object):
|
|||
@content.setter
|
||||
def content(self, widget):
|
||||
self._content = widget
|
||||
self._impl.add(self._content._impl)
|
||||
self._content.window = self
|
||||
if self._impl:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
widget.app = self.app
|
||||
|
||||
self._impl.add(self._content._impl)
|
||||
|
||||
def show(self):
|
||||
self._impl.show_all()
|
||||
|
||||
def on_startup(self):
|
||||
pass
|
||||
|
||||
def _on_close(self, widget, data):
|
||||
self.on_close()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,16 @@ from .libs import *
|
|||
from .window import Window
|
||||
from .widgets import *
|
||||
|
||||
|
||||
_apps = {}
|
||||
# The global variable used to store the app instance.
|
||||
_app = None
|
||||
|
||||
|
||||
class MainWindow(Window):
|
||||
def __init__(self):
|
||||
super(MainWindow, self).__init__(self)
|
||||
super(MainWindow, self).__init__()
|
||||
print ("SET BACKGROUND COLOR")
|
||||
|
||||
def _startup(self):
|
||||
super(MainWindow, self)._startup()
|
||||
def on_startup(self):
|
||||
self._impl.backgroundColor = UIColor.whiteColor()
|
||||
|
||||
|
||||
|
|
@ -28,11 +27,7 @@ class AppDelegate_impl(object):
|
|||
@AppDelegate.method('B@@')
|
||||
def application_didFinishLaunchingWithOptions_(self, application, launchOptions):
|
||||
print("FINISHED LAUNCHING")
|
||||
|
||||
# FIXME - there's got to be a better way to pass the Toga instance
|
||||
# into the delegate.
|
||||
app = _apps[None]
|
||||
app._startup()
|
||||
_app._startup()
|
||||
|
||||
return True
|
||||
|
||||
|
|
@ -42,15 +37,17 @@ AppDelegate = ObjCClass('AppDelegate')
|
|||
class App(object):
|
||||
|
||||
def __init__(self, name, app_id):
|
||||
global _app
|
||||
_app = self
|
||||
|
||||
self.name = name
|
||||
self.app_id = app_id
|
||||
|
||||
_apps[None] = self
|
||||
|
||||
self.main_window = MainWindow()
|
||||
|
||||
def _startup(self):
|
||||
self.main_window._startup()
|
||||
# Assign the window to the app; this initiates startup
|
||||
self.main_window.app = self
|
||||
self.main_window.show()
|
||||
|
||||
def main_loop(self):
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ from toga.widget import Widget as WidgetBase
|
|||
|
||||
|
||||
class Widget(WidgetBase):
|
||||
pass
|
||||
pass
|
||||
|
|
@ -22,6 +22,7 @@ class Button(Widget):
|
|||
|
||||
self.on_press = on_press
|
||||
self.label = label
|
||||
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
|
|
|
|||
|
|
@ -45,19 +45,23 @@ class Container(Widget):
|
|||
self._controller.view = self._impl
|
||||
|
||||
for child in self.children:
|
||||
child._startup()
|
||||
self._impl.addSubview_(child._impl)
|
||||
self._add(child)
|
||||
|
||||
for constraint, impl in ((c, i) for c, i in self.constraints.items() if i is None):
|
||||
self._constrain(constraint)
|
||||
self._impl.addConstraint_(constraint._impl)
|
||||
self.constraints[constraint] = constraint._impl
|
||||
|
||||
def add(self, widget):
|
||||
print("ADD SUBVIEW")
|
||||
self.children.append(widget)
|
||||
if self._impl:
|
||||
self._impl.addSubview_(widget._impl)
|
||||
self._add(widget)
|
||||
|
||||
def _add(self, widget):
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
widget.app = self.app
|
||||
|
||||
self._impl.addSubview_(widget._impl)
|
||||
|
||||
def constrain(self, constraint):
|
||||
"Add the given constraint to the widget."
|
||||
|
|
@ -67,8 +71,6 @@ class Container(Widget):
|
|||
if self._impl:
|
||||
print ("Add constraint")
|
||||
self._constrain(constraint)
|
||||
self._impl.addConstraint_(constraint._impl)
|
||||
self.constraints[constraint] = constraint._impl
|
||||
else:
|
||||
print("Defer constraint until later")
|
||||
self.constraints[constraint] = None
|
||||
|
|
@ -98,3 +100,6 @@ class Container(Widget):
|
|||
related_widget, self._IDENTIFIER[related_identifier],
|
||||
multiplier, constant,
|
||||
)
|
||||
|
||||
self._impl.addConstraint_(constraint._impl)
|
||||
self.constraints[constraint] = constraint._impl
|
||||
|
|
|
|||
|
|
@ -3,21 +3,37 @@ from __future__ import print_function, absolute_import, division
|
|||
from .libs import *
|
||||
|
||||
|
||||
|
||||
|
||||
class Window(object):
|
||||
def __init__(self, position=(100, 100), size=(640, 480)):
|
||||
self._app = None
|
||||
self._content = None
|
||||
self._impl = None
|
||||
|
||||
def _startup(self):
|
||||
print ("startup WINDOW")
|
||||
self._impl = UIWindow.alloc().initWithFrame_(UIScreen.mainScreen().bounds())
|
||||
self.on_startup()
|
||||
|
||||
self._content._startup()
|
||||
if self.content:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
self.content.app = self.app
|
||||
|
||||
print("SET ROOT VIEW CONTROLLER")
|
||||
self._impl.addSubview_(self.content._impl)
|
||||
self._impl.rootViewController = self._content._controller
|
||||
print("SET ROOT VIEW CONTROLLER")
|
||||
self._impl.addSubview_(self.content._impl)
|
||||
self._impl.rootViewController = self.content._controller
|
||||
|
||||
@property
|
||||
def app(self):
|
||||
return self._app
|
||||
|
||||
@app.setter
|
||||
def app(self, app):
|
||||
if self._app:
|
||||
raise Exception("Window is already associated with an App")
|
||||
|
||||
self._app = app
|
||||
self._startup()
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
|
|
@ -26,7 +42,13 @@ class Window(object):
|
|||
@content.setter
|
||||
def content(self, widget):
|
||||
self._content = widget
|
||||
self._content.window = self
|
||||
if self._impl:
|
||||
# Assign the widget to the same app as the window.
|
||||
# This initiates startup logic.
|
||||
widget.app = self.app
|
||||
|
||||
# We now know the widget impl exists; add it.
|
||||
self._impl.addSubview_(widget._impl)
|
||||
|
||||
print("SET ROOT VIEW CONTROLLER")
|
||||
|
|
@ -37,3 +59,6 @@ class Window(object):
|
|||
self._impl.makeKeyAndVisible()
|
||||
|
||||
# self._impl.visualizeConstraints_(self._impl.contentView().constraints())
|
||||
|
||||
def on_startup(self):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class App(object):
|
|||
self.main_window = MainWindow()
|
||||
|
||||
def main_loop(self):
|
||||
self.main_window.app = self
|
||||
self.main_window.show()
|
||||
|
||||
# Main message handling loop.
|
||||
|
|
|
|||
|
|
@ -17,20 +17,24 @@ class Button(Widget):
|
|||
self._expand_vertical = False
|
||||
self.label = label
|
||||
self.on_press = on_press
|
||||
self._impl = None
|
||||
self.window = None
|
||||
|
||||
def _create(self, window, x, y, width, height):
|
||||
print "CREATE AT ", x, y, width, height
|
||||
identifier = window._allocate_id()
|
||||
def _startup(self):
|
||||
x, y, width, height = self._geometry
|
||||
print("CREATE AT ", x, y, width, height)
|
||||
identifier = self.window._allocate_id()
|
||||
self._impl = user32.CreateWindowExW(0, c_wchar_p("button"), c_wchar_p(self.label),
|
||||
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_TEXT,
|
||||
int(x), int(y), int(width), int(height),
|
||||
window._impl, identifier, 0, 0)
|
||||
self.window._impl, identifier, 0, 0)
|
||||
|
||||
print "CREATE BUTTON", identifier, self.label
|
||||
window._widgets[identifier] = self
|
||||
print("CREATE BUTTON", identifier, self.label)
|
||||
self.window._widgets[identifier] = self
|
||||
|
||||
def _resize(self, x, y, width, height):
|
||||
print "RESIZE", self.label,x,y,width,height
|
||||
def _resize(self):
|
||||
x, y, width, height = self._geometry
|
||||
print("RESIZE", self.label,x,y,width,height)
|
||||
user32.SetWindowPos(self._impl, HWND_TOP,
|
||||
int(x), int(y), int(width), int(height),
|
||||
0)
|
||||
|
|
@ -42,3 +46,24 @@ class Button(Widget):
|
|||
@property
|
||||
def _height_hint(self):
|
||||
return 30, 30
|
||||
|
||||
@property
|
||||
def _geometry(self):
|
||||
min_width, preferred_width = self._width_hint
|
||||
min_height, preferred_height = self._height_hint
|
||||
|
||||
x_pos = self._bounding_box.x.value
|
||||
if self._expand_horizontal:
|
||||
width = self._bounding_box.width.value
|
||||
else:
|
||||
x_pos = x_pos + ((self._bounding_box.width.value - preferred_width) / 2.0)
|
||||
width = preferred_width
|
||||
|
||||
y_pos = self._bounding_box.y.value
|
||||
if self._expand_vertical:
|
||||
height = self._bounding_box.height.value
|
||||
else:
|
||||
y_pos = y_pos + ((self._bounding_box.height.value - preferred_height) / 2.0)
|
||||
height = preferred_height
|
||||
|
||||
return (x_pos, y_pos, width, height)
|
||||
|
|
|
|||
|
|
@ -3,61 +3,24 @@ from __future__ import print_function, absolute_import, division
|
|||
from toga.cassowary.widget import Container as CassowaryContainer
|
||||
|
||||
|
||||
class Win32Container(object):
|
||||
def add(self, widget):
|
||||
pass
|
||||
|
||||
class Container(CassowaryContainer):
|
||||
def __init__(self):
|
||||
super(Container, self).__init__()
|
||||
self._window = None
|
||||
self.window = None
|
||||
|
||||
def add(self, widget):
|
||||
self._layout_manager.add_widget(widget)
|
||||
if self._window:
|
||||
widget._create(self._window)
|
||||
|
||||
def _create(self, window, x, y, width, height):
|
||||
self._window = window
|
||||
for widget in self._layout_manager.children:
|
||||
|
||||
min_width, preferred_width = widget._width_hint
|
||||
min_height, preferred_height = widget._height_hint
|
||||
|
||||
x_pos = widget._bounding_box.x.value
|
||||
if widget._expand_horizontal:
|
||||
width = widget._bounding_box.width.value
|
||||
else:
|
||||
x_pos = x_pos + ((widget._bounding_box.width.value - preferred_width) / 2.0)
|
||||
width = preferred_width
|
||||
|
||||
y_pos = widget._bounding_box.y.value
|
||||
if widget._expand_vertical:
|
||||
height = widget._bounding_box.height.value
|
||||
else:
|
||||
y_pos = y_pos + ((widget._bounding_box.height.value - preferred_height) / 2.0)
|
||||
height = preferred_height
|
||||
|
||||
widget._create(window, x_pos, y_pos, width, height)
|
||||
|
||||
def _resize(self, x, y, width, height):
|
||||
def _create_container(self):
|
||||
# No impl is requried for a container, but we need a placeholder
|
||||
# to keep the cross-platform logic happy.
|
||||
return Win32Container()
|
||||
|
||||
def _resize(self, width, height):
|
||||
with self._layout_manager.layout(width, height):
|
||||
for widget in self._layout_manager.children:
|
||||
min_width, preferred_width = widget._width_hint
|
||||
min_height, preferred_height = widget._height_hint
|
||||
|
||||
x_pos = widget._bounding_box.x.value
|
||||
if widget._expand_horizontal:
|
||||
width = widget._bounding_box.width.value
|
||||
else:
|
||||
x_pos = x_pos + ((widget._bounding_box.width.value - preferred_width) / 2.0)
|
||||
width = preferred_width
|
||||
|
||||
y_pos = widget._bounding_box.y.value
|
||||
if widget._expand_vertical:
|
||||
height = widget._bounding_box.height.value
|
||||
else:
|
||||
y_pos = y_pos + ((widget._bounding_box.height.value - preferred_height) / 2.0)
|
||||
height = preferred_height
|
||||
|
||||
widget._resize(x_pos, y_pos, width, height)
|
||||
widget._resize()
|
||||
|
||||
@property
|
||||
def _width_hint(self):
|
||||
|
|
|
|||
|
|
@ -4,11 +4,17 @@ from toga.platform.win32.libs import *
|
|||
|
||||
import ctypes
|
||||
|
||||
|
||||
class Window(object):
|
||||
def __init__(self, position=(100, 100), size=(640, 480)):
|
||||
|
||||
self._allocated = 0
|
||||
self._widgets = {}
|
||||
self.position = position
|
||||
self.size = size
|
||||
self._impl = None
|
||||
self._app = None
|
||||
|
||||
def _startup(self):
|
||||
module = kernel32.GetModuleHandleW(None)
|
||||
brush = user32.GetSysColorBrush(COLOR_WINDOW)
|
||||
self._window_class = WNDCLASS()
|
||||
|
|
@ -28,10 +34,10 @@ class Window(object):
|
|||
self._window_class.lpszClassName,
|
||||
u'',
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
position[0],
|
||||
position[0], # CW_USEDEFAULT,
|
||||
size[0],
|
||||
size[1],
|
||||
self.position[0],
|
||||
self.position[1], # CW_USEDEFAULT,
|
||||
self.size[0],
|
||||
self.size[1],
|
||||
0,
|
||||
0,
|
||||
self._window_class.hInstance,
|
||||
|
|
@ -44,7 +50,27 @@ class Window(object):
|
|||
ctypes.windll.UxTheme.SetWindowTheme(self._impl, c_wchar_p('Explorer'), 0)
|
||||
|
||||
user32.SetWindowTextW(self._impl, c_wchar_p("Hello World"))
|
||||
print(2,self._impl)
|
||||
print(2, self._impl)
|
||||
|
||||
self.on_startup()
|
||||
|
||||
if self.content:
|
||||
self.content.app = self.app
|
||||
|
||||
def on_startup(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def app(self):
|
||||
return self._app
|
||||
|
||||
@app.setter
|
||||
def app(self, app):
|
||||
if self._app:
|
||||
raise Exception("Window is already associated with an App")
|
||||
|
||||
self._app = app
|
||||
self._startup()
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
|
|
@ -52,13 +78,10 @@ class Window(object):
|
|||
|
||||
@content.setter
|
||||
def content(self, widget):
|
||||
self._widgets = {}
|
||||
self._content = widget
|
||||
|
||||
min_width, preferred_width = self._content._width_hint
|
||||
min_height, preferred_height = self._content._height_hint
|
||||
|
||||
widget._create(self, 0, 0, preferred_width, preferred_height)
|
||||
self._content.window = self
|
||||
if self._impl:
|
||||
widget.app = self.app
|
||||
|
||||
def show(self):
|
||||
print(3,self._impl)
|
||||
|
|
@ -103,7 +126,7 @@ class Window(object):
|
|||
height = HIWORD(lParam)
|
||||
print("REQUESTED SIZE", width, height)
|
||||
if self._content:
|
||||
self._content._resize(0, 0, width, height)
|
||||
self._content._resize(width, height)
|
||||
return 0
|
||||
|
||||
def _wm_close(self, msg, wParam, lParam):
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ from toga.constraint import Attribute
|
|||
|
||||
class Widget(object):
|
||||
def __init__(self):
|
||||
self._app = None
|
||||
self.window = None
|
||||
|
||||
self.LEFT = Attribute(self, Attribute.LEFT)
|
||||
self.RIGHT = Attribute(self, Attribute.RIGHT)
|
||||
self.TOP = Attribute(self, Attribute.TOP)
|
||||
|
|
@ -16,3 +19,18 @@ class Widget(object):
|
|||
self.CENTER_X = Attribute(self, Attribute.CENTER_X)
|
||||
self.CENTER_Y = Attribute(self, Attribute.CENTER_Y)
|
||||
# self.BASELINE = Attribute(self, Attribute.BASELINE)
|
||||
|
||||
@property
|
||||
def app(self):
|
||||
return self._app
|
||||
|
||||
@app.setter
|
||||
def app(self, app):
|
||||
if self._app:
|
||||
raise Exception("Widget is already associated with an App")
|
||||
|
||||
self._app = app
|
||||
self._startup()
|
||||
|
||||
def _startup(self):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Reference in a new issue