def snap(self, x, y, delay=0): """ :doc: drag_drop method Changes the position of the drag. If the drag is not showing, then the position change is instantaneous. Otherwise, the position change takes `delay` seconds, and is animated as a linear move. """ if type(x) is float: x = int(x * self.parent_width) if type(y) is float: y = int(y * self.parent_height) self.target_x = x self.target_y = y if self.x is not None: self.target_at_delay = delay else: self.target_at = self.at self.x = x self.y = y if self.drag_group is not None: self.drag_group.positions[self.drag_name] = (x, y, self.old_position) redraw(self, 0)
def snap(self, x, y, delay=0): """ :doc: drag_drop method Changes the position of the drag. If the drag is not showing, then the position change is instantaneous. Otherwise, the position change takes `delay` seconds, and is animated as a linear move. """ self.target_x = x self.target_y = y if self.x is not None: self.target_at = self.at + delay else: self.target_at = self.at self.x = x self.y = y redraw(self, 0)
def event(self, ev, x, y, st): if not self.is_focused(): return self.child.event(ev, x, y, st) # if not self.draggable: # return self.child.event(ev, x, y, st) # Mouse, in parent-relative coordinates. par_x = int(self.last_x + x) par_y = int(self.last_y + y) grabbed = (renpy.display.focus.get_grab() is self) if grabbed: joined_offsets = self.drag_joined(self) joined = [ i[0] for i in joined_offsets ] elif self.draggable and map_event(ev, "drag_activate"): joined_offsets = self.drag_joined(self) joined = [ i[0] for i in joined_offsets ] if not joined: raise renpy.display.core.IgnoreEvent() renpy.display.focus.set_grab(self) self.grab_x = x self.grab_y = y # If we're not the only thing we're joined with, we # might need to adjust our grab point. for i, xo, yo in joined_offsets: if i is self: self.grab_x += xo self.grab_y += yo break self.drag_moved = False self.start_x = par_x self.start_y = par_y grabbed = True # Handle clicking on droppables. if not grabbed: if self.clicked is not None and map_event(ev, "drag_deactivate"): rv = run(self.clicked) if rv is not None: return rv raise renpy.display.core.IgnoreEvent() return self.child.event(ev, x, y, st) # Handle moves by moving things relative to the grab point. if ev.type in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN): if not self.drag_moved and (self.start_x != par_x or self.start_y != par_y): self.drag_moved = True # We may not be in the drag_joined group. self.set_style_prefix("idle_", True) # Set the style. for i in joined: i.set_style_prefix("selected_hover_", True) # Raise the joined items. if self.drag_raise and self.drag_group is not None: self.drag_group.raise_children(joined) if self.drag_moved: for i, xo, yo in joined_offsets: new_x = int(par_x - self.grab_x + xo) new_y = int(par_y - self.grab_y + yo) new_x = max(new_x, 0) new_x = min(new_x, int(i.parent_width - i.w)) new_y = max(new_y, 0) new_y = min(new_y, int(i.parent_height - i.h)) if i.drag_group is not None and i.drag_name is not None: i.drag_group.positions[i.drag_name] = (new_x, new_y, self.old_position) i.x = new_x i.y = new_y i.target_x = new_x i.target_y = new_y i.target_at = self.at redraw(i, 0) if (self.drag_group is not None) and self.drag_moved: drop = self.drag_group.get_best_drop(joined) else: drop = None if drop is not self.last_drop: if self.last_drop is not None: self.last_drop.set_style_prefix("idle_", True) if drop is not None: drop.set_style_prefix("selected_idle_", True) self.last_drop = drop if map_event(ev, 'drag_deactivate'): renpy.display.focus.set_grab(None) if drop is not None: drop.set_style_prefix("idle_", True) for i in joined: i.set_style_prefix("idle_", True) self.set_style_prefix("hover_", True) self.grab_x = None self.grab_y = None self.last_drop = None if self.drag_moved: # Call the drag callback. drag = joined[0] if drag.dragged is not None: rv = run(drag.dragged, joined, drop) if rv is not None: return rv # Call the drop callback. if drop is not None and drop.dropped is not None: rv = run(drop.dropped, drop, joined) if rv is not None: return rv else: # Call the clicked callback. if self.clicked: rv = run(self.clicked) if rv is not None: return rv raise renpy.display.core.IgnoreEvent()
def render(self, width, height, st, at): child = self.style.child if child is None: child = self.child self.parent_width = width self.parent_height = height cr = render(child, width, height, st, at) cw, ch = cr.get_size() rv = Render(cw, ch) rv.blit(cr, (0, 0)) self.w = cw self.h = ch position = (self.style.xpos, self.style.ypos, self.style.xanchor, self.style.yanchor, self.style.xoffset, self.style.yoffset) # If we don't have a position, then look for it in a drag group. if (self.x is None) and (self.drag_group is not None) and (self.drag_name is not None): if self.drag_name in self.drag_group.positions: dgp = self.drag_group.positions[self.drag_name] if len(dgp) == 3: self.x, self.y, self.old_position = dgp else: self.x, self.y = dgp self.old_position = position if self.old_position != position: place = True elif self.x is None: place = True else: place = False # If we don't have a position, run the placement code and use # that to compute our placement. if place: # This is required to get get_placement to work properly. self.x = None place_x, place_y = self.place(None, 0, 0, width, height, rv) self.x = int(place_x) self.y = int(place_y) self.target_x = None self.old_position = position if self.target_x is None: self.target_x = self.x self.target_y = self.y self.target_at = at # Determine if we need to do the snap animation. if at >= self.target_at: self.x = self.target_x self.y = self.target_y else: done = (at - self.at) / (self.target_at - self.at) self.x = absolute(self.x + done * (self.target_x - self.x)) self.y = absolute(self.y + done * (self.target_y - self.y)) redraw(self, 0) if self.draggable or self.clicked is not None: fx, fy, fw, fh = self.drag_handle if isinstance(fx, float): fx = int(fx * cw) if isinstance(fy, float): fy = int(fy * ch) if isinstance(fw, float): fw = int(fw * cw) if isinstance(fh, float): fh = int(fh * ch) rv.add_focus(self, None, fx, fy, fw, fh, fx, fy, cr.subsurface((fx, fy, fw, fh))) self.last_x = self.x self.last_y = self.y self.at = at return rv
def event(self, ev, x, y, st): if not self.is_focused(): return self.child.event(ev, x, y, st) # if not self.draggable: # return self.child.event(ev, x, y, st) # Mouse, in parent-relative coordinates. par_x = self.last_x + x par_y = self.last_y + y grabbed = (renpy.display.focus.get_grab() is self) if grabbed: joined_offsets = self.drag_joined(self) joined = [i[0] for i in joined_offsets] elif self.draggable and map_event(ev, "drag_activate"): joined_offsets = self.drag_joined(self) joined = [i[0] for i in joined_offsets] if not joined: raise renpy.display.core.IgnoreEvent() renpy.display.focus.set_grab(self) self.grab_x = x self.grab_y = y # If we're not the only thing we're joined with, we # might need to adjust our grab point. for i, xo, yo in joined_offsets: if i is self: self.grab_x += xo self.grab_y += yo break self.drag_moved = False self.start_x = par_x self.start_y = par_y grabbed = True # Handle clicking on droppables. if not grabbed: if self.clicked is not None and map_event(ev, "drag_deactivate"): rv = run(self.clicked) if rv is not None: return rv raise renpy.display.core.IgnoreEvent() return self.child.event(ev, x, y, st) # Handle moves by moving things relative to the grab point. if ev.type in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN): if not self.drag_moved and (self.start_x != par_x or self.start_y != par_y): self.drag_moved = True # We may not be in the drag_joined group. self.set_style_prefix("idle_", True) # Set the style. for i in joined: i.set_style_prefix("selected_hover_", True) # Raise the joined items. if self.drag_raise and self.drag_group is not None: self.drag_group.raise_children(joined) if self.drag_moved: for i, xo, yo in joined_offsets: new_x = par_x - self.grab_x + xo new_y = par_y - self.grab_y + yo new_x = max(new_x, 0) new_x = min(new_x, int(i.parent_width - i.w)) new_y = max(new_y, 0) new_y = min(new_y, int(i.parent_height - i.h)) if i.drag_group is not None and i.drag_name is not None: i.drag_group.positions[i.drag_name] = (new_x, new_y) i.x = new_x i.y = new_y i.target_x = new_x i.target_y = new_y i.target_at = self.at redraw(i, 0) if (self.drag_group is not None) and self.drag_moved: drop = self.drag_group.get_best_drop(joined) else: drop = None if drop is not self.last_drop: if self.last_drop is not None: self.last_drop.set_style_prefix("idle_", True) if drop is not None: drop.set_style_prefix("selected_idle_", True) self.last_drop = drop if map_event(ev, 'drag_deactivate'): renpy.display.focus.set_grab(None) if drop is not None: drop.set_style_prefix("idle_", True) for i in joined: i.set_style_prefix("idle_", True) self.set_style_prefix("hover_", True) self.grab_x = None self.grab_y = None self.last_drop = None if self.drag_moved: # Call the drag callback. drag = joined[0] if drag.dragged is not None: rv = run(drag.dragged, joined, drop) if rv is not None: return rv # Call the drop callback. if drop is not None and drop.dropped is not None: rv = run(drop.dropped, drop, joined) if rv is not None: return rv else: # Call the clicked callback. if self.clicked: rv = run(self.clicked) if rv is not None: return rv raise renpy.display.core.IgnoreEvent()
def render(self, width, height, st, at): child = self.style.child if child is None: child = self.child self.parent_width = width self.parent_height = height cr = render(child, width, height, st, at) cw, ch = cr.get_size() rv = Render(cw, ch) rv.blit(cr, (0, 0)) self.w = cw self.h = ch # If we don't have a position, then look for it in a drag group. if (self.x is None) and (self.drag_group is not None) and (self.drag_name is not None): if self.drag_name in self.drag_group.positions: self.x, self.y = self.drag_group.positions[self.drag_name] # If we don't have a position, run the placement code and use # that to compute our placement. if self.x is None: self.x, self.y = self.place(None, 0, 0, width, height, rv) self.x = int(self.x) self.y = int(self.y) if self.target_x is None: self.target_x = self.x self.target_y = self.y self.target_at = at # Determine if we need to do the snap animation. if at >= self.target_at: self.x = self.target_x self.y = self.target_y else: done = (at - self.at) / (self.target_at - self.at) self.x = absolute(self.x + done * (self.target_x - self.x)) self.y = absolute(self.y + done * (self.target_y - self.y)) redraw(self, 0) if self.draggable or self.clicked is not None: fx, fy, fw, fh = self.drag_handle if isinstance(fx, float): fx = int(fx * cw) if isinstance(fy, float): fy = int(fy * ch) if isinstance(fw, float): fw = int(fw * cw) if isinstance(fh, float): fh = int(fh * ch) rv.add_focus(self, None, fx, fy, fw, fh, fx, fy, cr.subsurface((fx, fy, fw, fh))) self.last_x = self.x self.last_y = self.y self.at = at return rv
def render(self, width, height, st, at): child = self.style.child if child is None: child = self.child self.parent_width = renpy.display.render.render_width self.parent_height = renpy.display.render.render_height cr = render(child, width, height, st, at) cw, ch = cr.get_size() rv = Render(cw, ch) rv.blit(cr, (0, 0)) self.w = cw self.h = ch position = (self.style.xpos, self.style.ypos, self.style.xanchor, self.style.yanchor, self.style.xoffset, self.style.yoffset) # If we don't have a position, then look for it in a drag group. if (self.x is None) and (self.drag_group is not None) and (self.drag_name is not None): if self.drag_name in self.drag_group.positions: dgp = self.drag_group.positions[self.drag_name] if len(dgp) == 3: self.x, self.y, self.old_position = dgp else: self.x, self.y = dgp self.old_position = position if self.old_position != position: place = True elif self.x is None: place = True else: place = False # If we don't have a position, run the placement code and use # that to compute our placement. if place: # This is required to get get_placement to work properly. self.x = None place_x, place_y = self.place(None, 0, 0, width, height, rv) self.x = int(place_x) self.y = int(place_y) self.target_x = None self.old_position = position if self.target_x is None: self.target_x = self.x self.target_y = self.y self.target_at = at # Determine if we need to do the snap animation. if self.target_at_delay: # Snap starts now self.target_at = at + self.target_at_delay self.target_at_delay = 0 redraw(self, 0) elif at >= self.target_at: # Snap complete self.x = self.target_x self.y = self.target_y else: # Snap in progress done = (at - self.at) / (self.target_at - self.at) self.x = absolute(self.x + done * (self.target_x - self.x)) self.y = absolute(self.y + done * (self.target_y - self.y)) redraw(self, 0) if self.draggable or self.clicked is not None: fx, fy, fw, fh = self.drag_handle if isinstance(fx, float): fx = int(fx * cw) if isinstance(fy, float): fy = int(fy * ch) if isinstance(fw, float): fw = int(fw * cw) if isinstance(fh, float): fh = int(fh * ch) mask = self.style.focus_mask if mask is True: mask = cr.subsurface((fx, fy, fw, fh)) elif mask is not None: try: mask = renpy.display.render.render(mask, fw, fh, st, at) except: if callable(mask): mask = mask else: raise Exception( "Focus_mask must be None, True, a displayable, or a callable." ) if mask is not None: fmx = 0 fmy = 0 else: fmx = None fmy = None rv.add_focus(self, None, fx, fy, fw, fh, fmx, fmy, mask) self.last_x = self.x self.last_y = self.y self.at = at return rv
def render(self, width, height, st, at): child = self.style.child if child is None: child = self.child self.parent_width = width self.parent_height = height cr = render(child, width, height, st, at) cw, ch = cr.get_size() rv = Render(cw, ch) rv.blit(cr, (0, 0)) self.w = cw self.h = ch position = (self.style.xpos, self.style.ypos, self.style.xanchor, self.style.yanchor, self.style.xoffset, self.style.yoffset) # If we don't have a position, then look for it in a drag group. if (self.x is None) and (self.drag_group is not None) and (self.drag_name is not None): if self.drag_name in self.drag_group.positions: dgp = self.drag_group.positions[self.drag_name] if len(dgp) == 3: self.x, self.y, self.old_position = dgp else: self.x, self.y = dgp self.old_position = position if self.old_position != position: place = True elif self.x is None: place = True else: place = False # If we don't have a position, run the placement code and use # that to compute our placement. if place: # This is required to get get_placement to work properly. self.x = None place_x, place_y = self.place(None, 0, 0, width, height, rv) self.x = int(place_x) self.y = int(place_y) self.target_x = None self.old_position = position if self.target_x is None: self.target_x = self.x self.target_y = self.y self.target_at = at # Determine if we need to do the snap animation. if self.target_at_delay: # Snap starts now self.target_at = at + self.target_at_delay self.target_at_delay = 0 redraw(self, 0) elif at >= self.target_at: # Snap complete self.x = self.target_x self.y = self.target_y else: # Snap in progress done = (at - self.at) / (self.target_at - self.at) self.x = absolute(self.x + done * (self.target_x - self.x)) self.y = absolute(self.y + done * (self.target_y - self.y)) redraw(self, 0) if self.draggable or self.clicked is not None: fx, fy, fw, fh = self.drag_handle if isinstance(fx, float): fx = int(fx * cw) if isinstance(fy, float): fy = int(fy * ch) if isinstance(fw, float): fw = int(fw * cw) if isinstance(fh, float): fh = int(fh * ch) mask = self.style.focus_mask if mask is True: mask = cr.subsurface((fx, fy, fw, fh)) elif mask is not None: try: mask = renpy.display.render.render(mask, fw, fh, st, at) except: if callable(mask): mask = mask else: raise Exception("Focus_mask must be None, True, a displayable, or a callable.") if mask is not None: fmx = 0 fmy = 0 else: fmx = None fmy = None rv.add_focus(self, None, fx, fy, fw, fh, fmx, fmy, mask) self.last_x = self.x self.last_y = self.y self.at = at return rv
def event(self, ev, x, y, st): if not self.is_focused(): return self.child.event(ev, x, y, st) # Mouse, in parent-relative coordinates. par_x = int(self.last_x + x) par_y = int(self.last_y + y) grabbed = (renpy.display.focus.get_grab() is self) if (self.alternate is not None) and renpy.display.touch and map_event( ev, "drag_activate"): self.click_time = st renpy.game.interface.timeout(renpy.config.longpress_duration) if grabbed: joined_offsets = self.drag_joined(self) joined = [i[0] for i in joined_offsets] elif self.draggable and map_event(ev, "drag_activate"): joined_offsets = self.drag_joined(self) joined = [i[0] for i in joined_offsets] if not joined: raise renpy.display.core.IgnoreEvent() renpy.display.focus.set_grab(self) run(joined[0].activated, joined) self.grab_x = x self.grab_y = y # If we're not the only thing we're joined with, we # might need to adjust our grab point. for i, xo, yo in joined_offsets: if i is self: self.grab_x += xo self.grab_y += yo break self.drag_moved = False self.start_x = par_x self.start_y = par_y grabbed = True elif (self.alternate is not None) and map_event( ev, "button_alternate"): rv = run(self.alternate) if rv is not None: return rv raise renpy.display.core.IgnoreEvent() if ((self.alternate is not None) and renpy.display.touch and (self.click_time is not None) and ((st - self.click_time) > renpy.config.longpress_duration)): self.click_time = None rv = run(self.alternate) if rv is not None: return rv renpy.exports.vibrate(renpy.config.longpress_vibrate) # Handle clicking on droppables. if not grabbed: if self.clicked is not None and map_event(ev, "drag_deactivate"): self.click_time = None rv = run(self.clicked) if rv is not None: return rv raise renpy.display.core.IgnoreEvent() return self.child.event(ev, x, y, st) # Handle moves by moving things relative to the grab point. if ev.type in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN): handled = True if (not self.drag_moved) and (self.start_x != par_x or self.start_y != par_y): self.drag_moved = True self.click_time = None # Raise the joined items. if self.drag_raise and self.drag_group is not None: self.drag_group.raise_children(joined) if self.drag_moved: for i, xo, yo in joined_offsets: new_x = int(par_x - self.grab_x + xo) new_y = int(par_y - self.grab_y + yo) if not self.drag_offscreen: new_x = max(new_x, 0) new_x = min(new_x, int(i.parent_width - i.w)) new_y = max(new_y, 0) new_y = min(new_y, int(i.parent_height - i.h)) if i.drag_group is not None and i.drag_name is not None: i.drag_group.positions[i.drag_name] = ( new_x, new_y, self.old_position) i.x = new_x i.y = new_y i.target_x = new_x i.target_y = new_y i.target_at = self.at redraw(i, 0) else: handled = False if (self.drag_group is not None) and self.drag_moved: if self.mouse_drop: drop = self.drag_group.get_drop_at(joined, par_x, par_y) else: drop = self.drag_group.get_best_drop(joined) else: drop = None if drop is not self.last_drop: if self.last_drop is not None: self.last_drop.set_style_prefix("idle_", True) self.last_drop = drop if self.drag_moved: self.update_style_prefix() if map_event(ev, 'drag_deactivate'): self.click_time = None renpy.display.focus.set_grab(None) if drop is not None: drop.set_style_prefix("idle_", True) for i in joined: i.set_style_prefix("idle_", True) self.set_style_prefix("hover_", True) self.grab_x = None self.grab_y = None self.last_drop = None if self.drag_moved: # Call the drag callback. drag = joined[0] if drag.dragged is not None: rv = run(drag.dragged, joined, drop) if rv is not None: return rv # Call the drop callback. if drop is not None and drop.dropped is not None: rv = run(drop.dropped, drop, joined) if rv is not None: return rv else: # Call the clicked callback. if self.clicked: rv = run(self.clicked) if rv is not None: return rv if handled: raise renpy.display.core.IgnoreEvent()