Refactor palette positioning API and implementation

This commit is contained in:
Marco Pesenti Gritti 2007-06-29 14:45:04 +02:00
parent 858e43dea9
commit 893ffe92da

View File

@ -23,31 +23,35 @@ import hippo
from sugar.graphics import animator from sugar.graphics import animator
from sugar import _sugarext from sugar import _sugarext
ALIGNMENT_AUTOMATIC = 0 _BOTTOM_LEFT = 0
ALIGNMENT_BOTTOM_LEFT = 1 _BOTTOM_RIGHT = 1
ALIGNMENT_BOTTOM_RIGHT = 2 _LEFT_BOTTOM = 2
ALIGNMENT_LEFT_BOTTOM = 3 _LEFT_TOP = 3
ALIGNMENT_LEFT_TOP = 4 _RIGHT_BOTTOM = 4
ALIGNMENT_RIGHT_BOTTOM = 5 _RIGHT_TOP = 5
ALIGNMENT_RIGHT_TOP = 6 _TOP_LEFT = 6
ALIGNMENT_TOP_LEFT = 7 _TOP_RIGHT = 7
ALIGNMENT_TOP_RIGHT = 8
class Palette(gobject.GObject): class Palette(gobject.GObject):
AUTOMATIC = 0
BOTTOM = 1
LEFT = 2
RIGHT = 3
TOP = 4
__gtype_name__ = 'SugarPalette' __gtype_name__ = 'SugarPalette'
__gproperties__ = { __gproperties__ = {
'invoker' : (object, None, None, 'invoker' : (object, None, None,
gobject.PARAM_READWRITE), gobject.PARAM_READWRITE),
'alignment' : (gobject.TYPE_INT, None, None, 0, 8, 'position' : (gobject.TYPE_INT, None, None, 0, 5,
ALIGNMENT_AUTOMATIC, 0, gobject.PARAM_READWRITE)
gobject.PARAM_READWRITE)
} }
def __init__(self, label, accel_path=None): def __init__(self, label, accel_path=None):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._alignment = ALIGNMENT_AUTOMATIC self._position = self.AUTOMATIC
self._popup_anim = animator.Animator(0.3, 10) self._popup_anim = animator.Animator(0.3, 10)
self._popup_anim.add(_PopupAnimation(self)) self._popup_anim.add(_PopupAnimation(self))
@ -110,77 +114,83 @@ class Palette(gobject.GObject):
if pspec.name == 'invoker': if pspec.name == 'invoker':
self._invoker = value self._invoker = value
self._invoker.add_listener(self) self._invoker.add_listener(self)
elif pspec.name == 'alignment': elif pspec.name == 'position':
self._alignment = value self._position = value
else: else:
raise AssertionError raise AssertionError
def _get_position(self): def _get_position(self, alignment):
if self._alignment == ALIGNMENT_AUTOMATIC:
x, y = self._try_position(ALIGNMENT_BOTTOM_LEFT)
if x == -1:
x, y = self._try_position(ALIGNMENT_BOTTOM_RIGHT)
if x == -1:
x, y = self._try_position(ALIGNMENT_LEFT_BOTTOM)
if x == -1:
x, y = self._try_position(ALIGNMENT_LEFT_TOP)
if x == -1:
x, y = self._try_position(ALIGNMENT_RIGHT_BOTTOM)
if x == -1:
x, y = self._try_position(ALIGNMENT_RIGHT_TOP)
if x == -1:
x, y = self._try_position(ALIGNMENT_LEFT_BOTTOM)
if x == -1:
x, y = self._try_position(ALIGNMENT_LEFT_BOTTOM)
else:
x, y = self._position_for_alignment(self._alignment)
return (x, y)
def _try_position(self, alignment):
x, y = self._position_for_alignment(alignment)
allocation = self._menu.get_allocation()
if (x + allocation.width > gtk.gdk.screen_width()) or \
(y + allocation.height > gtk.gdk.screen_height()):
return (-1, -1)
else:
return (x, y)
def _position_for_alignment(self, alignment):
# Invoker: x, y, width and height # Invoker: x, y, width and height
inv_rect = self._invoker.get_rect() inv_rect = self._invoker.get_rect()
palette_rect = self._menu.get_allocation() palette_rect = self._menu.get_allocation()
if alignment == ALIGNMENT_BOTTOM_LEFT: if alignment == _BOTTOM_LEFT:
move_x = inv_rect.x x = inv_rect.x
move_y = inv_rect.y + inv_rect.height y = inv_rect.y + inv_rect.height
elif alignment == ALIGNMENT_BOTTOM_RIGHT: elif alignment == _BOTTOM_RIGHT:
move_x = (inv_rect.x + inv_rect.width) - palette_rect.width x = (inv_rect.x + inv_rect.width) - palette_rect.width
move_y = inv_rect.y + inv_rect.height y = inv_rect.y + inv_rect.height
elif alignment == ALIGNMENT_LEFT_BOTTOM: elif alignment == _LEFT_BOTTOM:
move_x = inv_rect.x - palette_rect.width x = inv_rect.x - palette_rect.width
move_y = inv_rect.y y = inv_rect.y
elif alignment == ALIGNMENT_LEFT_TOP: elif alignment == _LEFT_TOP:
move_x = inv_rect.x - palette_rect.width x = inv_rect.x - palette_rect.width
move_y = (inv_rect.y + inv_rect.height) - palette_rect.height y = (inv_rect.y + inv_rect.height) - palette_rect.height
elif alignment == ALIGNMENT_RIGHT_BOTTOM: elif alignment == _RIGHT_BOTTOM:
move_x = inv_rect.x + inv_rect.width x = inv_rect.x + inv_rect.width
move_y = inv_rect.y y = inv_rect.y
elif alignment == ALIGNMENT_RIGHT_TOP: elif alignment == _RIGHT_TOP:
move_x = inv_rect.x + inv_rect.width x = inv_rect.x + inv_rect.width
move_y = (inv_rect.y + inv_rect.height) - palette_rect.height y = (inv_rect.y + inv_rect.height) - palette_rect.height
elif alignment == ALIGNMENT_TOP_LEFT: elif alignment == _TOP_LEFT:
move_x = inv_rect.x x = inv_rect.x
move_y = inv_rect.y - palette_rect.height y = inv_rect.y - palette_rect.height
elif alignment == ALIGNMENT_TOP_RIGHT: elif alignment == _TOP_RIGHT:
move_x = (inv_rect.x + inv_rect.width) - palette_rect.width x = (inv_rect.x + inv_rect.width) - palette_rect.width
move_y = inv_rect.y - palette_rect.height y = inv_rect.y - palette_rect.height
return move_x, move_y return x, y
def _in_screen(self, x, y):
allocation = self._menu.get_allocation()
return x + allocation.width < gtk.gdk.screen_width() and \
y + allocation.height < gtk.gdk.screen_height() and \
x >= 0 and y >= 0
def _get_automatic_position(self):
alignments = [ _BOTTOM_LEFT, _BOTTOM_RIGHT,
_LEFT_BOTTOM, _LEFT_TOP,
_RIGHT_BOTTOM, _RIGHT_TOP,
_TOP_LEFT, _TOP_RIGHT ]
for alignment in alignments:
x, y = self._get_position(alignment)
if self._in_screen(x, y):
return x, y
def _show(self): def _show(self):
x, y = self._get_position() x = y = 0
if self._position == self.AUTOMATIC:
x, y = self._get_automatic_position()
elif self._position == self.BOTTOM:
x, y = self._get_position(_BOTTOM_LEFT)
if not self._in_screen(x, y):
x, y = self._get_position(_BOTTOM_RIGHT)
elif self._position == self.LEFT:
x, y = self._get_position(_LEFT_BOTTOM)
if not self._in_screen(x, y):
x, y = self._get_position(_LEFT_TOP)
elif self._position == self.RIGHT:
x, y = self._get_position(_RIGHT_BOTTOM)
if not self._in_screen(x, y):
x, y = self._get_position(_RIGHT_TOP)
elif self._position == self.TOP:
x, y = self._get_position(_TOP_LEFT)
if not self._in_screen(x, y):
x, y = self._get_position(_TOP_RIGHT)
self._menu.popup(x, y) self._menu.popup(x, y)
def _hide(self): def _hide(self):