diff options
Diffstat (limited to 'montage.py')
-rw-r--r-- | montage.py | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/montage.py b/montage.py new file mode 100644 index 0000000..b1c4515 --- /dev/null +++ b/montage.py @@ -0,0 +1,786 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +### flipsticks +### +### author: Ed Stoner (ed@whsd.net) +### (c) 2007 World Wide Workshop Foundation + +import os +import gtk +import math +import gobject +import logging +from gettext import gettext as _ + +from sugar.activity.activity import get_bundle_path + +import model +import screen +import kinematic +import theme +from theme import * + +logger = logging.getLogger('flipsticks') + +class View(gtk.EventBox): + def reset(self): + self.key.reset() + self.selectstickebox() + self.drawmainframe() + + def setframe(self): + model.keys[self.kfselected].assign(self.key) + self.drawkeyframe() + + def clearframe(self): + model.keys[self.kfselected].clear() + self.drawkeyframe() + + def setplayspeed(self, value): + self.waittime = int((100-value)*5) + if self.playing: + gobject.source_remove(self.playing) + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def playbackwards(self): + self.frames = kinematic.makeframes() + fsecs = self.frames.keys() + fsecs.sort() + if fsecs: + self.playframenum = fsecs[-1] + else: + self.playframenum = -1 + self.playingbackwards = True + + logger.debug('playbackwards speed=%s' % self.waittime) + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def playforwards(self): + self.frames = kinematic.makeframes() + fsecs = self.frames.keys() + fsecs.sort() + if fsecs: + self.playframenum = fsecs[0] + else: + self.playframenum = -1 + + logger.debug('playforwards speed=%s' % self.waittime) + self.playingbackwards = False + self.playing = gobject.timeout_add(self.waittime, self.playframe) + + def stop(self): + if not self.playing: + return + + self.playing = False + # set the main window to the keyframe + if not model.keys[self.kfselected].empty(): + self.key.assign(model.keys[self.kfselected]) + self.drawmainframe() + self.updateentrybox() + + def exportframe(self): + self.frames = kinematic.makeframes() + fsecs = self.frames.keys() + firstpixindex = fsecs[0] + + x, y, width, height = self.mfdraw.get_allocation() + pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + self._draw_frame(fsecs[0], pixmap) + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) + gtk.gdk.Pixbuf.get_from_drawable(pixbuf,pixmap,pixmap.get_colormap(),0,0,0,0,width,height) + + model.screen_shot(pixbuf) + + + + + + + def restore(self): + self.drawkeyframe() + self.syncmaintokf() + self.updateentrybox() + + def expose_event(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.pixmap, x, y, x, y, width, height) + return False + + def kf_expose_event(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.kfpixmap, x, y, x, y, width, height) + return False + + def configure_event(self, widget, event): + x, y, width, height = self.mfdraw.get_allocation() + self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + self.drawmainframe() + return True + + def kf_configure_event(self, widget, event): + self.drawkeyframe() + return True + + def motion_notify_event(self, widget, event): + if event.is_hint: + x, y, state = event.window.get_pointer() + else: + x = event.x + y = event.y + state = event.state + if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + if self.jointpressed: + if _inarea(widget, x, y): + #self.key.joints[self.jointpressed] = (x,y) # old hack way + # first find the parents x,y + (px,py) = model.getparentjoint(self.jointpressed,self.key.joints, + self.key.middle) + if x-px == 0: + #computeangle = 0 + b = 1 + else: + b = float(px-x) + a = float(y-py) + computeangle = int(math.degrees(math.atan(a/b))) + stickname = JOINTTOSTICK[self.jointpressed] + # add sum of parent angles to new angle + parents = model.getparentsticks(stickname) + panglesum = 0 + for parentname in parents: + (pangle,plen) = self.key.sticks[parentname] + panglesum += pangle + (angle, len) = self.key.sticks[stickname] + #print 'X:%s,Y:%s,PX:%s,PY:%s,ANGLE:%s,NEWANGLE:%s' % (x,y,px,py,angle,newangle) + newangle = computeangle-panglesum + if (x < px) or (b == 1): + newangle = newangle + 180 + if newangle < 0: + newangle = 360 + newangle + self.key.sticks[stickname] = (newangle,len) + self.key.setjoints() # this is overkill + self.drawmainframe() + self.updateentrybox() + elif self.middlepressed: + if _inarea(widget, x, y): + xdiff = x-self.key.middle[0] + ydiff = y-self.key.middle[1] + self.key.move(xdiff, ydiff) + self.key.middle = (x,y) + self.drawmainframe() + elif self.rotatepressed: + if _inarea(widget, x, y): + (px,py) = self.key.middle + if x-px == 0: + #computeangle = 0 + b = 1 + else: + b = float(px-x) + a = float(y-py) + computeangle = int(math.degrees(math.atan(a/b))) + stickname = 'TORSO' + (angle, len) = self.key.sticks[stickname] + newangle = computeangle + if (x < px) or (b == 1): + newangle = newangle + 180 + if newangle < 0: + newangle = 360 + newangle + anglediff = newangle-angle + self.key.sticks[stickname] = (newangle,len) + # now rotate the other sticks off of the middle + for stickname in ['NECK','RIGHT SHOULDER','LEFT SHOULDER']: + (sangle,slen) = self.key.sticks[stickname] + newsangle = sangle+anglediff + if newsangle < 0: + newsangle = 360 + newsangle + if newsangle > 360: + newsangle = newsangle - 360 + self.key.sticks[stickname] = (newsangle,slen) + self.key.setjoints() + self.drawmainframe() + self.updateentrybox() + + return True + + def kf_motion_notify_event(self, widget, event): + if event.is_hint: + x, y, state = event.window.get_pointer() + else: + x = event.x + y = event.y + state = event.state + if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + if self.kfpressed >= 0: + if _inarea(widget, x, y): + xdiff = int(x - self.kf_mouse_pos) + frame = model.keys[self.kfpressed] + if frame.x + xdiff > KEYFRAME_RADIUS \ + and frame.x + xdiff < KEYFRAMEWIDTH-KEYFRAME_RADIUS: + frame.move(xdiff) + self.drawkeyframe() + self.kf_mouse_pos = x + return True + + def button_press_event(self, widget, event): + if event.button == 1 and self.pixmap != None: + joint = self.key.injoint(event.x, event.y) + if joint: + self.jointpressed = joint + self.drawmainframe() + elif self.key.inmiddle(event.x, event.y): + self.middlepressed = True + self.drawmainframe() + elif self.key.inrotate(event.x, event.y): + self.rotatepressed = True + self.drawmainframe() + return True + + def syncmaintokf(self): + # set the main window to the keyframe + if not model.keys[self.kfselected].empty(): + self.key.assign(model.keys[self.kfselected]) + self.drawmainframe() + + def kf_button_press_event(self, widget, event): + if event.button == 1 and self.pixmap != None: + kfnum = self._inkeyframe(event.x, event.y) + if kfnum >= 0: + self.kf_mouse_pos = event.x + self.kfpressed = kfnum + self.kfselected = kfnum + self.drawkeyframe() + self.syncmaintokf() + self.updateentrybox() + return True + + def button_release_event(self, widget, event): + self.jointpressed = None + self.middlepressed = False + self.rotatepressed = False + self.drawmainframe() + return True + + def kf_button_release_event(self, widget, event): + self.kfpressed = -1 + self.drawkeyframe() + return True + + def playframe(self): + if not self.playing: + return False + else: + if self.playframenum == -1: + return True + + self._draw_frame(self.playframenum, self.pixmap) + # draw circle for middle + #green = cm.alloc_color('green') + #drawgc.set_foreground(green) + #x,y = middle + #self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + self.mfdraw.queue_draw() + + fsecs = self.frames.keys() + fsecs.sort() + if self.playingbackwards: + # decrement playframenum + if self.playframenum == fsecs[0]: + self.playframenum = fsecs[-1] + else: + i = fsecs.index(self.playframenum) + self.playframenum = fsecs[i-1] + else: + # increment playframenum + if self.playframenum == fsecs[-1]: + self.playframenum = fsecs[0] + else: + i = fsecs.index(self.playframenum) + self.playframenum = fsecs[i+1] + if self.playing: + return True + else: + return False + + def enterangle_callback(self, widget, entry): + stickname = self.stickselected + if stickname in self.key.sticks: + newangle = int(entry.get_text()) + (angle, len) = self.key.sticks[stickname] + self.key.sticks[stickname] = (newangle,len) + self.anglel_adj.set_value(newangle) + self.anglel_slider.set_sensitive(True) + else: + # part not stick + self.angleentry.set_text('') + self.angleentry.set_sensitive(False) + self.anglel_adj.set_value(0) + self.anglel_slider.set_sensitive(False) + + self.key.setjoints() + self.drawmainframe() + + def updateentrybox(self): + if self.stickselected in self.key.sticks: + (angle, len) = self.key.sticks[self.stickselected] + self.angleentry.set_text(str(angle)) + self.anglel_adj.set_value(angle) + else: + # part not stick + len = self.key.parts[self.stickselected] + self.sizeentry.set_text(str(len)) + self.size_adj.set_value(len) + + def enterlen_callback(self, widget, entry): + stickname = self.stickselected + newlen = int(entry.get_text()) + if stickname in self.key.sticks: + if stickname == 'HEAD': + newlen = int(newlen/2.0) + (angle, len) = self.key.sticks[stickname] + self.key.sticks[stickname] = (angle,newlen) + else: + # part not stick + self.key.parts[stickname] = newlen + self.key.setjoints() + self.drawmainframe() + + def drawmainframe(self): + if not self.pixmap: + return + + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + yellow = cm.alloc_color('yellow') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + #self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + self.pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + hsize = self.key.sticks['HEAD'][1] # really half of head size + rhsize = self.key.parts['RIGHT HAND'] + lhsize = self.key.parts['LEFT HAND'] + self.drawstickman(drawgc,self.pixmap,self.key.middle,self.key.joints,hsize,rhsize,lhsize) + # draw circle for middle + drawgc.set_foreground(green) + if self.middlepressed: + drawgc.set_foreground(blue) + x,y = self.key.middle + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + # draw circle for rotate (should be halfway between middle and groin + (rx,ry) = self.key.getrotatepoint() + drawgc.set_foreground(yellow) + if self.rotatepressed: + drawgc.set_foreground(blue) + self.pixmap.draw_arc(drawgc,True,rx-5,ry-5,10,10,0,360*64) + # draw circles for joints + drawgc.set_foreground(black) + for jname in self.key.joints: + if jname == 'head': + continue + x,y = self.key.joints[jname] + if self.jointpressed == jname: + drawgc.set_foreground(blue) + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + drawgc.set_foreground(black) + else: + drawgc.set_foreground(red) + self.pixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + drawgc.set_foreground(black) + self.mfdraw.queue_draw() + + def drawstickman(self,drawgc,pixmap,middle,joints,hsize,rhsize,lhsize): + leftarm = [middle, joints['leftshoulder'],joints['leftelbow'],joints['lefthand']] + rightarm = [middle, joints['rightshoulder'],joints['rightelbow'],joints['righthand']] + torso = [joints['neck'],middle,joints['groin']] + leftleg = [joints['groin'],joints['lefthip'],joints['leftknee'], + joints['leftheel'],joints['lefttoe']] + rightleg = [joints['groin'],joints['righthip'],joints['rightknee'], + joints['rightheel'],joints['righttoe']] + # draw lines + pixmap.draw_lines(drawgc, leftarm) + pixmap.draw_lines(drawgc, rightarm) + pixmap.draw_lines(drawgc, torso) + pixmap.draw_lines(drawgc, leftleg) + pixmap.draw_lines(drawgc, rightleg) + # draw head + x,y = joints['head'] + pixmap.draw_arc(drawgc,True,x-hsize,y-hsize,hsize*2,hsize*2,0,360*64) + # draw circles for hands + x,y = joints['righthand'] + pixmap.draw_arc(drawgc,True,x-int(rhsize/2.0),y-int(rhsize/2.0),rhsize,rhsize,0,360*64) + x,y = joints['lefthand'] + pixmap.draw_arc(drawgc,True,x-int(lhsize/2.0),y-int(lhsize/2.0),lhsize,lhsize,0,360*64) + + def drawkeyframe(self): + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 2 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + pink = cm.alloc_color(PINK) + bgcolor = cm.alloc_color(BACKGROUND) + darkgreen = cm.alloc_color(BUTTON_BACKGROUND) + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.kfdraw.get_allocation() + self.kfpixmap = gtk.gdk.Pixmap(self.kfdraw.window, width, height) + # clear area + drawgc.set_foreground(bgcolor) + self.kfpixmap.draw_rectangle(drawgc,True,0,0,width,height) + # draw line in middle + drawgc.set_foreground(darkgreen) + self.kfpixmap.draw_rectangle(drawgc,True,10,int(height/2.0)-5,width-20,10) + x = 10 + y = int(height/2.0) + self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + x = width-10 + self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + + # draw the keyframe circles + for i in list(reversed(self.keys_overlap_stack)): + # first the outer circle + x = model.keys[i].x + if i == self.kfselected: + drawgc.set_foreground(pink) + else: + drawgc.set_foreground(darkgreen) + self.kfpixmap.draw_arc(drawgc, True, x-KEYFRAME_RADIUS, + y-KEYFRAME_RADIUS, KEYFRAME_RADIUS*2, KEYFRAME_RADIUS*2, + 0, 360*64) + # then the inner circle + drawgc.set_foreground(white) + self.kfpixmap.draw_arc(drawgc, True, x-KEYFRAME_RADIUS+5, + y-KEYFRAME_RADIUS+5, (KEYFRAME_RADIUS-5)*2, + (KEYFRAME_RADIUS-5)*2, 0, 360*64) + if model.keys[i].scaled_sticks: + # draw a man in the circle + drawgc.set_foreground(black) + hsize = model.keys[i].scaled_sticks['HEAD'][1] + rhsize = int(model.keys[i].parts['RIGHT HAND']*0.2) + lhsize = int(model.keys[i].parts['LEFT HAND']*0.2) + self.drawstickman(drawgc,self.kfpixmap,(x,y), model.keys[i].scaled_joints,hsize,rhsize,lhsize) + #self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) + self.kfdraw.queue_draw() + + def drawfp(self): + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 1 + cm = drawgc.get_colormap() + red = cm.alloc_color('red') + white = cm.alloc_color('white') + black = cm.alloc_color('black') + blue = cm.alloc_color('blue') + green = cm.alloc_color('green') + pink = cm.alloc_color(PINK) + bgcolor = cm.alloc_color(BACKGROUND) + darkgreen = cm.alloc_color(BUTTON_BACKGROUND) + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.fpdraw.get_allocation() + self.fppixmap = gtk.gdk.Pixmap(self.fpdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + self.fppixmap.draw_rectangle(drawgc,True,0,0,width,height) + self.fpdraw.queue_draw() + + def selectstick(self, widget, event, data=None): + if data: + if self.stickselected: + ebox = self.stickbuttons[self.stickselected] + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + label = ebox.get_child() + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.stickselected = data + self.selectstickebox() + + def selectstickebox(self): + ebox = self.stickbuttons[self.stickselected] + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_FOREGROUND)) + label = ebox.get_child() + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + + if self.stickselected in self.key.sticks: + if self.stickselected == 'HEAD': + size = self.key.sticks[self.stickselected][1]*2 + else: + size = self.key.sticks[self.stickselected][1] + + angle = self.key.sticks[self.stickselected][0] + self.angleentry.set_text(str(angle)) + self.angleentry.set_sensitive(True) + self.anglel_adj.set_value(angle) + self.anglel_slider.set_sensitive(True) + else: + size = self.key.parts[self.stickselected] + + # its a part not a stick + self.angleentry.set_text('') + self.angleentry.set_sensitive(False) + self.anglel_adj.set_value(0) + self.anglel_slider.set_sensitive(False) + + self.sizeentry.set_text(str(size)) + self.size_adj.set_value(size) + + def __init__(self, activity): + gtk.EventBox.__init__(self) + + self.playing = False + self.playingbackwards = False + self.toplevel = activity + self.stickselected = 'RIGHT SHOULDER' + self.pixmap = None + + self.setplayspeed(50) + + self.keys_overlap_stack = [] + for i in range(len(model.keys)): + self.keys_overlap_stack.append(i) + + self.key = screen.ScreenFrame() + + self.kfselected = 0 + self.jointpressed = None + self.kfpressed = -1 + self.middlepressed = False + self.rotatepressed = False + self.iconsdir = os.path.join(get_bundle_path(), 'icons') + self.language = 'English' + + # screen + + self.mfdraw = gtk.DrawingArea() + self.mfdraw.connect('expose_event', self.expose_event) + self.mfdraw.connect('configure_event', self.configure_event) + self.mfdraw.connect('motion_notify_event', self.motion_notify_event) + self.mfdraw.connect('button_press_event', self.button_press_event) + self.mfdraw.connect('button_release_event', self.button_release_event) + self.mfdraw.set_events(gtk.gdk.EXPOSURE_MASK + | gtk.gdk.LEAVE_NOTIFY_MASK + | gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK + | gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_MASK) + + screen_box = gtk.EventBox() + screen_box.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + screen_box.set_border_width(PAD/2) + screen_box.add(self.mfdraw) + + screen_pink = gtk.EventBox() + screen_pink.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + screen_pink.set_border_width(PAD) + screen_pink.add(screen_box) + + # keyframes + + self.kfdraw = gtk.DrawingArea() + self.kfdraw.set_size_request(KEYFRAMEWIDTH,KEYFRAMEHEIGHT) + self.kfdraw.connect('expose_event', self.kf_expose_event) + self.kfdraw.connect('configure_event', self.kf_configure_event) + self.kfdraw.connect('motion_notify_event', self.kf_motion_notify_event) + self.kfdraw.connect('button_press_event', self.kf_button_press_event) + self.kfdraw.connect('button_release_event', self.kf_button_release_event) + self.kfdraw.set_events(gtk.gdk.EXPOSURE_MASK + | gtk.gdk.LEAVE_NOTIFY_MASK + | gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK + | gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_MASK) + + kfdraw_box = gtk.EventBox() + kfdraw_box.set_border_width(PAD) + kfdraw_box.add(self.kfdraw) + + # control box + + angle_box = gtk.HBox() + anglelabel = gtk.Label(_('Angle:')) + anglelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + anglelabel.set_size_request(60, -1) + angle_box.pack_start(anglelabel,False,False,5) + self.angleentry = gtk.Entry() + self.angleentry.set_max_length(3) + self.angleentry.set_width_chars(3) + self.angleentry.connect('activate', self.enterangle_callback, self.angleentry) + self.angleentry.modify_bg(gtk.STATE_INSENSITIVE, + gtk.gdk.color_parse(BUTTON_FOREGROUND)) + angle_box.pack_start(self.angleentry,False,False,0) + self.anglel_adj = gtk.Adjustment(0, 0, 360, 1, 60, 0) + self.anglel_adj.connect('value_changed', self._anglel_adj_cb) + self.anglel_slider = gtk.HScale(self.anglel_adj) + self.anglel_slider.set_draw_value(False) + for state, color in COLOR_BG_BUTTONS: + self.anglel_slider.modify_bg(state, gtk.gdk.color_parse(color)) + angle_box.pack_start(self.anglel_slider) + + size_box = gtk.HBox() + sizelabel = gtk.Label(_('Size:')) + sizelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + sizelabel.set_size_request(60, -1) + size_box.pack_start(sizelabel,False,False,5) + self.sizeentry = gtk.Entry() + self.sizeentry.set_max_length(3) + self.sizeentry.set_width_chars(3) + self.sizeentry.connect('activate', self.enterlen_callback, self.sizeentry) + self.sizeentry.modify_bg(gtk.STATE_INSENSITIVE, + gtk.gdk.color_parse(BUTTON_FOREGROUND)) + size_box.pack_start(self.sizeentry,False,False,0) + self.size_adj = gtk.Adjustment(0, 0, 200, 1, 30, 0) + self.size_adj.connect('value_changed', self._size_adj_cb) + size_slider = gtk.HScale(self.size_adj) + size_slider.set_draw_value(False) + for state, color in COLOR_BG_BUTTONS: + size_slider.modify_bg(state, gtk.gdk.color_parse(color)) + size_box.pack_start(size_slider) + + control_head_box = gtk.VBox() + control_head_box.pack_start(angle_box) + control_head_box.pack_start(size_box) + + control_head = gtk.EventBox() + control_head.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_FOREGROUND)) + control_head.add(control_head_box) + + control_options = gtk.VBox() + self.stickbuttons = {} + self.sticklabels = {} + for stickpartname in LABELLIST: + label = gtk.Label(LANG[self.language][stickpartname]) + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.sticklabels[stickpartname] = label + ebox = gtk.EventBox() + ebox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + ebox.set_events(gtk.gdk.BUTTON_PRESS_MASK) + ebox.connect('button_press_event',self.selectstick,stickpartname) + ebox.add(label) + self.stickbuttons[stickpartname] = ebox + control_options.pack_start(ebox,False,False,0) + self.selectstickebox() + + control_scroll = gtk.ScrolledWindow() + control_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + control_scroll.add_with_viewport(control_options) + control_options.get_parent().modify_bg(gtk.STATE_NORMAL, + gtk.gdk.color_parse(BUTTON_BACKGROUND)) + + control_box = gtk.VBox() + control_box.pack_start(control_head, False, False, 0) + control_box.pack_start(control_scroll) + + control_bg = gtk.EventBox() + control_bg.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BUTTON_BACKGROUND)) + control_bg.set_border_width(PAD/2) + control_bg.add(control_box) + + control_pink = gtk.EventBox() + control_pink.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK)) + control_pink.set_border_width(PAD) + control_pink.add(control_bg) + + # left control box + + logo = gtk.Image() + logo.set_from_file(os.path.join(self.iconsdir,'logo.png')) + + leftbox = gtk.VBox() + leftbox.pack_start(logo, False, False) + leftbox.pack_start(control_pink) + + # desktop + + hdesktop = gtk.HBox() + hdesktop.pack_start(leftbox, False) + hdesktop.pack_start(screen_pink) + + desktop = gtk.VBox() + desktop.pack_start(hdesktop) + desktop.pack_start(kfdraw_box, False, False, 0) + + greenbox = gtk.EventBox() + greenbox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND)) + greenbox.set_border_width(PAD/2) + greenbox.add(desktop) + + self.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW)) + self.add(greenbox) + self.show_all() + + def _draw_frame(self, index, pixmap): + joints = self.frames[index].joints + parts = self.frames[index].parts + # draw on the main drawing area + area = self.toplevel.window + drawgc = area.new_gc() + drawgc.line_width = 3 + cm = drawgc.get_colormap() + white = cm.alloc_color('white') + black = cm.alloc_color('black') + drawgc.fill = gtk.gdk.SOLID + x, y, width, height = self.mfdraw.get_allocation() + #pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + # clear area + drawgc.set_foreground(white) + pixmap.draw_rectangle(drawgc,True,0,0,width,height) + + drawgc.set_foreground(black) + #hsize = self.key.sticks['HEAD'][1] # really half of head size + hsize = self.frames[index].hsize + middle = self.frames[index].middle + rhsize = parts['RIGHT HAND'] + lhsize = parts['LEFT HAND'] + self.drawstickman(drawgc, pixmap, middle, joints, hsize, rhsize, lhsize) + + def _inkeyframe(self, x, y): + dy = math.pow(abs(y - KEYFRAMEHEIGHT/2), 2) + + for i, key in enumerate(self.keys_overlap_stack): + dx = math.pow(abs(x - model.keys[key].x), 2) + l = math.sqrt(dx + dy) + if int(l) <= KEYFRAME_RADIUS: + self.keys_overlap_stack.pop(i) + self.keys_overlap_stack.insert(0, key) + return key + + return -1 + + def _anglel_adj_cb(self, adj): + self.angleentry.set_text(str(int(adj.value))) + self.enterangle_callback(None, self.angleentry) + + def _size_adj_cb(self, adj): + self.sizeentry.set_text(str(int(adj.value))) + self.enterlen_callback(None, self.sizeentry) + +def _inarea(widget, x, y): + x_, y_, width, height = widget.get_allocation() + if x < 0 or y < 0 or x >= width or y >= height: + return False + return True |