| Server IP : 182.53.201.61 / Your IP : 216.73.217.175 Web Server : Apache/2.2.15 (Fedora) System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 User : apache ( 48) PHP Version : 5.3.3 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/system-config-lvm/ |
Upload File : |
import math
import operator
import pygtk
import gtk, gtk.gdk
class Widget:
def __init__(self):
self.left_clickable = False
self.right_clickable = False
self.objects = {}
def draw(self, dc, gc, (x, y)):
pass
def click(self, (x, y), leftClick): # local coordinates
return None # nothing selected
def add_object(self, id, obj):
self.objects[id] = obj
def get_object(self, id):
return self.objects[id]
class Highlight:
def __init__(self):
self.highlighted = False
self.also_highlight = []
def add_highlightable(self, obj):
self.also_highlight.append(obj)
def remove_highlightable(self, obj):
self.also_highlight.remove(obj)
def highlight(self):
for ch in self.also_highlight:
ch.highlighted = True
def unhighlight(self):
for ch in self.also_highlight:
ch.highlighted = False
class CylinderItem(Widget):
def __init__(self,
selectable=False,
width=0,
height=0,
label_upper='',
label_lower=''):
Widget.__init__(self)
self.children = []
self.ratio = 1 # pixels/width
self.width = width
self.height = height
self.selectable = selectable
self.selected = False
self.label_upper = label_upper
self.LU_showAlways = True
self.LU_showAtSelected = False
self.LU_showAtHighlighted = False
self.label_lower = label_lower
self.LL_showAlways = True
self.LL_showAtSelected = False
self.LL_showAtHighlighted = False
self.highlighted = False
self.anchors = {}
def set_label_upper(self, text, showAlways=True, showAtSelected=False, showAtHighlighted=False):
self.label_upper = text
self.LU_showAlways = showAlways
self.LU_showAtSelected = showAtSelected
self.LU_showAtHighlighted = showAtHighlighted
def set_label_lower(self, text, showAlways=True, showAtSelected=False, showAtHighlighted=False):
self.label_lower = text
self.LL_showAlways = showAlways
self.LL_showAtSelected = showAtSelected
self.LL_showAtHighlighted = showAtHighlighted
def get_label_upper(self):
return self.label_upper
def get_label_lower(self):
return self.label_lower
def get_selected(self):
return self.selected
def set_selected(self, bool):
self.selected = bool
for child in self.children:
child.set_selected(bool)
def set_height(self, height):
self.height = height
for child in self.children:
child.set_height(height)
def draw(self, dc, gc, (x, y)):
x = x + self.get_width()
self.children.reverse()
for child in self.children:
x = x - child.get_width()
child.draw(dc, gc, (x, y))
self.children.reverse()
def get_labels_upper(self):
return self.__get_labels(True)
def get_labels_lower(self):
return self.__get_labels(False)
def __get_labels(self, upper):
labels = []
if upper:
if self.label_upper != '':
if self.LU_showAlways or (self.selected and self.LU_showAtSelected) or (self.highlighted and self.LU_showAtHighlighted):
offset = self.get_width() / 2
labels.append((self.label_upper, offset))
else:
if self.label_lower != '':
if self.LL_showAlways or (self.selected and self.LL_showAtSelected) or (self.highlighted and self.LL_showAtHighlighted):
offset = self.get_width() / 2
labels.append((self.label_lower, offset))
# set offset of childrens' labels
offset = 0
for child in self.children:
ch_labels = child.__get_labels(upper)
for label in ch_labels:
labels.append((label[0], label[1] + offset))
offset = offset + child.get_width()
return labels
def get_smallest_selectable_width(self):
maximum = 100000000
smallest = maximum
for child in self.children:
width = child.get_smallest_selectable_width()
if width == 0:
continue
if width < smallest:
smallest = width
if self.get_width() < smallest and self.selectable:
smallest = self.get_width()
if smallest == maximum:
return 0
else:
return smallest
def get_width(self): # returns width adjusted by ratio
if self.width != 0:
# end_node
width = int(self.width * self.ratio)
if width == 0:
return 1
return width
width = 0
for child in self.children:
width = width + child.get_width()
return width
def get_adjustable_width(self): # get width that is adjustable by ratio
if self.width != 0:
# end_node
adjustable_width = int(self.width * self.ratio)
return adjustable_width
adjustable_width = 0
for child in self.children:
adjustable_width = adjustable_width + child.get_adjustable_width()
return adjustable_width
def set_ratio(self, ratio):
self.ratio = ratio
for child in self.children:
child.set_ratio(ratio)
def get_ratio(self):
return self.ratio
def click(self, (x, y), leftClick):
if x > self.get_width():
return None
if self.selectable and leftClick and self.left_clickable:
#print 'left clicked'
return self
if self.right_clickable and not leftClick:
#print 'right clicked'
return self
# propagate click
offset = 0
for child in self.children:
child_width = child.get_width()
if (x > offset) and (x < offset + child_width):
return child.click((x - offset, y), leftClick)
offset = offset + child_width
return None
def set_anchor(self, id, perc):
self.anchors[id] = perc
def get_anchors(self):
anchors = []
width = self.get_width()
if self.selected or self.highlighted:
for id in self.anchors:
anchors.append((id, int(width * self.anchors[id])))
# set offset of childrens' anchors
offset = 0
for child in self.children:
for anchor in child.get_anchors():
anchors.append((anchor[0], anchor[1] + offset))
offset = offset + child.get_width()
return anchors
class Separator(CylinderItem):
def __init__(self, width=1, cyl_gen=None, pattern_id=0):
CylinderItem.__init__(self, False, width)
self.cyl_gen = cyl_gen
self.pattern_id = pattern_id
def get_width(self):
# no ratio adjustment
return self.width
def get_adjustable_width(self):
return 0
def get_smallest_selectable_width(self):
return 0
def draw(self, dc, gc, (x, y)):
if self.cyl_gen == None:
return
cyl_pix = self.cyl_gen.get_pattern(self.pattern_id, dc, self.get_width(), self.height)
dc.draw_pixbuf(gc, cyl_pix, 0, 0, x, y)
class End(CylinderItem):
def __init__(self, cyl_gen):
CylinderItem.__init__(self)
self.cyl_gen = cyl_gen
def draw(self, dc, gc, (x, y)):
self.cyl_gen.draw_end(dc, gc, x, y, self.height)
def get_smallest_selectable_width(self):
return 0
class Subcylinder(CylinderItem, Highlight):
def __init__(self,
cyl_gen=None,
selectedPattern=None,
highlightedPattern=None,
selectable=False,
width=0):
CylinderItem.__init__(self, selectable, width, 0)
Highlight.__init__(self)
if selectable:
self.left_clickable = True
#self.right_clickable = True
self.cyl_gen = cyl_gen
self.selectedPattern = selectedPattern
self.highlightedPattern = highlightedPattern
def set_patterns(self, selected, highlighted):
self.selectedPattern = selected
self.highlightedPattern = highlighted
def set_selected(self, bool):
CylinderItem.set_selected(self, bool)
if bool:
self.highlight()
else:
self.unhighlight()
def draw(self, dc, gc, (x, y)):
# draw children
CylinderItem.draw(self, dc, gc, (x, y))
if self.cyl_gen == None:
return
# draw self
if self.width != 0:
cyl_pix = self.cyl_gen.get_cyl(dc, self.get_width(), self.height)
dc.draw_pixbuf(gc, cyl_pix, 0, 0, x, y)
# draw highlighted pattern
if self.highlighted:
cyl_pix = self.cyl_gen.get_pattern(self.highlightedPattern, dc, self.get_width(), self.height)
dc.draw_pixbuf(gc, cyl_pix, 0, 0, x, y)
# draw selection pattern
if self.selected:
cyl_pix = self.cyl_gen.get_pattern(self.selectedPattern, dc, self.get_width(), self.height)
dc.draw_pixbuf(gc, cyl_pix, 0, 0, x, y)
def click(self, (x, y), leftClick): # local coordinates
selection = CylinderItem.click(self, (x, y), leftClick)
if leftClick:
# left click handling
return selection
else:
# right click handling
return selection
class SingleCylinder:
def __init__(self,
exclusive_selection,
name='',
label='',
smallest_clickable_width=1,
width=200, # fullfilled only if smallest_clickable_width is met
height=1):
self.cyl = Subcylinder()
self.cyl_drawn_at = (0, 0)
self.width = width
self.height = height
self.exclusive_selection = exclusive_selection
self.selection = []
self.name = name
self.label = label
self.label_to_cyl_distance = 10
self.smallest_clickable_width = smallest_clickable_width
self.respect_smallest_selectable_width(True)
def respect_smallest_selectable_width(self, bool):
self.respect_selectable_width = bool
self.__adjust_width()
def get_smallest_selectable_width(self):
return self.cyl.get_smallest_selectable_width()
def get_selection(self):
return self.selection
def click(self, (x, y), leftClick):
(ellipse_table, x_radius) = get_ellipse_table(self.height/2)
cyl_x = self.cyl_drawn_at[0]
cyl_y = self.cyl_drawn_at[1]
if not (y > cyl_y and y < cyl_y + self.height):
return None
if not (x > cyl_x and x < cyl_x + self.cyl.get_width() + x_radius):
return None
# click is in a rectangle, change to local coordinates
y = y - cyl_y
x = x - cyl_x - ellipse_table[y]
if x < 0:
return None
selected = self.cyl.click((x, y), leftClick) # local coordinates
if leftClick:
if selected in self.selection:
selected.set_selected(False)
self.selection.remove(selected)
return
if self.exclusive_selection:
# single selection only
if selected != None:
if len(self.selection) != 0:
self.selection[0].set_selected(False)
self.selection = []
selected.set_selected(True)
self.selection.append(selected)
else:
if selected != None:
selected.set_selected(True)
self.selection.append(selected)
def append_right(self, child):
self.cyl.children.append(child)
self.cyl.set_height(self.height)
self.__adjust_width()
def __adjust_width(self):
self.cyl.set_ratio(1)
width = self.cyl.get_width()
if width == 0:
return
else:
self.cyl.set_ratio(float(self.width)/width)
if self.respect_selectable_width:
smallest = self.cyl.get_smallest_selectable_width()
if smallest == 0:
return
elif smallest < self.smallest_clickable_width:
self.cyl.set_ratio(1)
smallest = self.cyl.get_smallest_selectable_width()
self.cyl.set_ratio(self.smallest_clickable_width/float(smallest))
def set_height(self, height):
self.height = height
self.cyl.set_height(height)
def get_height(self):
return self.height
def set_width(self, width):
self.width = width
self.__adjust_width()
def get_width(self):
return self.width
def get_adjusted_width(self):
return self.cyl.get_width()
def minimum_pixmap_dimension(self, da):
# cylinder dimension
cyl_dim = (2 * get_ellipse_table(self.height/2)[1] + self.cyl.get_width(), self.height)
# labels dimensions
# main
layout = da.create_pango_layout('')
layout.set_markup(self.label)
main_label_dim = layout.get_pixel_size()
# upper
upper_label_dim = draw_cyl_labels_upper(da, None, None,
self.cyl.get_labels_upper(),
0, 0,
False)
# lower
lower_label_dim = draw_cyl_labels_lower(da, None, None,
self.cyl.get_labels_lower(),
0, 0,
self.height,
False)
# width
max_cyl_w = cyl_dim[0]
ellipse_w = get_ellipse_table(self.height/2)[1]
if upper_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = upper_label_dim[0] + ellipse_w
if lower_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = lower_label_dim[0] + ellipse_w
width = main_label_dim[0] + self.label_to_cyl_distance + max_cyl_w
# height
height = upper_label_dim[1] + cyl_dim[1] + lower_label_dim[1]
if main_label_dim[1] > height:
height = mail_label_dim[1]
return width, height, upper_label_dim[1]
def draw(self, da, gc, (x, y)):
dc = da.window
(w, h) = dc.get_size()
pixmap = gtk.gdk.Pixmap(dc, w, h) # buffer
# adjust y for upper label height
upper_label_height = draw_cyl_labels_upper(da, None, None,
self.cyl.get_labels_upper(),
0, 0,
False)[1]
y = y + upper_label_height
# clear
front = gc.foreground
gc.foreground = gc.background
pixmap.draw_rectangle(gc, True, 0, 0, w, h)
gc.foreground = front
# draw name
#layout = da.create_pango_layout(self.name)
#label_w, label_h = layout.get_pixel_size()
#pixmap.draw_layout(gc, x, y + (self.height - label_h) / 2, layout)
# draw main label
layout = da.create_pango_layout('')
layout.set_markup(self.label)
label_w, label_h = layout.get_pixel_size()
pixmap.draw_layout(gc,
x, y + (self.height-label_h)/2,
layout)
# draw cylinder
x = x + label_w + get_ellipse_table(self.height/2)[1] + self.label_to_cyl_distance
self.cyl.draw(pixmap, gc, (x, y))
self.cyl_drawn_at = (x, y)
# draw labels
draw_cyl_labels_upper(da, pixmap, gc,
self.cyl.get_labels_upper(),
x, y)
draw_cyl_labels_lower(da, pixmap, gc,
self.cyl.get_labels_lower(),
x, y, self.height)
# double buffering
dc.draw_drawable(gc, pixmap, 0, 0, 0, 0, w, h)
def draw_cyl_labels_upper(da, pixmap, gc, labels, x, y, draw=True):
# sort
labels_t = labels
labels = []
while len(labels_t) != 0:
largest = labels_t[0]
for label in labels_t:
if label[1] > largest[1]:
largest = label
labels_t.remove(largest)
labels.append(largest)
width_total, height_total = 0, 0 # dimensions of encompasing rectangle
X_boundry = 1000000 # used for offset adjustment
offset_default = 0
offset = offset_default
length = 30
for label in labels:
layout = da.create_pango_layout('')
layout.set_markup(label[0])
label_w, label_h = layout.get_pixel_size()
X1 = x + label[1]
Y1 = y
X2 = X1 - int(math.cos(math.pi/4) * length)
Y2 = Y1 - int(math.sin(math.pi/4) * length)
X3 = X2
if X2 + label_w + 3 > X_boundry:
offset = offset + label_h
else:
offset = offset_default
Y3 = Y2 - offset - label_h / 2
X_boundry = X2
if draw:
pixmap.draw_line(gc, X1, Y1, X2, Y2)
pixmap.draw_line(gc, X2, Y2, X3, Y3)
X_lay = X2 + 2
Y_lay = Y3 - label_h/2
if draw:
backup = gc.foreground
gc.foreground = gc.background
pixmap.draw_rectangle(gc, True, X_lay, Y_lay, label_w, label_h)
gc.foreground = backup
pixmap.draw_layout(gc, X_lay, Y_lay, layout)
# calculate dimension of encompasing rectangle
max_w_tmp = X_lay + label_w - x
max_h_tmp = y - Y_lay
if max_w_tmp > width_total:
width_total= max_w_tmp
if max_h_tmp > height_total:
height_total= max_h_tmp
return width_total, height_total
def draw_cyl_labels_lower(da, pixmap, gc, labels, x, y, cyl_height, draw=True):
# sort
labels_t = labels
labels = []
while len(labels_t) != 0:
largest = labels_t[0]
for label in labels_t:
if label[1] > largest[1]:
largest = label
labels_t.remove(largest)
labels.append(largest)
width_total, height_total = 0, 0 # dimensions of encompasing rectangle
X_boundry = 1000000 # used for offset adjustment
height = int(cyl_height * 5 / 8)
X_offset = get_ellipse_table(cyl_height/2)[0][height]
offset_default = cyl_height - height + 10
offset = offset_default
for label in labels:
layout = da.create_pango_layout('')
layout.set_markup(label[0])
label_w, label_h = layout.get_pixel_size()
X1 = x + label[1] + X_offset
Y1 = y + height
X2 = X1
Y2 = Y1 + label_h
X3 = X2 + label_w
if X3 + 3 > X_boundry:
offset = offset + label_h + 1
else:
offset = offset_default
Y2 = Y2 + offset
Y3 = Y2
X_boundry = X1
if draw:
pixmap.draw_line(gc, X1, Y1, X2, Y2)
pixmap.draw_line(gc, X2, Y2, X3, Y3)
X_lay = X2 + 2
Y_lay = Y2 - label_h
if draw:
back = gc.foreground
gc.foreground = gc.background
pixmap.draw_rectangle(gc, True, X_lay, Y_lay, label_w, label_h)
gc.foreground = back
pixmap.draw_layout(gc, X_lay, Y_lay, layout)
# calculate dimension of encompasing rectangle
max_w_tmp = X3 - x
max_h_tmp = Y3 - (cyl_height + y)
if max_w_tmp > width_total:
width_total = max_w_tmp
if max_h_tmp > height_total:
height_total = max_h_tmp
return width_total, height_total
class DoubleCylinder:
def __init__(self,
distance,
name='',
label_upper='',
label_lower='',
smallest_clickable_width=1,
width=200, # fullfilled only if smallest_clickable_width is met
height=1):
self.cyl_upper = Subcylinder()
self.cyl_lower = Subcylinder()
self.cyl_upper_drawn_at = (0, 0)
self.cyl_lower_drawn_at = (0, 0)
self.label_upper = label_upper
self.label_lower = label_lower
self.distance = distance
self.label_to_cyl_distance = 10
self.selection = None
self.name = name
self.width = width
self.height = height
self.smallest_clickable_width = smallest_clickable_width
self.respect_smallest_selectable_width(True)
def respect_smallest_selectable_width(self, bool):
self.respect_selectable_width = bool
self.__adjust_width()
def get_smallest_selectable_width(self):
upper = self.cyl_upper.get_smallest_selectable_width()
lower = self.cyl_lower.get_smallest_selectable_width()
if upper == 0:
return lower
elif lower == 0:
return upper
smaller = 0
if upper > lower:
smaller = lower
else:
smaller = upper
return smaller
def get_selection(self):
if self.selection == None:
return []
return [self.selection]
def click(self, (x, y), leftClick):
(ellipse_table, x_radius) = get_ellipse_table(self.height/2)
cyl = None
cyl_x = self.cyl_upper_drawn_at[0]
cyl_y = self.cyl_upper_drawn_at[1]
if x > cyl_x and x < cyl_x + self.cyl_upper.get_width() + x_radius:
if y > cyl_y and y < cyl_y + self.height:
cyl = self.cyl_upper
if cyl == None:
cyl_x = self.cyl_lower_drawn_at[0]
cyl_y = self.cyl_lower_drawn_at[1]
if x > cyl_x and x < cyl_x + self.cyl_lower.get_width() + x_radius:
if y > cyl_y and y < cyl_y + self.height:
cyl = self.cyl_lower
if cyl == None:
return None
# click is in a rectangle, change to local coordinates
y = y - cyl_y
x = x - cyl_x - ellipse_table[y]
if x < 0:
return None
selected = cyl.click((x, y), leftClick) # local coordinates
if leftClick:
if selected == self.selection and selected != None:
selected.set_selected(False)
self.selection = None
return
if selected != None:
if self.selection != None:
self.selection.set_selected(False)
selected.set_selected(True)
self.selection = selected
def append_right(self, upper, child):
cyl = None
if upper:
cyl = self.cyl_upper
else:
cyl = self.cyl_lower
cyl.children.append(child)
cyl.set_height(self.height)
self.__adjust_width()
def __adjust_width(self):
self.cyl_upper.set_ratio(1)
self.cyl_lower.set_ratio(1)
up_w = self.cyl_upper.get_width()
lo_w = self.cyl_lower.get_width()
if up_w == 0 or lo_w == 0:
return
up_w_adj = self.cyl_upper.get_adjustable_width()
lo_w_adj = self.cyl_lower.get_adjustable_width()
self.cyl_upper.set_ratio(float(self.width-(up_w-up_w_adj))/up_w_adj)
self.cyl_lower.set_ratio(float(self.width-(lo_w-lo_w_adj))/lo_w_adj)
if self.respect_selectable_width:
# make sure smallest selectable width is at least self.smallest_clickable_width
smallest = self.__get_smallest_selectable_width()
if smallest < self.smallest_clickable_width:
self.cyl_upper.set_ratio(1)
self.cyl_lower.set_ratio(1)
smallest = self.__get_smallest_selectable_width()
ratio = self.smallest_clickable_width/float(smallest)
self.cyl_upper.set_ratio(ratio)
self.cyl_lower.set_ratio(ratio)
def __get_smallest_selectable_width(self):
smallest_upper = self.cyl_upper.get_smallest_selectable_width()
smallest_lower = self.cyl_lower.get_smallest_selectable_width()
if smallest_upper == 0 or smallest_lower == 0:
if smallest_upper == 0:
smallest = smallest_lower
else:
smallest = smallest_upper
else:
if smallest_upper < smallest_lower:
smallest = smallest_upper
else:
smallest = smallest_lower
return smallest
def set_height(self, height):
self.height = height
self.cyl_upper.set_height(height)
self.cyl_lower.set_height(height)
def get_height(self):
return self.height
def set_width(self, width):
self.width = width
self.__adjust_width()
def get_width(self):
return self.width
def get_adjusted_width(self):
return self.cyl_upper.get_width()
def minimum_pixmap_dimension(self, da):
# cylinder dimension
cyl_dim = (2 * get_ellipse_table(self.height/2)[1] + self.cyl_upper.get_width(), self.height)
# labels dimensions
# main
layout = da.create_pango_layout('')
layout.set_markup(self.label_upper)
main_label_dim = layout.get_pixel_size()
layout = da.create_pango_layout('')
layout.set_markup(self.label_lower)
if layout.get_pixel_size()[0] > main_label_dim[0]:
main_label_dim = layout.get_pixel_size()
# upper cylinder
up_cyl_up_label_dim = draw_cyl_labels_upper(da, None, None,
self.cyl_upper.get_labels_upper(),
0, 0,
False)
up_cyl_low_label_dim = draw_cyl_labels_lower(da, None, None,
self.cyl_upper.get_labels_lower(),
0, 0,
self.height,
False)
# lower cylinder
low_cyl_up_label_dim = draw_cyl_labels_upper(da, None, None,
self.cyl_lower.get_labels_upper(),
0, 0,
False)
low_cyl_low_label_dim = draw_cyl_labels_lower(da, None, None,
self.cyl_lower.get_labels_lower(),
0, 0,
self.height,
False)
# width
max_cyl_w = cyl_dim[0]
ellipse_w = get_ellipse_table(self.height/2)[1]
if up_cyl_up_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = up_cyl_up_label_dim[0] + ellipse_w
if up_cyl_low_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = up_cyl_low_label_dim[0] + ellipse_w
if low_cyl_up_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = low_cyl_up_label_dim[0] + ellipse_w
if low_cyl_low_label_dim[0] > max_cyl_w - ellipse_w:
max_cyl_w = low_cyl_low_label_dim[0] + ellipse_w
width = main_label_dim[0] + self.label_to_cyl_distance + max_cyl_w
# height
distance = self.distance
auto_distance = up_cyl_low_label_dim[1] + self.label_to_cyl_distance + low_cyl_up_label_dim[1]
if auto_distance > distance:
distance = auto_distance
height = up_cyl_up_label_dim[1] + 2 * cyl_dim[1] + distance + low_cyl_low_label_dim[1]
return width, height, up_cyl_up_label_dim[1]
def draw(self, da, gc, (x, y)):
dc = da.window
(w, h) = dc.get_size()
pixmap = gtk.gdk.Pixmap(dc, w, h) # buffer
# clear
front = gc.foreground
gc.foreground = gc.background
pixmap.draw_rectangle(gc, True, 0, 0, w, h)
gc.foreground = front
# labels dimensions
up_cyl_up_label_dim = draw_cyl_labels_upper(da, None, None,
self.cyl_upper.get_labels_upper(),
0, 0,
False)
up_cyl_low_label_dim = draw_cyl_labels_lower(da, None, None,
self.cyl_upper.get_labels_lower(),
0, 0,
self.height,
False)
low_cyl_up_label_dim = draw_cyl_labels_upper(da, None, None,
self.cyl_lower.get_labels_upper(),
0, 0,
False)
low_cyl_low_label_dim = draw_cyl_labels_lower(da, None, None,
self.cyl_lower.get_labels_lower(),
0, 0,
self.height,
False)
# calculate distance
distance = self.distance
auto_distance = up_cyl_low_label_dim[1] + self.label_to_cyl_distance + low_cyl_up_label_dim[1]
if auto_distance > distance:
distance = auto_distance
# adjust y for upper label height
y = y + up_cyl_up_label_dim[1]
# draw name
#layout = da.create_pango_layout(self.name)
#label_w, label_h = layout.get_pixel_size()
#pixmap.draw_layout(gc, x, y + (self.height - label_h) / 2, layout)
# draw upper label
layout = da.create_pango_layout('')
layout.set_markup(self.label_upper)
label_w, label_h = layout.get_pixel_size()
pixmap.draw_layout(gc, x, y + (self.height-label_h)/2, layout)
max_label_w = label_w
# draw lower label
layout = da.create_pango_layout('')
layout.set_markup(self.label_lower)
label_w, label_h = layout.get_pixel_size()
pixmap.draw_layout(gc,
x,
y + self.height + distance + (self.height - label_h)/2,
layout)
if label_w > max_label_w:
max_label_w = label_w
# draw upper cylinder
x = x + max_label_w + get_ellipse_table(self.height/2)[1] + self.label_to_cyl_distance
self.cyl_upper.draw(pixmap, gc, (x, y))
self.cyl_upper_drawn_at = (x, y)
# draw lower cylinder
self.cyl_lower.draw(pixmap, gc, (x, y + self.height + distance))
self.cyl_lower_drawn_at = (x, y + self.height + distance)
# draw mapping lines
self.draw_mappings(pixmap, gc)
# draw cylinders' labels
# upper cylinder
draw_cyl_labels_upper(da, pixmap, gc,
self.cyl_upper.get_labels_upper(),
self.cyl_upper_drawn_at[0],
self.cyl_upper_drawn_at[1])
draw_cyl_labels_lower(da, pixmap, gc,
self.cyl_upper.get_labels_lower(),
self.cyl_upper_drawn_at[0],
self.cyl_upper_drawn_at[1],
self.height)
# lower cylinder
draw_cyl_labels_upper(da, pixmap, gc,
self.cyl_lower.get_labels_upper(),
self.cyl_lower_drawn_at[0],
self.cyl_lower_drawn_at[1])
draw_cyl_labels_lower(da, pixmap, gc,
self.cyl_lower.get_labels_lower(),
self.cyl_lower_drawn_at[0],
self.cyl_lower_drawn_at[1],
self.height)
# double buffering
dc.draw_drawable(gc, pixmap, 0, 0, 0, 0, w, h)
def draw_mappings(self, dc, gc):
upper_anchors = self.cyl_upper.get_anchors()
lower_anchors = self.cyl_lower.get_anchors()
# match them
anchors = []
for ancU in self.cyl_upper.get_anchors():
for ancL in self.cyl_lower.get_anchors():
if ancU[0] == ancL[0]:
anchors.append((ancU[1], ancL[1]))
break
# draw lines
back = gc.line_style
gc.line_style = gtk.gdk.LINE_ON_OFF_DASH
for pair in anchors:
dc.draw_line(gc,
self.cyl_upper_drawn_at[0] + pair[0], #x1
self.cyl_upper_drawn_at[1] + self.height, #y1
self.cyl_lower_drawn_at[0] + pair[1], #x2
self.cyl_lower_drawn_at[1]) #y2
gc.line_style = back
class UnselectableSubcylinder(Subcylinder):
def __init__(self,
popup_message=None,
cyl_gen=None,
highlightedPattern=None,
width=0):
Subcylinder.__init__(self,
cyl_gen,
None,
highlightedPattern,
False,
width)
self.message = popup_message
def click(self, (x, y), leftClick): # local coordinates
if x < self.get_width():
if leftClick:
# left click handling
if self.message != None:
dlg = gtk.MessageDialog(None, 0,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
self.message)
dlg.show_all()
rc = dlg.run()
dlg.destroy()
else:
# right click handling
pass
return None
class CylinderGenerator:
def __init__(self, pixmap_path, end_color):
self.pixbuf = gtk.gdk.pixbuf_new_from_file(pixmap_path)
self.end_color = end_color
def get_cyl(self, dc, width, height):
y_radius = height / 2
(ellipse_table, x_radius) = get_ellipse_table(y_radius)
pixmap_width = width + x_radius
scaled_pixbuf = self.pixbuf.scale_simple(pixmap_width, height, gtk.gdk.INTERP_BILINEAR)
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_pixbuf(gc, scaled_pixbuf, 0, 0, 0, 0, -1, -1)
for y in range(0, height):
x_offset = ellipse_table[y]
for x in range(0, x_offset):
pixmap.draw_point(gc, x, y)
for x in range(width + x_offset, pixmap_width):
pixmap.draw_point(gc, x, y)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = scaled_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def __get_pattern0(self, dc, width, height):
y_radius = height / 2
(ellipse_table, x_radius) = get_ellipse_table(y_radius)
pixmap_width = width + x_radius
scaled_pixbuf = self.pixbuf.scale_simple(pixmap_width, height, gtk.gdk.INTERP_BILINEAR)
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_rectangle(gc, True, 0, 0, pixmap_width, height)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = scaled_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def __get_pattern1(self, dc, width, height):
y_radius = height / 2
(ellipse_table, x_radius) = get_ellipse_table(y_radius)
pixmap_width = width + x_radius
scaled_pixbuf = self.pixbuf.scale_simple(pixmap_width, height, gtk.gdk.INTERP_BILINEAR)
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_rectangle(gc, True, 0, 0, pixmap_width, height)
gc.foreground = gtk.gdk.colormap_get_system().alloc_color("white", 1,1)
for y in range(0, height, 2):
x_offset = ellipse_table[y]
for x in range(x_offset, x_offset + width):
pixmap.draw_point(gc, x, y)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = scaled_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def __get_pattern2(self, dc, width, height):
y_radius = height / 2
(ellipse_table, x_radius) = get_ellipse_table(y_radius)
pixmap_width = width + x_radius
scaled_pixbuf = self.pixbuf.scale_simple(pixmap_width, height, gtk.gdk.INTERP_BILINEAR)
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_rectangle(gc, True, 0, 0, pixmap_width, height)
gc.foreground = gtk.gdk.colormap_get_system().alloc_color("white", 1,1)
for y in range(0, height, 5):
x_offset = ellipse_table[y]
for x in range(x_offset, x_offset + width):
pixmap.draw_point(gc, x, y)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = scaled_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def __get_pattern3(self, dc, width, height):
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
cyl_pixbuf = self.get_cyl(dc, width, height)
pixmap_width = cyl_pixbuf.get_width()
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_rectangle(gc, True, 0, 0, pixmap_width, height)
pixmap.draw_pixbuf(gc, cyl_pixbuf, 0, 0, 0, 0, -1, -1)
for y in range(0, height, 6):
for x in range(0, pixmap_width):
pixmap.draw_point(gc, x, y)
pixmap.draw_point(gc, x, y+1)
pixmap.draw_point(gc, x, y+2)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = cyl_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def __get_pattern4(self, dc, width, height):
y_radius = height / 2
(ellipse_table, x_radius) = get_ellipse_table(y_radius)
pixmap_width = width + x_radius
scaled_pixbuf = self.pixbuf.scale_simple(pixmap_width, height, gtk.gdk.INTERP_BILINEAR)
gc = dc.new_gc()
colormap = dc.get_colormap()
gc.foreground = colormap.alloc_color(0, 0, 0)
pixmap = gtk.gdk.Pixmap(dc, pixmap_width, height)
pixmap.draw_rectangle(gc, True, 0, 0, pixmap_width, height)
gc.foreground = gtk.gdk.colormap_get_system().alloc_color("white", 1,1)
for y in range(0, height, 15):
x_offset = ellipse_table[y]
for x in range(x_offset, x_offset + width):
pixmap.draw_point(gc, x, y)
# get pixbuf from pixmap in order to add alpha channel
pixbuf = scaled_pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, pixmap_width, height)
# add alpha channel
pixbuf = pixbuf.add_alpha(True, chr(0), chr(0), chr(0))
return pixbuf
def get_pattern(self, pattern_id, dc, width, height):
if pattern_id == 0:
return self.__get_pattern0(dc, width, height)
elif pattern_id == 1:
return self.__get_pattern1(dc, width, height)
elif pattern_id == 2:
return self.__get_pattern2(dc, width, height)
elif pattern_id == 3:
return self.__get_pattern3(dc, width, height)
elif pattern_id == 4:
return self.__get_pattern4(dc, width, height)
else:
raise 'INVALID PATTERN ID'
def draw_end(self, dc, gc, x, y, height):
color_backup = gc.foreground
gc.foreground = self.end_color
ellipse_table, x_radius = get_ellipse_table(height / 2)
#dc.draw_arc(gc, True, x - x_radius, y, 2 * x_radius, height, 5760, 11520)
#dc.draw_arc(gc, True, x - x_radius, y, 2 * x_radius, height, 17280, 11520)
# draw ellipse by hand
for Y in range(0, height):
x_offset = ellipse_table[Y]
for X in range(x - x_offset, x + x_offset):
dc.draw_point(gc, X, y + Y)
gc.foreground = color_backup
# returns (ellipse_table, x_radius)
ellipses_table = {}
def get_ellipse_table(y_radius):
global ellipses_table
if ellipses_table.has_key(y_radius):
return ellipses_table[y_radius]
x_radius = y_radius / 2
ellipse_table = {}
split_point = y_radius - 0.5
for y in range(y_radius, 0, -1):
yy = y * y
val1 = operator.div(yy, float(y_radius * y_radius))
val2 = operator.sub(1.0, val1)
x_squared = (float(x_radius * x_radius)) * val2
x_offset_float = math.sqrt(operator.abs(x_squared))
x_offset = int(math.ceil(x_offset_float))
y_offset = operator.abs(y - y_radius)
ellipse_table[y_offset] = x_offset
ellipse_table[int(2*split_point) - y_offset] = x_offset
pair = (ellipse_table, x_radius)
ellipses_table[y_radius] = pair
return pair