diff options
Diffstat (limited to 'unrpyc/renpy/display/focus.py')
-rw-r--r-- | unrpyc/renpy/display/focus.py | 449 |
1 files changed, 0 insertions, 449 deletions
diff --git a/unrpyc/renpy/display/focus.py b/unrpyc/renpy/display/focus.py deleted file mode 100644 index 521fe22..0000000 --- a/unrpyc/renpy/display/focus.py +++ /dev/null @@ -1,449 +0,0 @@ -# Copyright 2004-2013 Tom Rothamel <pytom@bishoujo.us> -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -# This file contains code to manage focus on the display. - -import pygame -import renpy.display - -class Focus(object): - - def __init__(self, widget, arg, x, y, w, h): - - self.widget = widget - self.arg = arg - self.x = x - self.y = y - self.w = w - self.h = h - - def copy(self): - return Focus( - self.widget, - self.arg, - self.x, - self.y, - self.w, - self.h) - - def __repr__(self): - return "<Focus: %r %r (%r, %r, %r, %r)>" % ( - self.widget, - self.arg, - self.x, - self.y, - self.w, - self.h) - - -# The current focus argument. -argument = None - -# The widget currently grabbing the input, if any. -grab = None - -# The default focus for the current screen. -default_focus = None - -# Sets the currently focused widget. -def set_focused(widget, arg): - global argument - argument = arg - renpy.game.context().scene_lists.focused = widget - -# Gets the currently focused widget. -def get_focused(): - return renpy.game.context().scene_lists.focused - -# Get the mouse cursor for the focused widget. -def get_mouse(): - focused = get_focused() - if focused is None: - return None - else: - return focused.style.mouse - -def set_grab(widget): - global grab - grab = widget - -def get_grab(): - return grab - -# The current list of focuses that we know about. -focus_list = [ ] - -# This takes in a focus list from the rendering system. -def take_focuses(): - global focus_list - focus_list = [ ] - - renpy.display.render.take_focuses(focus_list) - - global default_focus - default_focus = None - - for f in focus_list: - if f.x is None: - default_focus = f - -def focus_coordinates(): - """ - :doc: other - - This attempts to find the coordinates of the currently-focused - displayable. If it can, it will return them as a (x, y, w, h) - tuple. If not, it will return a (None, None, None, None) tuple. - """ - - current = get_focused() - - for i in focus_list: - if i.widget == current and i.arg == argument: - return i.x, i.y, i.w, i.h - - return None, None, None, None - - -# This is called before each interaction. It's purpose is to choose -# the widget that is focused, and to mark it as focused and all of -# the other widgets as unfocused. - -# The new grab widget. (The one that replaced the old grab widget at the start -# of the interaction.) -new_grab = None - -def before_interact(roots): - - global new_grab - global grab - - # a list of focusable, name tuples. - fwn = [ ] - - def callback(f, n): - fwn.append((f, n)) - - for root in roots: - root.find_focusable(callback, None) - - # Assign a full name to each focusable. - - namecount = { } - - for f, n in fwn: - serial = namecount.get(n, 0) - namecount[n] = serial + 1 - - f.full_focus_name = n, serial - - # If there's something with the same full name as the current widget, - # it becomes the new current widget. - - current = get_focused() - - if current is not None: - current_name = current.full_focus_name - - for f, n in fwn: - if f.full_focus_name == current_name: - current = f - set_focused(f, None) - break - else: - current = None - - # Otherwise, focus the default widget, or nothing. - if current is None: - - for f, n in fwn: - if f.default: - current = f - set_focused(f, None) - break - else: - set_focused(None, None) - - # Finally, mark the current widget as the focused widget, and - # all other widgets as unfocused. - for f, n in fwn: - if f is not current: - f.unfocus(default=True) - - if current: - current.focus(default=True) - - grab = new_grab - new_grab = None - -# This changes the focus to be the widget contained inside the new -# focus object. -def change_focus(newfocus, default=False): - rv = None - - if grab: - return - - if newfocus is None: - widget = None - else: - widget = newfocus.widget - - current = get_focused() - - # Nothing to do. - if current is widget and (newfocus is None or newfocus.arg == argument): - return rv - - if current is not None: - current.unfocus(default=default) - - current = widget - - if newfocus is not None: - arg = newfocus.arg - else: - arg = None - - set_focused(current, arg) - - if widget is not None: - rv = widget.focus(default=default) - - return rv - -# This handles mouse events, to see if they change the focus. -def mouse_handler(ev, x, y, default=False): - - if ev.type not in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN): - return - - new_focus = renpy.display.render.focus_at_point(x, y) - - if new_focus is None: - new_focus = default_focus - - return change_focus(new_focus, default=default) - - -# This focuses an extreme widget, which is one of the widgets that's -# at an edge. To do this, we multiply the x, y, width, and height by -# the supplied multiplers, add them all up, and take the focus with -# the largest value. -def focus_extreme(xmul, ymul, wmul, hmul): - - max_focus = None - max_score = -(65536**2) - - for f in focus_list: - - if not f.x: - continue - - score = (f.x * xmul + - f.y * ymul + - f.w * wmul + - f.h * hmul) - - if score > max_score: - max_score = score - max_focus = f - - if max_focus: - return change_focus(max_focus) - - -# This calculates the distance between two points, applying -# the given fudge factors. The distance is left squared. -def points_dist(x0, y0, x1, y1, xfudge, yfudge): - return (( x0 - x1 ) * xfudge ) ** 2 + \ - (( y0 - y1 ) * yfudge ) ** 2 - - -# This computes the distance between two horizontal lines. (So the -# distance is either vertical, or has a vertical component to it.) -# -# The distance is left squared. -def horiz_line_dist(ax0, ay0, ax1, ay1, bx0, by0, bx1, by1): - - # The lines overlap in x. - if bx0 <= ax0 <= ax1 <= bx1 or \ - ax0 <= bx0 <= bx1 <= ax1 or \ - ax0 <= bx0 <= ax1 <= bx1 or \ - bx0 <= ax0 <= bx1 <= ax1: - return (ay0 - by0) ** 2 - - # The right end of a is to the left of the left end of b. - if ax0 <= ax1 <= bx0 <= bx1: - return points_dist(ax1, ay1, bx0, by0, renpy.config.focus_crossrange_penalty, 1.0) - - if bx0 <= bx1 <= ax0 <= ax1: - return points_dist(ax0, ay0, bx1, by1, renpy.config.focus_crossrange_penalty, 1.0) - - assert False - -# This computes the distance between two vertical lines. (So the -# distance is either hortizontal, or has a horizontal component to it.) -# -# The distance is left squared. -def verti_line_dist(ax0, ay0, ax1, ay1, bx0, by0, bx1, by1): - - # The lines overlap in x. - if by0 <= ay0 <= ay1 <= by1 or \ - ay0 <= by0 <= by1 <= ay1 or \ - ay0 <= by0 <= ay1 <= by1 or \ - by0 <= ay0 <= by1 <= ay1: - return (ax0 - bx0) ** 2 - - # The right end of a is to the left of the left end of b. - if ay0 <= ay1 <= by0 <= by1: - return points_dist(ax1, ay1, bx0, by0, 1.0, renpy.config.focus_crossrange_penalty) - - if by0 <= by1 <= ay0 <= ay1: - return points_dist(ax0, ay0, bx1, by1, 1.0, renpy.config.focus_crossrange_penalty) - - assert False - - - -# This focuses the widget that is nearest to the current widget. To -# determine nearest, we compute points on the widgets using the -# {from,to}_{x,y}off values. We pick the nearest, applying a fudge -# multiplier to the distances in each direction, that satisfies -# the condition (which is given a Focus object to evaluate). -# -# If no focus can be found matching the above, we look for one -# with an x of None, and make that the focus. Otherwise, we do -# nothing. -# -# If no widget is focused, we pick one and focus it. -# -# If the current widget has an x of None, we pass things off to -# focus_extreme to deal with. -def focus_nearest(from_x0, from_y0, from_x1, from_y1, - to_x0, to_y0, to_x1, to_y1, - line_dist, - condition, - xmul, ymul, wmul, hmul): - - if not focus_list: - return - - # No widget focused. - current = get_focused() - - if not current: - change_focus(focus_list[0]) - return - - # Find the current focus. - for f in focus_list: - if f.widget is current and f.arg == argument: - from_focus = f - break - else: - # If we can't pick something. - change_focus(focus_list[0]) - return - - # If placeless, focus_extreme. - if from_focus.x is None: - focus_extreme(xmul, ymul, wmul, hmul) - return - - fx0 = from_focus.x + from_focus.w * from_x0 - fy0 = from_focus.y + from_focus.h * from_y0 - fx1 = from_focus.x + from_focus.w * from_x1 - fy1 = from_focus.y + from_focus.h * from_y1 - - placeless = None - new_focus = None - - # a really big number. - new_focus_dist = (65536.0 * renpy.config.focus_crossrange_penalty) ** 2 - - for f in focus_list: - - if f is from_focus: - continue - - if f.x is None: - placeless = f - continue - - if not condition(from_focus, f): - continue - - tx0 = f.x + f.w * to_x0 - ty0 = f.y + f.h * to_y0 - tx1 = f.x + f.w * to_x1 - ty1 = f.y + f.h * to_y1 - - dist = line_dist(fx0, fy0, fx1, fy1, - tx0, ty0, tx1, ty1) - - if dist < new_focus_dist: - new_focus = f - new_focus_dist = dist - - # If we couldn't find anything, try the placeless focus. - new_focus = new_focus or placeless - - # If we have something, switch to it. - if new_focus: - return change_focus(new_focus) - - # And, we're done. - - - -def key_handler(ev): - - if renpy.display.behavior.map_event(ev, 'focus_right'): - return focus_nearest(0.9, 0.1, 0.9, 0.9, - 0.1, 0.1, 0.1, 0.9, - verti_line_dist, - lambda old, new : old.x + old.w <= new.x, - -1, 0, 0, 0) - - if renpy.display.behavior.map_event(ev, 'focus_left'): - return focus_nearest(0.1, 0.1, 0.1, 0.9, - 0.9, 0.1, 0.9, 0.9, - verti_line_dist, - lambda old, new : new.x + new.w <= old.x, - 1, 0, 1, 0) - - if renpy.display.behavior.map_event(ev, 'focus_up'): - return focus_nearest(0.1, 0.1, 0.9, 0.1, - 0.1, 0.9, 0.9, 0.9, - horiz_line_dist, - lambda old, new : new.y + new.h <= old.y, - 0, 1, 0, 1) - - if renpy.display.behavior.map_event(ev, 'focus_down'): - return focus_nearest(0.1, 0.9, 0.9, 0.9, - 0.1, 0.1, 0.9, 0.1, - horiz_line_dist, - lambda old, new : old.y + old.h <= new.y, - 0, -1, 0, 0) - - - |