1# -*- coding: utf-8 -*- 2 3# #################################################################### 4# Copyright (C) 2005-2019 by the FIFE team 5# http://www.fifengine.net 6# This file is part of FIFE. 7# 8# FIFE is free software; you can redistribute it and/or 9# modify it under the terms of the GNU Lesser General Public 10# License as published by the Free Software Foundation; either 11# version 2.1 of the License, or (at your option) any later version. 12# 13# This library is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16# Lesser General Public License for more details. 17# 18# You should have received a copy of the GNU Lesser General Public 19# License along with this library; if not, write to the 20# Free Software Foundation, Inc., 21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22# #################################################################### 23 24""" 25Automatic widget positioning 26============================ 27 28You can use the C{position_technique} attribute 29on top level widgets which can also be set from xml. 30 31For direct use call L{placeWidget}. 32""" 33from __future__ import absolute_import 34 35from .internal import screen_width, screen_height 36from .exceptions import PyChanException 37 38EXPLICIT = "explicit" 39AUTOMATIC = "automatic" 40 41TOP = "top" 42LEFT = "left" 43RIGHT = "right" 44CENTER = "center" 45BOTTOM = "bottom" 46 47 48def _splicePosition(p): 49 if "+" in p: 50 technique,delta = p.split("+") 51 elif "-" in p: 52 technique,delta = p.split("-") 53 delta = '-' + delta 54 else: 55 technique,delta = p,0 56 delta = int(delta) 57 return technique,delta 58 59def _parsePosition(position): 60 try: 61 if position == AUTOMATIC: 62 position = "center+0:center+0" 63 64 x_pos,y_pos = position.split(":") 65 x_pos, x_delta = _splicePosition(x_pos) 66 y_pos, y_delta = _splicePosition(y_pos) 67 68 if x_pos not in [EXPLICIT,LEFT,CENTER,RIGHT]: 69 raise "" 70 if y_pos not in [EXPLICIT,TOP,CENTER,BOTTOM]: 71 raise "" 72 except: 73 raise PyChanException("Malformed position definition: " + repr(position)) 74 return x_pos,x_delta,y_pos,y_delta 75 76def placeWidget(widget,position): 77 """ 78 Place a widget according to a string defining relative coordinates to screen borders. 79 80 The position definition has to be of the form: C{"<x_pos><x_delta>:<y_pos><y_delta>"} 81 82 C{<x_pos>} may be one of: 83 - left 84 - right 85 - center 86 - explicit 87 88 C{<y_pos>} may be one of: 89 - top 90 - bottom 91 - center 92 - explicit 93 94 C{explicit} means that the widgets x or y position will not be touched. The rest should be 95 self explanatory. 96 97 C{<x_delta>} and C{<y_delta>} must be of the form: +pixel_number or -pixel_number. Or completely 98 omitted. Note that the sign has to be there for for positive deltas, too. 99 100 For brevity two shortcuts exist: 101 - "explicit" -> "explicit:explicit" 102 - "automatic" -> "center:center" 103 104 A few examples:: 105 "right-20:top" 106 "center:top+10" 107 "center:center" 108 109 @param widget: The PyChan widget. 110 @param position: A position definition. 111 112 If the position cannot be parsed a L{PyChanException} is thrown. 113 114 """ 115 if position == EXPLICIT: 116 return 117 x_pos,x_delta,y_pos,y_delta = _parsePosition(position) 118 119 x,y = widget.position 120 w,h = widget.size 121 122 if x_pos == CENTER: 123 x = (screen_width() - w) // 2 + x_delta 124 125 if y_pos == CENTER: 126 y = (screen_height() - h) // 2 + y_delta 127 128 if x_pos == LEFT: 129 x = x_delta 130 131 if y_pos == TOP: 132 y = y_delta 133 134 if x_pos == RIGHT: 135 x = screen_width() - w + x_delta 136 137 if y_pos == BOTTOM: 138 y = screen_height() - h + y_delta 139 140 widget.position = x,y 141 142 143 144