Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/View.py
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-01-30 23:32:43 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-01-30 23:32:43 (GMT)
commitf3f438af59c69b584d84b27f103f9392fc8185f8 (patch)
tree808556779f0d70312625b6d50277371bbf19b880 /View.py
parent56cea3b5c6361c7958e1c27182fcf117470a1861 (diff)
...
Diffstat (limited to 'View.py')
-rw-r--r--View.py353
1 files changed, 353 insertions, 0 deletions
diff --git a/View.py b/View.py
new file mode 100644
index 0000000..98815df
--- /dev/null
+++ b/View.py
@@ -0,0 +1,353 @@
+# 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
+#
+
+### cartoonbuilder
+###
+### author: Ed Stoner (ed@whsd.net)
+### (c) 2007 World Wide Workshop Foundation
+
+import time
+import pygtk
+import gtk
+import gobject
+import gettext
+import os
+import textwrap
+
+import Theme
+import Char
+import Ground
+import Sound
+import Document
+from Utils import *
+
+class FrameWidget(gtk.DrawingArea):
+ def __init__(self):
+ gtk.DrawingArea.__init__(self)
+ self.gc = None # initialized in realize-event handler
+ self.width = 0 # updated in size-allocate handler
+ self.height = 0 # idem
+ self.bgpixbuf = None
+ self.fgpixbuf = None
+ self.connect('size-allocate', self.on_size_allocate)
+ self.connect('expose-event', self.on_expose_event)
+ self.connect('realize', self.on_realize)
+
+ def on_realize(self, widget):
+ self.gc = widget.window.new_gc()
+
+ def on_size_allocate(self, widget, allocation):
+ self.height = self.width = min(allocation.width, allocation.height)
+
+ def on_expose_event(self, widget, event):
+ # This is where the drawing takes place
+ if self.bgpixbuf:
+ pixbuf = self.bgpixbuf
+ if pixbuf.get_width != self.width:
+ pixbuf = Theme.scale(pixbuf, self.width)
+ widget.window.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, -1, -1, 0, 0)
+
+ if self.fgpixbuf:
+ pixbuf = self.fgpixbuf
+ if pixbuf.get_width != self.width:
+ pixbuf = Theme.scale(pixbuf, self.width)
+ widget.window.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, -1, -1, 0, 0)
+
+ def draw(self):
+ self.queue_draw()
+
+class View:
+ def __init__(self):
+ self._playing = None
+ self.waittime = 3*150
+ self.tape = []
+ self.frames = []
+ self._prev_combo_selected = {}
+
+ # frames table
+
+ from math import ceil
+
+ rows = max((DESKTOP_HEIGHT - THUMB_SIZE*3) / THUMB_SIZE,
+ int(ceil(float(FRAME_COUNT) / FRAME_COLS)))
+
+ self.table = gtk.Table(rows, columns=Theme.FRAME_COLS, homogeneous=False)
+
+ for y in range(rows):
+ for x in range(Theme.FRAME_COLS):
+ image = gtk.Image()
+ self.frames.append(image)
+
+ image_box = gtk.EventBox()
+ image_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ image_box.connect('button_press_event', self._frame_cb,
+ y * Theme.FRAME_COLS + x)
+ image_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLACK))
+ image_box.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(BLACK))
+ image_box.props.border_width = 2
+ image_box.set_size_request(Theme.THUMB_SIZE, Theme.THUMB_SIZE)
+ image_box.add(image)
+
+ self.table.attach(image_box, x, x+1, y, y+1)
+
+ # frames box
+
+ table_scroll = VScrolledBox()
+ table_scroll.set_viewport(self.table)
+ table_scroll.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND))
+
+ yellow_frames = gtk.EventBox()
+ yellow_frames.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW))
+ table_frames = gtk.EventBox()
+ table_frames.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND))
+ table_frames.set_border_width(5)
+ table_frames.add(table_scroll)
+ yellow_frames.add(table_frames)
+
+ yelow_arrow = gtk.Image()
+ yelow_arrow.set_from_file(Theme.path('icons/yellow_arrow.png'))
+
+ frames_box = gtk.VBox()
+ frames_box.pack_start(yellow_frames, True, True)
+ frames_box.pack_start(yelow_arrow, False, False)
+ frames_box.props.border_width = 20
+
+ # screen
+
+ self.screen = FrameWidget()
+ screen_pink = gtk.EventBox()
+ screen_pink.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(PINK))
+ screen_box = gtk.EventBox()
+ screen_box.set_border_width(5)
+ screen_box.add(self.screen)
+ screen_pink.add(screen_box)
+ screen_pink.props.border_width = 20
+
+ # tape
+
+ tape = gtk.HBox()
+
+ for i in range(TAPE_COUNT):
+ frame_box = gtk.VBox()
+
+ filmstrip_pixbuf = gtk.gdk.pixbuf_new_from_file_at_scale(
+ Theme.path('icons/filmstrip.png'), THUMB_SIZE, -1, False)
+
+ filmstrip = gtk.Image()
+ filmstrip.set_from_pixbuf(filmstrip_pixbuf);
+ frame_box.pack_start(filmstrip, True, False)
+
+ frame = gtk.EventBox()
+ frame.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ frame.connect('button_press_event', self._tape_cb, i)
+ frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLACK))
+ frame.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(BLACK))
+ frame.props.border_width = 2
+ frame.set_size_request(Theme.THUMB_SIZE, Theme.THUMB_SIZE)
+ frame_box.pack_start(frame, False, False)
+ self.tape.append(frame)
+
+ frame_image = gtk.Image()
+ frame_image.set_from_pixbuf(Document.tape_thumb(i))
+ frame.add(frame_image)
+
+ filmstrip = gtk.Image()
+ filmstrip.set_from_pixbuf(filmstrip_pixbuf);
+ frame_box.pack_start(filmstrip, False, False)
+
+ tape.pack_start(frame_box, False, False)
+
+ self.tape_selected = -1
+ self._tape_cb(None, None, 0)
+
+ # left control box
+
+ self.controlbox = gtk.VBox()
+ self.controlbox.props.border_width = 10
+ self.controlbox.props.spacing = 10
+
+ leftbox = gtk.VBox()
+ logo = gtk.Image()
+ logo.set_from_file(Theme.path('icons/logo.png'))
+ leftbox.set_size_request(logo.props.pixbuf.get_width(), -1)
+ leftbox.pack_start(logo, False, False)
+ leftbox.pack_start(self.controlbox, True, True)
+
+ # screen box
+
+ screen_alignment = gtk.Alignment(0.5, 0.5, 0, 0)
+ screen_alignment.add(screen_pink)
+ screen_alignment.connect('size-allocate', self._screen_size_cb)
+
+ cetralbox = gtk.HBox()
+ cetralbox.pack_start(screen_alignment, True, True)
+ cetralbox.pack_start(frames_box, True, False)
+
+ hdesktop = gtk.HBox()
+ hdesktop.pack_start(leftbox,False,True,0)
+ hdesktop.pack_start(cetralbox,True,True,0)
+
+ # tape box
+
+ arrow = gtk.Image()
+ arrow.set_from_file(Theme.path('icons/pink_arrow.png'))
+ animborder = gtk.EventBox()
+ animborder.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(PINK))
+ animframe = gtk.EventBox()
+ animframe.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND))
+ animframe.set_border_width(5)
+ animframe.add(tape)
+ animborder.add(animframe)
+ animbox = gtk.HBox()
+ animbox.pack_start(animborder, True, False)
+ tape_box = gtk.VBox()
+ tape_box.props.border_width = 10
+ tape_box.pack_start(arrow, False, False)
+ tape_box.pack_start(animbox, False, False, 0)
+
+ desktop = gtk.VBox()
+ desktop.pack_start(hdesktop,True,True,0)
+ desktop.pack_start(tape_box, False, False, 0)
+
+ greenbox = gtk.EventBox()
+ greenbox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BACKGROUND))
+ greenbox.set_border_width(5)
+ greenbox.add(desktop)
+
+ yellowbox = gtk.EventBox()
+ yellowbox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW))
+ yellowbox.add(greenbox)
+ yellowbox.show_all()
+
+ self.main = yellowbox
+ yellowbox.connect_after('map', self.map_cb)
+
+ def map_cb(self, widget):
+ def new_combo(themes, cb):
+ combo = ComboBox()
+
+ for i in themes:
+ if not i:
+ combo.append_separator()
+ continue
+
+ combo.append_item(i, text = i.name,
+ size = (Theme.THUMB_SIZE, Theme.THUMB_SIZE),
+ pixbuf = i.thumb())
+
+ combo.connect('changed', cb)
+ combo.set_active(0)
+ combo.show()
+
+ return combo
+
+ self.controlbox.pack_start(new_combo(Char.THEMES, self._char_cb),
+ True, False)
+ self.controlbox.pack_start(new_combo(Ground.THEMES, self._ground_cb),
+ True, False)
+ self.controlbox.pack_start(new_combo(Sound.THEMES, self._combo_cb),
+ True, False)
+
+ return False
+
+ def play(self):
+ self.play_tape_num = 0
+ self._playing = gobject.timeout_add(self.waittime, self._play_tape)
+
+ def stop(self):
+ self._playing = None
+
+ def set_tempo(self, tempo):
+ self.waittime = int((6-tempo) * 150)
+ if self._playing:
+ gobject.source_remove(self._playing)
+ self._playing = gobject.timeout_add(self.waittime, self._play_tape)
+
+ def clear_tape(self):
+ for i in range(TAPE_COUNT):
+ Document.tape_clean(i)
+ self.screen.fgpixbuf = Document.tape_orig(self.tape_selected)
+ self.screen.draw()
+
+ def _play_tape(self):
+ self.screen.fgpixbuf = Document.tape_orig(self.play_tape_num)
+ self.screen.draw()
+
+ self.play_tape_num += 1
+ if self.play_tape_num == TAPE_COUNT:
+ self.play_tape_num = 0
+
+ if self._playing:
+ return True
+ else:
+ return False
+
+ def _tape_cb(self, widget, event, index):
+ tape = self.tape[index]
+ tape.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(YELLOW))
+ tape.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(YELLOW))
+
+ if self.tape_selected != index:
+ if self.tape_selected != -1:
+ old_tape = self.tape[self.tape_selected]
+ old_tape.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(BLACK))
+ old_tape.modify_bg(gtk.STATE_PRELIGHT,gtk.gdk.color_parse(BLACK))
+
+ self.tape_selected = index
+ self.screen.fgpixbuf = Document.tape_orig(index)
+ self.screen.draw()
+
+ def _frame_cb(self, widget, event, frame):
+ orig = self.char.orig(frame)
+ if not orig: return
+ thumb = self.char.thumb(frame)
+
+ Document.tape_stamp(self.tape_selected, orig)
+ self.tape[self.tape_selected].child.set_from_pixbuf(thumb)
+ self.frames[frame].set_from_pixbuf(thumb)
+
+ self._tape_cb(None, None, self.tape_selected)
+
+ def _char_cb(self, widget):
+ self.char = widget.props.value
+ for i in range(len(self.frames)):
+ self.frames[i].set_from_pixbuf(self.char.thumb(i))
+
+ def _combo_cb(self, widget):
+ choice = widget.props.value.change()
+
+ if not choice:
+ widget.set_active(self._prev_combo_selected[widget])
+ return None
+
+ if id(choice) != id(widget.props.value):
+ pos = widget.get_active()
+ widget.append_item(choice, text = choice.name,
+ size = (Theme.THUMB_SIZE, Theme.THUMB_SIZE),
+ pixbuf = choice.thumb(), position = pos)
+ widget.set_active(pos)
+
+ self._prev_combo_selected[widget] = widget.get_active()
+ return choice
+
+ def _ground_cb(self, widget):
+ choice = self._combo_cb(widget)
+ if choice:
+ self.screen.bgpixbuf = choice.orig()
+ self.screen.draw()
+
+ def _screen_size_cb(self, widget, aloc):
+ size = min(aloc.width, aloc.height)
+ widget.child.set_size_request(size, size)