Added ability to drag windows.
This commit is contained in:
parent
0e4f2324f5
commit
4cea15f4f1
3 changed files with 129 additions and 46 deletions
|
|
@ -28,10 +28,14 @@ class EventSource(object):
|
|||
self.events[event].remove(callback)
|
||||
|
||||
class WindowEventSource(EventSource):
|
||||
types = ['mouse-enter', 'mouse-leave',
|
||||
'resize', 'move',
|
||||
'key-repeat', 'key-down', 'key-up',
|
||||
'mouse-right', 'mouse-right-up',
|
||||
'mouse-left', 'mouse-left-up',
|
||||
'mouse-middle', 'mouse-middle-up',
|
||||
'scroll-up', 'scroll-down', 'drag']
|
||||
mouse_events = ['mouse-enter', 'mouse-leave', 'drag', 'mouse-move', 'hover']
|
||||
mouse_wheel_events = ['scroll-up', 'scroll-down']
|
||||
mouse_button_down_events = ['mouse-right', 'mouse-left', 'mouse-middle']
|
||||
mouse_button_drag_events = ['mouse-right-drag', 'mouse-left-drag', 'mouse-middle-drag']
|
||||
mouse_button_up_events = ['mouse-right-up', 'mouse-left-up',
|
||||
'mouse-middle-up']
|
||||
mouse_button_events = mouse_button_down_events + mouse_button_up_events + mouse_button_drag_events
|
||||
window_events = ['resize', 'move', 'focus']
|
||||
key_events = ['key-down', 'key-up', 'key-repeat']
|
||||
types = mouse_events + mouse_wheel_events + mouse_button_events +\
|
||||
window_events + key_events
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ class Position(StructureBase):
|
|||
other = Position.from_value(other)
|
||||
return Position(self.x-other.x, self.y-other.y)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.x == other.x and self.y == other.y
|
||||
|
||||
def __ne__(self, other):
|
||||
return not(self == other)
|
||||
|
||||
@classmethod
|
||||
def from_value(cls, value):
|
||||
if not value:
|
||||
|
|
@ -75,6 +81,12 @@ class Size(StructureBase):
|
|||
other = Size.from_value(other)
|
||||
return Size(self.width-other.width, self.height-other.height)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.width == other.width and self.height == other.height
|
||||
|
||||
def __ne__(self, other):
|
||||
return not(self == other)
|
||||
|
||||
@classmethod
|
||||
def from_value(cls, value):
|
||||
if not value:
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class Surface(object):
|
|||
else:
|
||||
self.context = context
|
||||
self.root_window = Window('root', Position(0,0), self.size, self.context)
|
||||
self.root_window.add_child(Window('child', Position(0,0), [500,200], self.context))
|
||||
self.root_window.add_child(Window('child', Position(0,0), [500,200], self.context, draggable=True))
|
||||
self.windows = [self.root_window]
|
||||
|
||||
def setTopZero(self, context):
|
||||
|
|
@ -21,6 +21,12 @@ class Surface(object):
|
|||
1, 0, 0)
|
||||
context.transform(matrix)
|
||||
|
||||
def inject_mouse_position(self, pos):
|
||||
self.root_window.inject_mouse_position(pos)
|
||||
|
||||
def inject_mouse_down(self, button):
|
||||
self.root_window.inject_mouse_down(button)
|
||||
|
||||
def draw(self):
|
||||
#self.setTopZero(ctx)
|
||||
self.context.identity_matrix()
|
||||
|
|
@ -86,19 +92,20 @@ class WindowSurface(object):
|
|||
context.stroke()
|
||||
|
||||
def render(self):
|
||||
self.draw_rounded_rect([0,0], [self.size.width, self.size.height], outline_width=self.size.width/50)
|
||||
self.draw_rounded_rect([0,0], [self.size.width, self.size.height], outline_width=self.size.width/70)
|
||||
|
||||
def draw(self):
|
||||
self.context.save()
|
||||
self.process_inputs()
|
||||
self.render()
|
||||
for child in self.children:
|
||||
child.draw()
|
||||
self.context.restore()
|
||||
if self.visible:
|
||||
self.context.save()
|
||||
self.process_inputs()
|
||||
self.render()
|
||||
for child in self.children:
|
||||
child.draw()
|
||||
self.context.restore()
|
||||
|
||||
|
||||
class Window(WindowEventSource, WindowSurface):
|
||||
def __init__(self, name, position=None, size=None, context=None):
|
||||
def __init__(self, name, position=None, size=None, context=None, draggable=False):
|
||||
super(Window, self).__init__()
|
||||
self.context = context
|
||||
self.name = name
|
||||
|
|
@ -106,50 +113,110 @@ class Window(WindowEventSource, WindowSurface):
|
|||
self.children = []
|
||||
self.parent = None
|
||||
self.mouse_pos = Position(-1, -1)
|
||||
self.mouse_diff = Position(0, 0)
|
||||
self.mouse_in = False
|
||||
self.mouse_hover = False
|
||||
self.mouse_down = False
|
||||
self.old_mouse_down = False
|
||||
self.mouse_inputs = dict.fromkeys(self.mouse_button_down_events, False)
|
||||
self.focused = False
|
||||
self.visible = True
|
||||
self.draggable = draggable
|
||||
|
||||
def injectMouseDown(self, button):
|
||||
self.mouse_down = True
|
||||
if self.draggable:
|
||||
self.accept('mouse-left-drag', self.drag)
|
||||
self.accept('mouse-left', self.click)
|
||||
self.accept('mouse-left-up', self.click_up)
|
||||
|
||||
def injectMouseUp(self, button):
|
||||
self.mouse_down = False
|
||||
def drag(self, obj, mouse_pos):
|
||||
obj.position = mouse_pos - self.mouse_diff
|
||||
|
||||
def injectMousePosition(self, pos):
|
||||
self.mouse_pos = Position.from_value(pos)
|
||||
def click(self, obj, mouse_pos):
|
||||
self.mouse_diff = mouse_pos - self.position
|
||||
|
||||
def click_up(self, obj, mouse_pos):
|
||||
self.mouse_diff = Position(0, 0)
|
||||
|
||||
def show(self):
|
||||
self.visible = True
|
||||
|
||||
def hide(self):
|
||||
self.visible = False
|
||||
|
||||
def inject_mouse_down(self, button):
|
||||
if self.mouse_inside():
|
||||
print button, self.name
|
||||
self.mouse_inputs[button] = True
|
||||
self.mouse_down = True
|
||||
self.grab_focus()
|
||||
self.dispatch(button, self, self.mouse_pos)
|
||||
else:
|
||||
self.release_focus()
|
||||
for child in self.children:
|
||||
child.injectMousePosition(pos)
|
||||
child.inject_mouse_down(button)
|
||||
|
||||
def has_mouse_focus(self):
|
||||
def inject_mouse_up(self, button):
|
||||
if self.mouse_inside() and self.mouse_inputs[button]:
|
||||
print button+'-up', self.name
|
||||
self.mouse_down = False
|
||||
self.mouse_inputs[button] = False
|
||||
self.dispatch('{}-up'.format(button), self, self.mouse_pos)
|
||||
for child in self.children:
|
||||
child.inject_mouse_up(button)
|
||||
|
||||
def inject_mouse_position(self, pos):
|
||||
mouse_pos = Position.from_value(pos)
|
||||
diff = mouse_pos - self.mouse_pos
|
||||
if diff != Position(0,0):
|
||||
self.dispatch('mouse-move', self, self.mouse_pos, mouse_pos)
|
||||
if self.focused and self.mouse_down:
|
||||
for button, down in self.mouse_inputs.items():
|
||||
if down:
|
||||
self.dispatch('{}-drag'.format(button), self, self.mouse_pos)
|
||||
self.mouse_pos = mouse_pos
|
||||
for child in self.children:
|
||||
child.inject_mouse_position(pos)
|
||||
|
||||
def grab_focus(self):
|
||||
self.focused = True
|
||||
|
||||
def release_focus(self):
|
||||
if self.focused:
|
||||
print 'released', self.name
|
||||
self.focused = False
|
||||
self.mouse_down = False
|
||||
#clear events that may have been triggered
|
||||
#eg. User clicks on one window, holds, and
|
||||
#then releases on another
|
||||
for key in self.mouse_inputs:
|
||||
self.mouse_inputs[key] = False
|
||||
|
||||
|
||||
def mouse_inside(self):
|
||||
res = self.rectangle.intersects_with(self.mouse_pos)
|
||||
for child in self.children:
|
||||
res &= not child.has_mouse_focus()
|
||||
res &= not child.mouse_inside()
|
||||
return res
|
||||
|
||||
def mouse_held(self):
|
||||
res = self.mouse_down
|
||||
for child in self.children:
|
||||
res |= child.mouse_down
|
||||
return res
|
||||
|
||||
def process_inputs(self):
|
||||
mouse_focus = self.has_mouse_focus()
|
||||
if mouse_focus:
|
||||
if not self.mouse_in:
|
||||
print 'mouse-enter'
|
||||
self.dispatch('mouse-enter', self)
|
||||
self.mouse_in = True
|
||||
else:
|
||||
if self.mouse_in:
|
||||
print 'mouse-leave'
|
||||
self.dispatch('mouse-leave', self)
|
||||
self.mouse_in = False
|
||||
|
||||
if self.mouse_in and self.mouse_down and not self.old_mouse_down:
|
||||
print 'mousedown'
|
||||
self.dispatch('mouse-left', self, self.mouse_pos)
|
||||
self.old_mouse_down = True
|
||||
elif self.mouse_in and not self.mouse_down and self.old_mouse_down:
|
||||
print 'mouseup'
|
||||
self.dispatch('mouse-left-up', self, self.mouse_pos)
|
||||
self.old_mouse_down = False
|
||||
|
||||
mouse_focus = self.mouse_inside()
|
||||
if not self.mouse_held():
|
||||
if mouse_focus:
|
||||
if not self.mouse_in:
|
||||
print 'mouse-enter', self.name
|
||||
self.dispatch('mouse-enter', self)
|
||||
self.mouse_in = True
|
||||
else:
|
||||
if self.mouse_in:
|
||||
print 'mouse-leave', self.name
|
||||
self.dispatch('mouse-leave', self)
|
||||
self.mouse_in = False
|
||||
|
||||
def add_child(self, child_window):
|
||||
if child_window not in self.children:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue