Refactored code in the structures file for easier structure adding. Added the beginning of a resizable function.
This commit is contained in:
parent
5fa72907cc
commit
067c77ac23
2 changed files with 125 additions and 34 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import colorsys
|
||||||
|
|
||||||
class StructureBase(object):
|
class StructureBase(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -16,8 +17,12 @@ class StructureBase(object):
|
||||||
d[a] = getattr(self, a)
|
d[a] = getattr(self, a)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def _dict_items(self):
|
||||||
|
for a in reversed(self._attrs()):
|
||||||
|
yield a, getattr(self,a)
|
||||||
|
|
||||||
def _dict_string(self):
|
def _dict_string(self):
|
||||||
return ', '.join('{}={}'.format(key, val) for key, val in self._dict().items())
|
return ', '.join('{}={}'.format(key, val) for key, val in self._dict_items())
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return unicode(self)
|
return unicode(self)
|
||||||
|
|
@ -28,6 +33,25 @@ class StructureBase(object):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'{} [{}]'.format(self.__class__.__name__, self._dict_string())
|
return u'{} [{}]'.format(self.__class__.__name__, self._dict_string())
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
eq = True
|
||||||
|
for attr in self._attrs():
|
||||||
|
val = getattr(self, attr)
|
||||||
|
if hasattr(other, attr):
|
||||||
|
eq &= getattr(other, attr) == val
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return eq
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return list(self)[index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._attrs())
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not(self == other)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_like(cls, obj):
|
def is_like(cls, obj):
|
||||||
"""Checks if the object is like the current class
|
"""Checks if the object is like the current class
|
||||||
|
|
@ -37,6 +61,13 @@ class StructureBase(object):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_value(cls, value):
|
||||||
|
try:
|
||||||
|
return cls(*value)
|
||||||
|
except TypeError:
|
||||||
|
return cls()
|
||||||
|
|
||||||
class Position(StructureBase):
|
class Position(StructureBase):
|
||||||
def __init__(self, x=0, y=0):
|
def __init__(self, x=0, y=0):
|
||||||
self.x = x
|
self.x = x
|
||||||
|
|
@ -50,28 +81,15 @@ class Position(StructureBase):
|
||||||
other = Position.from_value(other)
|
other = Position.from_value(other)
|
||||||
return Position(self.x-other.x, self.y-other.y)
|
return Position(self.x-other.x, self.y-other.y)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __iter__(self):
|
||||||
return self.x == other.x and self.y == other.y
|
yield self.x
|
||||||
|
yield self.y
|
||||||
def __ne__(self, other):
|
|
||||||
return not(self == other)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_value(cls, value):
|
|
||||||
if not value:
|
|
||||||
return cls()
|
|
||||||
if cls.is_like(value):
|
|
||||||
return value
|
|
||||||
elif len(value) >= 2:
|
|
||||||
return cls(value[0], value[1])
|
|
||||||
else:
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
|
|
||||||
class Size(StructureBase):
|
class Size(StructureBase):
|
||||||
def __init__(self, width=0, height=0):
|
def __init__(self, width=0, height=0):
|
||||||
self.height = height
|
|
||||||
self.width = width
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
other = Size.from_value(other)
|
other = Size.from_value(other)
|
||||||
|
|
@ -81,23 +99,83 @@ class Size(StructureBase):
|
||||||
other = Size.from_value(other)
|
other = Size.from_value(other)
|
||||||
return Size(self.width-other.width, self.height-other.height)
|
return Size(self.width-other.width, self.height-other.height)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __iter__(self):
|
||||||
return self.width == other.width and self.height == other.height
|
yield self.width
|
||||||
|
yield self.height
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not(self == other)
|
class Color(StructureBase):
|
||||||
|
def __init__(self, r=0, g=0, b=0, a=1):
|
||||||
|
self.r = float(r)
|
||||||
|
self.g = float(g)
|
||||||
|
self.b = float(b)
|
||||||
|
self.a = float(a)
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
"""Blend two colors using self as the background and other as the foreground"""
|
||||||
|
other = Color.from_value(other)
|
||||||
|
r = Color()
|
||||||
|
r.a = 1 - (1-other.a)*(1-self.a)
|
||||||
|
r_a_inv = self.a*(1-other.a)/r.a
|
||||||
|
o_factor = other.a/r.a
|
||||||
|
r.r = other.r*o_factor + self.r*r_a_inv
|
||||||
|
r.g = other.g*o_factor + self.g*r_a_inv
|
||||||
|
r.b = other.b*o_factor + self.b*r_a_inv
|
||||||
|
return r
|
||||||
|
|
||||||
|
def brightness(self, value):
|
||||||
|
h, s, v = colorsys.rgb_to_hsv(self.r, self.g, self.b)
|
||||||
|
v = value
|
||||||
|
self.r, self.g, self.b = colorsys.hsv_to_rgb(h, s, v)
|
||||||
|
|
||||||
|
def hue(self, value):
|
||||||
|
h, s, v = colorsys.rgb_to_hsv(self.r, self.g, self.b)
|
||||||
|
h = value
|
||||||
|
self.r, self.g, self.b = colorsys.hsv_to_rgb(h, s, v)
|
||||||
|
|
||||||
|
def saturation(self, value):
|
||||||
|
h, s, v = colorsys.rgb_to_hsv(self.r, self.g, self.b)
|
||||||
|
s = value
|
||||||
|
self.r, self.g, self.b = colorsys.hsv_to_rgb(h, s, v)
|
||||||
|
|
||||||
|
def from_hsv(self, h, s, v):
|
||||||
|
self.r, self.g, self.b = colorsys.hsv_to_rgb(h, s, v)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield self.r
|
||||||
|
yield self.g
|
||||||
|
yield self.b
|
||||||
|
yield self.a
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def hex_to_rgba(cls, hex_val):
|
||||||
|
"""Converts a hex string in the format 0xFFAABB/CC or an integer to rgba"""
|
||||||
|
if isinstance(hex_val, (long, int)):
|
||||||
|
hexstring = "{0:x}".format(abs(hex_val))
|
||||||
|
elif isinstance(hex_val, basestring):
|
||||||
|
hexstring = hexval[2:]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
if len(hexstring) % 2 != 0:
|
||||||
|
hexstring = '0' + hexstring
|
||||||
|
if len(hexstring) != 6 and len(hexstring) != 8:
|
||||||
|
return None
|
||||||
|
ba = []
|
||||||
|
for i in xrange(0, len(hexstring), 2):
|
||||||
|
ba.append(int(hexstring[i:i+2], 16))
|
||||||
|
c = cls(*ba)
|
||||||
|
return c
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_value(cls, value):
|
def from_value(cls, value):
|
||||||
if not value:
|
try:
|
||||||
|
return cls(*value)
|
||||||
|
except TypeError:
|
||||||
|
c = cls.hex_to_rgba(value)
|
||||||
|
if c is not None:
|
||||||
|
return c
|
||||||
return cls()
|
return cls()
|
||||||
if cls.is_like(value):
|
|
||||||
return value
|
|
||||||
elif len(value) >= 2:
|
|
||||||
return cls(value[0], value[1])
|
|
||||||
else:
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
|
|
||||||
class Rectangle(StructureBase):
|
class Rectangle(StructureBase):
|
||||||
def __init__(self, position=None, size=None):
|
def __init__(self, position=None, size=None):
|
||||||
|
|
@ -118,6 +196,10 @@ class Rectangle(StructureBase):
|
||||||
def position(self, position):
|
def position(self, position):
|
||||||
self._position = Position.from_value(position)
|
self._position = Position.from_value(position)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield list(self.position)
|
||||||
|
yield list(self.size)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
return self._size
|
return self._size
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import cairo
|
import cairo
|
||||||
import math
|
import math
|
||||||
from .structures import Size, Position, Rectangle
|
from .structures import Size, Position, Rectangle, Color
|
||||||
from ..events.events import WindowEventSource
|
from ..events.events import WindowEventSource
|
||||||
|
|
||||||
class Surface(object):
|
class Surface(object):
|
||||||
|
|
@ -44,6 +44,8 @@ class WindowSurface(object):
|
||||||
|
|
||||||
|
|
||||||
def draw_circle(self, position, size, color=(1,1,1), outline_width=1.0, outline_color=(0,0,0), start_angle=0.0, end_angle=360.0):
|
def draw_circle(self, position, size, color=(1,1,1), outline_width=1.0, outline_color=(0,0,0), start_angle=0.0, end_angle=360.0):
|
||||||
|
color = Color.from_value(color)
|
||||||
|
outline_color = Color.from_value(outline_color)
|
||||||
context = self.context
|
context = self.context
|
||||||
position = Position.from_value(position)
|
position = Position.from_value(position)
|
||||||
size = Size.from_value(size)
|
size = Size.from_value(size)
|
||||||
|
|
@ -69,6 +71,8 @@ class WindowSurface(object):
|
||||||
def draw_rounded_rect(self, position, size, color=(1,1,1), outline_width=1, outline_color=(0,0,0), corner_radius=10):
|
def draw_rounded_rect(self, position, size, color=(1,1,1), outline_width=1, outline_color=(0,0,0), corner_radius=10):
|
||||||
position = Position.from_value(position)
|
position = Position.from_value(position)
|
||||||
size = Size.from_value(size)
|
size = Size.from_value(size)
|
||||||
|
color = Color.from_value(color)
|
||||||
|
outline_color = Color.from_value(outline_color)
|
||||||
|
|
||||||
context = self.context
|
context = self.context
|
||||||
radius = corner_radius
|
radius = corner_radius
|
||||||
|
|
@ -85,7 +89,7 @@ class WindowSurface(object):
|
||||||
context.arc(x + radius + outline_width/2.0, y + radius + outline_width/2.0, radius, 180 * degrees, 270 * degrees)
|
context.arc(x + radius + outline_width/2.0, y + radius + outline_width/2.0, radius, 180 * degrees, 270 * degrees)
|
||||||
context.close_path()
|
context.close_path()
|
||||||
|
|
||||||
context.set_source_rgb(*color)
|
context.set_source_rgba(*color)
|
||||||
context.fill_preserve()
|
context.fill_preserve()
|
||||||
context.set_source_rgba(*outline_color)
|
context.set_source_rgba(*outline_color)
|
||||||
context.set_line_width(outline_width)
|
context.set_line_width(outline_width)
|
||||||
|
|
@ -105,7 +109,7 @@ class WindowSurface(object):
|
||||||
|
|
||||||
|
|
||||||
class Window(WindowEventSource, WindowSurface):
|
class Window(WindowEventSource, WindowSurface):
|
||||||
def __init__(self, name, position=None, size=None, context=None, draggable=False):
|
def __init__(self, name, position=None, size=None, context=None, draggable=False, resizable=False):
|
||||||
super(Window, self).__init__()
|
super(Window, self).__init__()
|
||||||
self.context = context
|
self.context = context
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
@ -122,6 +126,10 @@ class Window(WindowEventSource, WindowSurface):
|
||||||
self.focused = False
|
self.focused = False
|
||||||
self.visible = True
|
self.visible = True
|
||||||
self.draggable = draggable
|
self.draggable = draggable
|
||||||
|
self.resizable = resizable
|
||||||
|
|
||||||
|
if resizable:
|
||||||
|
pass
|
||||||
|
|
||||||
if self.draggable:
|
if self.draggable:
|
||||||
self.accept('mouse-left-drag', self.drag)
|
self.accept('mouse-left-drag', self.drag)
|
||||||
|
|
@ -132,7 +140,7 @@ class Window(WindowEventSource, WindowSurface):
|
||||||
obj.position = mouse_pos - self.mouse_diff
|
obj.position = mouse_pos - self.mouse_diff
|
||||||
|
|
||||||
def click(self, obj, mouse_pos):
|
def click(self, obj, mouse_pos):
|
||||||
self.mouse_diff = mouse_pos - self.position
|
self.mouse_diff = mouse_pos - obj.position
|
||||||
|
|
||||||
def click_up(self, obj, mouse_pos):
|
def click_up(self, obj, mouse_pos):
|
||||||
self.mouse_diff = Position(0, 0)
|
self.mouse_diff = Position(0, 0)
|
||||||
|
|
@ -211,6 +219,7 @@ class Window(WindowEventSource, WindowSurface):
|
||||||
if not self.mouse_in:
|
if not self.mouse_in:
|
||||||
print 'mouse-enter', self.name
|
print 'mouse-enter', self.name
|
||||||
self.dispatch('mouse-enter', self)
|
self.dispatch('mouse-enter', self)
|
||||||
|
self.dispatch('hover', self)
|
||||||
self.mouse_in = True
|
self.mouse_in = True
|
||||||
else:
|
else:
|
||||||
if self.mouse_in:
|
if self.mouse_in:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue