# HG changeset patch # User Radek Brich # Date 1359502728 -3600 # Node ID cfd3445107b4d8c89c901f341692029bffbcee17 # Parent db2eab0beb4529f4cc2a9ff4cb0f3ba4c21e1667 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected. diff -r db2eab0beb45 -r cfd3445107b4 demo_anchorlayout.py --- a/demo_anchorlayout.py Sun Jan 27 23:51:59 2013 +0100 +++ b/demo_anchorlayout.py Wed Jan 30 00:38:48 2013 +0100 @@ -41,6 +41,11 @@ label_margin.add_handler('draw', self.on_label_margin_draw) win.add(label_margin, halign='center', margin=Borders(t=6)) + label_size = Label(str(self.win.sizereq)) + label_size.name = 'label_size' + label_size.add_handler('draw', self.on_label_size_draw) + win.add(label_size, halign='center', margin=Borders(t=8)) + def on_button_align_click(self, ev): align_type = ev.originator.label.split(':', 1)[0] align = self.win.hints[align_type] @@ -52,6 +57,9 @@ def on_label_margin_draw(self, ev): ev.originator.label = str(self.win.hints['margin']) + def on_label_size_draw(self, ev): + ev.originator.label = str(self.win.sizereq) + def on_top_keypress(self, ev): if ev.keyname == 'escape': self.terminate() diff -r db2eab0beb45 -r cfd3445107b4 sdlterm/cython/sdlterm.pyx --- a/sdlterm/cython/sdlterm.pyx Sun Jan 27 23:51:59 2013 +0100 +++ b/sdlterm/cython/sdlterm.pyx Wed Jan 30 00:38:48 2013 +0100 @@ -17,6 +17,7 @@ cdef struct Event_mouse: int x, y + int relx, rely int button cdef struct Event: @@ -92,13 +93,13 @@ return None event = self.event if event.type == event.MOUSEMOVE: - return ('mousemove', event.mouse.x, event.mouse.y) + return ('mousemove', 0, event.mouse.x, event.mouse.y, event.mouse.relx, event.mouse.rely) if event.type == event.MOUSEDOWN: - return ('mousedown', event.mouse.x, event.mouse.y, event.mouse.button) + return ('mousedown', event.mouse.button, event.mouse.x, event.mouse.y) if event.type == event.MOUSEUP: - return ('mouseup', event.mouse.x, event.mouse.y, event.mouse.button) + return ('mouseup', event.mouse.button, event.mouse.x, event.mouse.y) if event.type == event.MOUSEWHEEL: - return ('mousewheel', event.mouse.x, event.mouse.y, event.mouse.button) + return ('mousewheel', event.mouse.button, event.mouse.x, event.mouse.y) if event.type == event.KEYPRESS: keyname = event.key.keyname if keyname: diff -r db2eab0beb45 -r cfd3445107b4 sdlterm/src/sdlterm.cc --- a/sdlterm/src/sdlterm.cc Sun Jan 27 23:51:59 2013 +0100 +++ b/sdlterm/src/sdlterm.cc Wed Jan 30 00:38:48 2013 +0100 @@ -462,9 +462,14 @@ if (_mousemove_last_x != event.mouse.x || _mousemove_last_y != event.mouse.y) { + if (_mousemove_last_x != -1) + { + event.mouse.relx = event.mouse.x - _mousemove_last_x; + event.mouse.rely = event.mouse.y - _mousemove_last_y; + event_ready = true; + } _mousemove_last_x = event.mouse.x; _mousemove_last_y = event.mouse.y; - event_ready = true; break; } break; // continue loop when mouse position did not change diff -r db2eab0beb45 -r cfd3445107b4 sdlterm/src/sdlterm.h --- a/sdlterm/src/sdlterm.h Sun Jan 27 23:51:59 2013 +0100 +++ b/sdlterm/src/sdlterm.h Wed Jan 30 00:38:48 2013 +0100 @@ -191,6 +191,7 @@ struct { int x, y; + int relx, rely; int button; } mouse; }; diff -r db2eab0beb45 -r cfd3445107b4 tuikit/driver_curses.py --- a/tuikit/driver_curses.py Sun Jan 27 23:51:59 2013 +0100 +++ b/tuikit/driver_curses.py Wed Jan 30 00:38:48 2013 +0100 @@ -318,8 +318,11 @@ if bstate & curses.REPORT_MOUSE_POSITION: if self._mouse_last_pos != (x, y): + if self._mouse_last_pos[0] is not None: + relx = x - (self._mouse_last_pos[0] or 0) + rely = y - (self._mouse_last_pos[1] or 0) + out += [('mousemove', 0, x, y, relx, rely)] self._mouse_last_pos = (x, y) - out += [('mousemove', x, y)] # we are interested only in changes, not buttons already pressed before event if self._mouse_last_bstate is not None: @@ -331,17 +334,17 @@ self._mouse_last_bstate = bstate if bstate & curses.BUTTON1_PRESSED: - out += [('mousedown', x, y, 1)] + out += [('mousedown', 1, x, y)] if bstate & curses.BUTTON2_PRESSED: - out += [('mousedown', x, y, 2)] + out += [('mousedown', 2, x, y)] if bstate & curses.BUTTON3_PRESSED: - out += [('mousedown', x, y, 3)] + out += [('mousedown', 3, x, y)] if bstate & curses.BUTTON1_RELEASED: - out += [('mouseup', x, y, 1)] + out += [('mouseup', 1, x, y)] if bstate & curses.BUTTON2_RELEASED: - out += [('mouseup', x, y, 2)] + out += [('mouseup', 2, x, y)] if bstate & curses.BUTTON3_RELEASED: - out += [('mouseup', x, y, 3)] + out += [('mouseup', 3, x, y)] # reset last pos when pressed/released if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'): @@ -432,26 +435,30 @@ out = [] - if t in (0x20, 0x21, 0x22): # button press + if t in (0x20, 0x21, 0x22): + # button press btn = t - 0x1f if not btn in self.mbtnstack: self.mbtnstack.append(btn) self._mouse_last_pos = (None, None) - out += [('mousedown', x, y, btn)] + out += [('mousedown', btn, x, y)] else: + # mouse move if self._mouse_last_pos != (x, y): + if self._mouse_last_pos[0] is not None: + relx = x - self._mouse_last_pos[0] + rely = y - self._mouse_last_pos[1] + out += [('mousemove', btn, x, y, relx, rely)] self._mouse_last_pos = (x, y) - out += [('mousemove', x, y, btn)] - - elif t == 0x23: # button release + elif t == 0x23: + # button release btn = self.mbtnstack.pop() self._mouse_last_pos = (None, None) - out += [('mouseup', x, y, btn)] - - elif t in (0x60, 0x61): # wheel up, down + out += [('mouseup', btn, x, y)] + elif t in (0x60, 0x61): + # wheel up, down btn = 4 + t - 0x60 - out += [('mousewheel', x, y, btn)] - + out += [('mousewheel', btn, x, y)] else: raise Exception('Unknown mouse event: %x' % t) diff -r db2eab0beb45 -r cfd3445107b4 tuikit/events.py --- a/tuikit/events.py Sun Jan 27 23:51:59 2013 +0100 +++ b/tuikit/events.py Wed Jan 30 00:38:48 2013 +0100 @@ -65,19 +65,25 @@ class MouseEvent(Event): - def __init__(self, x=0, y=0, button=0): + def __init__(self, button=0, x=0, y=0, relx=0, rely=0): Event.__init__(self) - self.x = x # global coordinates + # global coordinates + self.x = x self.y = y - self.wx = x # local widget coordinates + # local widget coordinates + self.wx = x self.wy = y - self.px = 0 # parent coordinates + # parent coordinates + self.px = 0 self.py = 0 + # relative change of coordinates (mousemove) + self.relx = relx + self.rely = rely #: Mouse button: left=1, middle=2, right=3, wheelup=4, wheeldown=5 self.button = button def make_child_event(self, container, child): - ev = MouseEvent(self.x, self.y, self.button) + ev = MouseEvent(self.button, self.x, self.y, self.relx, self.rely) ev.originator = self.originator ev.event_name = self.event_name # original local coordinates are new parent coordinates @@ -89,7 +95,7 @@ return ev def __repr__(self): - return 'MouseEvent(x={0.x},y={0.y},button={0.button})'.format(self) + return 'MouseEvent(button={0.button},x={0.x},y={0.y},relx={0.relx},rely={0.rely})'.format(self) class GenericEvent(Event): diff -r db2eab0beb45 -r cfd3445107b4 tuikit/layout.py --- a/tuikit/layout.py Sun Jan 27 23:51:59 2013 +0100 +++ b/tuikit/layout.py Wed Jan 30 00:38:48 2013 +0100 @@ -82,32 +82,38 @@ child._pos.update(x=x, y=y) child._size.update(w=w, h=h) - def move_child(self, child, x, y): + def move_child(self, child, x=None, y=None): + """Move child inside container by adjusting its margin. + + Operation is supported only for one-side anchors: + left, right, top, bottom + No move on axis where align is set to + center, fill + + """ if not child in self.children: raise ValueError('AnchorLayout.move(): Cannot move foreign child.') margin = child.hints['margin'] - ha = child.hints['halign'].selected - va = child.hints['valign'].selected - ofsx = x - child.x - ofsy = y - child.y - if ha == 'left': - margin.l += ofsx - newx = margin.l - elif ha == 'right': - margin.r -= ofsx - newx = self.width - margin.r - child.sizereq.w - else: - # do not move when halign is center,fill - newx = child.x - if va == 'top': - margin.t += ofsy - newy = margin.t - elif va == 'bottom': - margin.b -= ofsy - newy = self.height - margin.b - child.sizereq.h - else: - # do not move when valign is center,fill - newy = child.y + newx = None + if x is not None: + ha = child.hints['halign'].selected + ofsx = x - child.x + if ha == 'left': + margin.l += ofsx + newx = margin.l + elif ha == 'right': + margin.r -= ofsx + newx = self.width - margin.r - child.sizereq.w + newy = None + if y is not None: + va = child.hints['valign'].selected + ofsy = y - child.y + if va == 'top': + margin.t += ofsy + newy = margin.t + elif va == 'bottom': + margin.b -= ofsy + newy = self.height - margin.b - child.sizereq.h child._pos.update(x=newx, y=newy) diff -r db2eab0beb45 -r cfd3445107b4 tuikit/window.py --- a/tuikit/window.py Sun Jan 27 23:51:59 2013 +0100 +++ b/tuikit/window.py Wed Jan 30 00:38:48 2013 +0100 @@ -86,46 +86,35 @@ def after_mousedown(self, ev): - self.dragstart = (ev.wx, ev.wy) if self.resizable and ev.wx >= self.width - 1 and ev.wy >= self.height - 1: self._resizing = True elif self.movable: self._moving = True - self.origsize = (self.width, self.height) - self.redraw(True) - def after_mouseup(self, ev): - if self._resizing: - self.resize(self.origsize[0] + ev.wx - self.dragstart[0], - self.origsize[1] + ev.wy - self.dragstart[1]) - self._resizing = False - elif self._moving: - self.move(ev.px - self.dragstart[0], - ev.py - self.dragstart[1]) - self._moving = False + self._resize_or_move(ev) + self._resizing = False + self._moving = False + self.redraw(True) + def after_mousemove(self, ev): + self._resize_or_move(ev) self.redraw(True) - - def after_mousemove(self, ev): - if ev.px == self.x + self.dragstart[0] \ - and ev.py == self.y + self.dragstart[1]: - return - - #if x > self.parent.width-self.width: - # return - + def _resize_or_move(self, ev): if self._resizing: - self.resize(self.origsize[0] + ev.wx - self.dragstart[0], - self.origsize[1] + ev.wy - self.dragstart[1]) + self.resize(self.sizereq.w + ev.relx, + self.sizereq.h + ev.rely) + # AnchorLayout, right/bottom align + # also move the window so that it visualy stays in place + if 'halign' in self.hints and self.hints['halign'].selected == 'right': + self.move(x = self.x + ev.relx) + if 'valign' in self.hints and self.hints['valign'].selected == 'bottom': + self.move(y = self.y + ev.rely) elif self._moving: - self.move(ev.px - self.dragstart[0], - ev.py - self.dragstart[1]) - - self.redraw(True) - + self.move(self.x + ev.relx, + self.y + ev.rely) def on_closebtn_click(self, ev): self.hide()