Added ability to drag windows.

This commit is contained in:
Joey Payne 2014-01-29 15:51:36 -07:00
commit 4cea15f4f1
3 changed files with 129 additions and 46 deletions

View file

@ -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

View file

@ -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:

View file

@ -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: