InkDraw.py :  » Network » emesene » emesene-1.6.2 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » emesene 
emesene » emesene 1.6.2 » InkDraw.py
# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Emesene 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.
#
#    emesene 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 emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#    Ink drawing widgets from alencool

import pygtk
import gtk
import gtk.gdk
import cairo
import gobject
from math import pi

from pyisf import pyisf
from pyisf.drawing import *

#TODO: add button 'send' that encodes pixmap in isf and send to current conversation

class InkDraw(gtk.Window):
    def __init__(self, controller):
        gtk.Window.__init__(self)
        
        theme = gtk.icon_theme_get_default()
        theme.prepend_search_path('themes/default')
        #filename = 'pyisf/colors.isf'
        #data = open(filename, 'rb').read()
    
        self.set_size_request(400, 400)
        vbox = gtk.VBox()
        inkcanvas = InkCanvas(theme)
        inktoolbar = InkToolbar(theme, inkcanvas)
        vbox.pack_start(inktoolbar, expand = False)
        vbox.pack_start(inkcanvas)
        self.add(vbox)
        self.show_all()
        self.connect('delete_event', self.delete_event, inkcanvas)
    
        #inkcanvas.import_isf(data)
        
    def delete_event(self, *args):
        self.hide()

class ColorLabel(gtk.Widget):
    ''' Square shaped, color label '''   
    __gsignals__ = { 'size_request' : 'override', 'expose-event' : 'override' }
    
    _color = gtk.gdk.color_parse('#000000')
    _dimention = 20
    
    def __init__(self, color = gtk.gdk.color_parse('#000000')):
        gobject.GObject.__init__(self)
        gtk.Widget.__init__(self)
        self.set_flags(self.flags() | gtk.NO_WINDOW )       
        self._color = color

    def do_size_request(self,requisition):
        requisition.width = self._dimention
        requisition.height = self._dimention

    def do_expose_event(self, event):
        x , y, width, height = event.area
        dimention = min(width,height)
        y += (height /2) - (dimention /2)
        width, height = dimention, dimention
        ctx = event.window.cairo_create()
        ctx.translate(x, y) 
        ctx.set_antialias(cairo.ANTIALIAS_SUBPIXEL)        
        ctx.rectangle(0, 0, width, height)
        ctx.clip_preserve()
        set_context_color(ctx, self._color)
        ctx.fill_preserve()
        ctx.set_line_width(1.0)
        set_context_color(ctx, gtk.gdk.color_parse('#000000'))
        ctx.stroke()

    def set_color(self, color=gtk.gdk.color_parse('#000000')):
        self._color = color
        self.queue_draw()
        
    def get_color(self): 
        return self._color

gobject.type_register(ColorLabel)

class ColumnContainer(gtk.Box):
    ''' Container that postions widgets into a given column number'''
    __gsignals__ = { 'size_request' : 'override','size_allocate' : 'override' }
    
    _cols = 1       # number of columns
    _cr_width = 0   # child requisition width
    _cr_height = 0  # child requisition height
    _vc_number = 0  # number of visual children
    
    def __init__(self, column_number=1):
        gtk.Box.__init__(self)
        if column_number < 1:
            self._cols = 1
        else:
            self._cols = column_number

    def update_child_info(self):
        visual_children_number = 0
        child_requisition_width = 0
        child_requisition_height = 0
        for child in self.get_children():
            if child.get_property('visible'):
                child_request_width, child_request_height = child.size_request()
                child_requisition_width = max(child_requisition_width, child_request_width)
                child_requisition_height = max(child_requisition_height, child_request_height)
                visual_children_number += 1
        self._cr_width = child_requisition_width
        self._cr_height = child_requisition_height
        self._vc_number = visual_children_number
                        
    def do_size_request(self, requisition):
        self.update_child_info()        
        width, height = 0, 0          
        if self._vc_number > 0:
            width = self._cr_width * self._cols
            if self._vc_number <= self._cols:    
                height = self._cr_height
            elif (self._vc_number % self._cols ) == 0 :
                height = self._cr_height * ( self._vc_number / self._cols)
            else:
                height = self._cr_height * (( self._vc_number / self._cols) + 1)
        requisition.width = width
        requisition.height = height

    def do_size_allocate(self, allocation):     
        width = allocation.width / self._cols
        height = self._cr_height
        x, y = allocation.x, allocation.y
        col_spaces_remaining = self._cols
        for child in self.get_children():
            child.size_allocate(gtk.gdk.Rectangle(x, y, width, height))
            col_spaces_remaining -= 1
            if col_spaces_remaining == 0:
                y += height
                x = allocation.x
                col_spaces_remaining = self._cols
            else:
                x += width
                
gobject.type_register(ColumnContainer)

class DropdownWindow(gtk.Window):
    __gsignals__ = {
        'map-event' : 'override',
        'unmap-event' : 'override',
        'button-press-event' : 'override',
        'key-press-event' : 'override',
        }

    def __init__(self):
        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
        self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_MENU)
        self.set_decorated(False)

    def do_map_event(self, event):
        self.grab_focus()
        self.grab_add()
        time = gtk.get_current_event_time()
        gtk.gdk.pointer_grab(self.window, True, gtk.gdk.BUTTON_PRESS_MASK, None, None, time)
        gtk.gdk.keyboard_grab(self.window, True, time)

    def do_unmap_event(self, event): 
        time = gtk.get_current_event_time()
        gtk.gdk.pointer_ungrab(time)
        gtk.gdk.keyboard_ungrab(time)
        self.grab_remove()

    def do_button_press_event(self, event):
        win_tuple = gtk.gdk.window_at_pointer()
        if (win_tuple is None) or not( win_tuple[0] == self.window) : self.hide()
        return True

    def do_key_press_event(self, event):
        if not gtk.Window.do_key_press_event(self, event) \
               and event.keyval == gtk.gdk.keyval_from_name("Escape"):
            self.hide()
            return True

gobject.type_register(DropdownWindow)

class ColorButton(gtk.ToggleButton):
    __gsignals__ = { 
        'color-set' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_PYOBJECT,)),
        'button-press-event' : 'override'
        }
    _color = gtk.gdk.Color(0,0,0)
    _tango_colors = [ \
        '#2e3436', '#babdb6', '#a40000', '#5c3566', '#204a87', '#4e9a06', '#8f5902', '#ce5c00', '#c4a000',
        '#555753', '#d3d7cf', '#cc0000', '#75507b', '#3465a4', '#73d216', '#c17d11', '#f57900', '#edd400',
        '#888a85', '#eeeeec', '#ef2929', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fcaf3e', '#fce94f']

    def __init__(self, widget):
        gtk.Button.__init__(self)
        self.add(widget)
        self.set_property("can-default", False)
        self.set_property("can-focus", False)
        self.set_border_width(0)
        self.set_relief(gtk.RELIEF_NONE)
        self._dropdown_win = DropdownWindow()
        self._dropdown_win.realize()
        self._dropdown_win.connect("map-event", self.__win_map)
        self._dropdown_win.connect("unmap-event", self.__win_unmap)

        container = ColumnContainer(9)
        hbox = gtk.HBox()
        for hex_color in self._tango_colors:       
            container.add(self.__create_button(hex_color))
        for hex_color in ('#000000','#ffffff'):
            hbox.pack_start(self.__create_button(hex_color), False, False)    
        vbox = gtk.VBox()
        vbox.pack_start(hbox, False, False)
        vbox.pack_start(container, False, False)
        self._dropdown_win.add(vbox)
        
    def __create_button(self, hex_color='#000000'):
        label = ColorLabel(gtk.gdk.color_parse(hex_color))
        button = gtk.Button()
        button.set_relief(gtk.RELIEF_NONE)
        button.set_property("can-default", False)
        button.set_property("can-focus", False)                
        button.set_border_width(0)
        button.add(label)
        button.connect('clicked', self.__color_selected, label.get_color())    
        return button
        
    def __color_selected(self, widget, color):
        self._color = color
        self._dropdown_win.hide()
        self.emit('color-set', self._color)
    
    def __win_map(self, win, event): self.set_active(True)
    def __win_unmap(self, win, event): self.set_active(False)

    def __position(self, win):
        x, y = self.window.get_origin()
        alloc = self.allocation
        x, y = x + alloc.x, y + alloc.y
        width, height = win.get_size()
        if x + width > self.get_screen().get_width(): x += alloc.width - width
        if y + alloc.height + height > self.get_screen().get_height(): y -= height
        else: y += alloc.height
        win.move(x, y)
    
    def get_color(self): return self._color
    
    def do_button_press_event(self, event):
        if not self.get_active():
            self.__position(self._dropdown_win)
            self._dropdown_win.show_all()
            self._dropdown_win.present()
        return True        
gobject.type_register(ColorButton)

class GridType(object):
    Blank, Small, Medium, Large = range(4)
    
class GridButton(gtk.ToggleButton):
    __gsignals__ = { 
        'grid-type-set' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_PYOBJECT,)),
        'button-press-event' : 'override'
        }

    def __init__(self, button_icon, blank_icon, small_icon, medium_icon, large_icon, grid_type=GridType.Blank):
        gtk.Button.__init__(self)
        hbox = gtk.HBox()
        hbox.pack_start(button_icon)
        hbox.pack_start(gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_IN))
        self.add(hbox)
        self.set_property("can-default", False)
        self.set_property("can-focus", False)
        self.set_border_width(0)
        self.set_relief(gtk.RELIEF_NONE)
        self._grid_type = grid_type
        
        ### Grid Menu
        self._blank_item = self.__create_grid_item('Blank', blank_icon, GridType.Blank)
        self._small_item = self.__create_grid_item('Small grid', small_icon, GridType.Small)
        self._medium_item = self.__create_grid_item('Medium grid', medium_icon, GridType.Medium)
        self._large_item = self.__create_grid_item('Large grid', large_icon, GridType.Large)
        
        self._grid_menu = gtk.Menu()
        self._grid_menu.append(self._blank_item)
        self._grid_menu.append(gtk.SeparatorMenuItem())
        self._grid_menu.append(self._small_item)        
        self._grid_menu.append(self._medium_item)
        self._grid_menu.append(self._large_item)
        self._grid_menu.connect("unmap-event", self.__win_unmap)           
    
    def __create_grid_item(self, label, icon, grid_type):
        grid_item = gtk.ImageMenuItem(label)
        grid_item.set_image(icon)
        grid_item.connect('activate', self.__item_activate, grid_type)
        return grid_item
        
    def __item_activate(self, menuitem, grid_type):
        self._grid_type = grid_type
        self.emit('grid-type-set', self._grid_type)
        
    def __win_unmap(self, win, ev): self.set_active(False)
        
    def __menu_postion(self, menu):
        x, y = self.window.get_origin()
        alloc = self.allocation                
        x, y = x + alloc.x, y + alloc.y
        menu_allocation = menu.allocation
        width, height = menu_allocation.width, menu_allocation.height
        if x + width > self.get_screen().get_width(): x += alloc.width - width
        if y + alloc.height + height > self.get_screen().get_height(): y -= height
        else: y += alloc.height
        return (x,y, True)
        
    def do_button_press_event(self, event):
        if not self.get_active():
            self._grid_menu.popup(None, None, self.__menu_postion, event.button, event.time)
            self.set_active(True)
            self._grid_menu.show_all()
            if self._grid_type == GridType.Blank: self._grid_menu.select_item(self._blank_item)
            elif self._grid_type == GridType.Small: self._grid_menu.select_item(self._small_item)
            elif self._grid_type == GridType.Medium: self._grid_menu.select_item(self._medium_item)
            elif self._grid_type == GridType.Large: self._grid_menu.select_item(self._large_item)                    
        return True     
           
gobject.type_register(GridButton)


class InkCanvas(gtk.DrawingArea):

    __gsignals__ = {
        'expose_event' : 'override',
        'motion_notify_event' : 'override',
        'button_press_event' : 'override',
        'button_release_event' : 'override',
        'realize': 'override',
        'configure-event': 'override',
        }

    _history = []
    _paths = []     
    _tool_type = ToolType.Paintbrush
    _stroke_size = 8
    _stroke_color = gtk.gdk.Color(0, 0, 0)
    _grid_type = GridType.Blank  
    _grid_size = {
        GridType.Blank:     -1,
        GridType.Small:     10,
        GridType.Medium:    20,
        GridType.Large:     30,
        }    
    _pointer_surface = None
    _cached_grid_surface = None
    _cached_painting_surface = None
    _tool_type_to_surface = {}
    _is_pressed = False
    _intermediate_path = None

    
    def __init__(self, theme):
        gtk.DrawingArea.__init__(self)
        self.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) 

        self._pointer_surface = image_surface_from_pixbuf(theme.load_icon('cursor-mouse', 48, 0))
        self._tool_type_to_surface = {
            ToolType.Paintbrush: image_surface_from_pixbuf(theme.load_icon('tool-paintbrush', 48, 0)),
            ToolType.Eraser: image_surface_from_pixbuf(theme.load_icon('tool-eraser', 48, 0)), 
            }
        
    def set_tool_type(self, tool_type=ToolType.Paintbrush):
        self._tool_type = tool_type
        self.__update_cursor()
        
    def set_stroke_size(self, stroke_size= 10):
        if stroke_size < 1:
            self._stroke_size = 1
        else:
            self._stroke_size = stroke_size
        self.__update_cursor()

    def set_stroke_color(self, color = gtk.gdk.Color(0, 0, 0)):
        self._stroke_color = color
    
    def get_stroke_color(self):
        return self._stroke_color
    
    def set_grid_type(self, grid_type):
        self._grid_type = grid_type
        self.__update_grid_surface(self.allocation.width, self.allocation.height)
        self.queue_draw()
    
    def get_grid_type(self):
        return self._grid_type
   
    def undo(self):
        if len(self._paths) > 0:
            self._history.append(self._paths.pop())
            self._cached_painting_surface = self.__build_paths_surface()
            self.queue_draw()
                    
    def redo(self):
        if len(self._history) > 0:
            self._paths.append(self._history.pop())
            self._cached_painting_surface = self.__build_paths_surface()
            self.queue_draw()

    def clear_canvas(self):
        self._cached_painting_surface = None
        self._paths=[]
        self._history = []
        self.queue_draw()
        
    def build_pixbuf(self):
        surface = self.__build_paths_surface()
        return gtk.gdk.pixbuf_new_from_data(
            surface.get_data(), 
            gtk.gdk.COLORSPACE_RGB, True, 8, 
            surface.get_width(), surface.get_height(), 
            surface.get_stride())
            
    def build_isf(self):
        enc = pyisf.IsfEncoder(self._paths)
        return enc
        
    def import_isf(self, data, debug=False):
        dec = pyisf.IsfDecoder(data,True)
        if debug:
            dec.print_info()
        self._paths = dec.paths
        self._cached_painting_surface = self.__build_paths_surface()
        self.queue_draw()

    def do_button_press_event(self, event):
        if event.button == 1:
            self._is_pressed = True
            self._history = []
            draw_attr = DrawAttributes(self._stroke_color, self._stroke_size, self._tool_type)
            path = BrushPath(Point(event.x, event.y), draw_attr)
            self._paths.append(path)
            rec = path.get_intermediate_rectangle()
            self._intermediate_path = path
            self.queue_draw_area(rec.x, rec.y, rec.width, rec.height)
        return True
        
    def do_motion_notify_event(self, event):
        x,y =  event.get_coords()
        if self._is_pressed:
            path = self._paths[-1]
            path.add(Point(x,y))
            rec = path.get_intermediate_rectangle()
            self.queue_draw_area(rec.x, rec.y, rec.width, rec.height)
        return True

    def do_button_release_event(self, event):
        if self._is_pressed:
            self._is_pressed = False
            self._intermediate_path = None
            self.__update_cached_painting_surface(self._paths[-1])
        return True

    def do_expose_event(self, event):
        x , y, width, height = event.area
        ctx = event.window.cairo_create()      
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        cr = cairo.Context(surface)
        cr.translate(-x, -y)
        if self._cached_painting_surface:
            cr.set_source_surface(self._cached_painting_surface,0,0)        
            cr.paint()
        if self._intermediate_path:
            self._intermediate_path.draw(cr,0,0)
        self.__draw_grid(cr, x, y)
        self.__draw_canvas(cr, x,y, width, height)
        ctx.set_source_surface(surface,x,y)
        ctx.paint()
        return False

    def do_realize(self):
        gtk.DrawingArea.do_realize(self)
        self.__update_cursor()
        
    def do_configure_event(self, event):
        self.__update_grid_surface(event.width, event.height)
      
    def __draw_grid(self, ctx, x,y):
        if self._cached_grid_surface is not None:
            ctx.save()
            ctx.set_operator(cairo.OPERATOR_DEST_OVER)            
            ctx.set_source_surface(self._cached_grid_surface, 0, 0)
            ctx.paint()
            ctx.restore()

    def __draw_canvas(self, ctx, x,y, width, height, color = gtk.gdk.color_parse('#ffffff')):
        ctx.save()
        set_context_color(ctx, color)
        ctx.set_operator(cairo.OPERATOR_DEST_OVER)
        ctx.paint()
        ctx.restore()

    def __update_cached_painting_surface(self, path):

        if not self._cached_painting_surface:
            self._cached_painting_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
        
        surface_width = self._cached_painting_surface.get_width()
        surface_height = self._cached_painting_surface.get_height()
        rec = path.get_path_rectangle() 
    
        combined = rec.union( gtk.gdk.Rectangle(0,0,surface_width,surface_height))        
        if (surface_width < combined.width) or (surface_height < combined.height):
            self._cached_painting_surface = resize_image_surface(
                self._cached_painting_surface, combined.width, combined.height)
        ctx = cairo.Context(self._cached_painting_surface)
        path.draw(ctx)
        self.queue_draw_area(rec.x, rec.y, rec.width, rec.height)
                
    def __update_grid_surface(self, width, height, color = gtk.gdk.color_parse('#C0C0C0')):
        self._cached_grid_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        ctx = cairo.Context(self._cached_grid_surface)        
        space = self._grid_size[self._grid_type]
        if space < 1: return
        x, y = 0,0
        position = x + space
        end = x + width
        ctx.save()
        set_context_color(ctx, color)
        ctx.set_line_width(1)
        position = x + space
        end = x + width
        while position < end:
            ctx.move_to(position, y)
            ctx.line_to(position, y + height)
            position += space
        position = y + space
        end = y + height
        while position < end:
            ctx.move_to(x, position )
            ctx.line_to(x + width, position)
            position += space
        ctx.stroke()
        ctx.restore()

    def __build_paths_surface(self):
        rec = gtk.gdk.Rectangle()
        for path in self._paths:
            rec = rec.union(path.get_path_rectangle())
        width = max(1, rec.width)
        height = max(1, rec.height)
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        ctx = cairo.Context(surface)
        for path in self._paths:
            path.draw(ctx)
        return surface

    def __update_cursor(self):
        indicator_surface = self._tool_type_to_surface[self._tool_type]
        radius = int(self._stroke_size/2.0)
        shift = radius +1
        cursor_width = int(radius + max(self._pointer_surface.get_width(),  indicator_surface.get_width()))
        cursor_height = int(radius + max(self._pointer_surface.get_height(), indicator_surface.get_height()))                    
        cursor_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, cursor_width, cursor_height)
        ctx = cairo.Context(cursor_surface)
        ctx.save()
        ctx.set_line_width(1.0), ctx.set_source_rgb(0,0,0), ctx.set_dash([1,1],0)
        ctx.arc(shift,shift,radius, 0, 2 * pi), ctx.stroke()
        ctx.set_source_surface(self._pointer_surface, shift, shift), ctx.paint()
        ctx.set_source_surface(indicator_surface, shift, shift), ctx.paint()
        ctx.restore()
        pixbuf = gtk.gdk.pixbuf_new_from_data(
            cursor_surface.get_data(), 
            gtk.gdk.COLORSPACE_RGB, True, 8, 
            cursor_surface.get_width(), cursor_surface.get_height(), 
            cursor_surface.get_stride())
        cursor = gtk.gdk.Cursor(self.window.get_display(), pixbuf, shift, shift)
        self.window.set_cursor(cursor)

gobject.type_register(InkCanvas)

class InkToolbar(gtk.Toolbar):
    def __init__(self, theme, ink_canvas):
        gtk.Toolbar.__init__(self)
        self._inkcanvas = ink_canvas

        ### paint button
        paint_image = gtk.Image()
        paint_image.set_from_pixbuf(theme.load_icon('paintbrush', 48, 0))
        paint_button = gtk.RadioToolButton()
        paint_button.set_icon_widget(paint_image)
        paint_button.set_label('Paintbrush')
        paint_button.connect('clicked', self.__set_paint)
        
        ### eraser button
        erase_image = gtk.Image()
        erase_image.set_from_pixbuf(theme.load_icon('eraser', 48, 0))
        erase_button = gtk.RadioToolButton(paint_button)
        erase_button.set_icon_widget(erase_image)
        erase_button.set_label('Eraser')
        erase_button.connect('clicked', self.__set_eraser)

        ### Color select
        self._color_label = ColorLabel(self._inkcanvas.get_stroke_color())
        hbox = gtk.HBox()        
        hbox.pack_start(self._color_label)
        hbox.pack_start(gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_IN))
        color_button = gtk.ToolItem()
        color_button_t = ColorButton(hbox)
        color_button_t.connect('color-set', self.__color_set, paint_button)
        color_button.add(color_button_t)
        
        ### clear button
        imgclear = gtk.Image()
        imgclear.set_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_LARGE_TOOLBAR )
        clear = gtk.ToolButton(imgclear)
        clear.set_label('Clear')
        clear.connect( 'clicked', self.__clear_canvas )
        
        
        main_img = gtk.Image()
        main_img.set_from_pixbuf(theme.load_icon('medium_grid', 48, 0))
        blank_img = gtk.Image()
        blank_img.set_from_pixbuf(theme.load_icon('no_grid', 48, 0) )
        small_img = gtk.Image()
        small_img.set_from_pixbuf(theme.load_icon('small_grid', 48, 0))
        medium_img = gtk.Image()
        medium_img.set_from_pixbuf(theme.load_icon('medium_grid', 48, 0))
        large_img = gtk.Image()
        large_img.set_from_pixbuf(theme.load_icon('large_grid', 48, 0))
        
        ### grid button
        grid_button_t = GridButton(
            main_img, blank_img, small_img, medium_img, large_img,
            self._inkcanvas.get_grid_type())
        grid_button_t.connect( 'grid-type-set', self.__set_grid_type)
        grid_button = gtk.ToolItem()
        grid_button.add(grid_button_t)

        ### undo Button
        undo_button = gtk.ToolButton()
        undo_button.set_stock_id(gtk.STOCK_UNDO)
        undo_button.connect("clicked", self.__undo)

        ### redo Button
        redo_button = gtk.ToolButton()
        redo_button.set_stock_id(gtk.STOCK_REDO)
        redo_button.connect("clicked", self.__redo)
        
        ### size Slider
        brushsmall_t = gtk.Image()
        brushsmall_t.set_from_pixbuf(theme.load_icon('brush-small', 48, 0))
        brushsmall = gtk.ToolItem()
        brushsmall.add(brushsmall_t)
        
        brushlarge_t = gtk.Image()
        brushlarge_t.set_from_pixbuf(theme.load_icon('brush-large', 48, 0))
        brushlarge = gtk.ToolItem()
        brushlarge.add(brushlarge_t)
        
        brush_slider_t = gtk.HScale(gtk.Adjustment(value=8, lower=1, upper=20, step_incr=0.5, page_incr=1, page_size=0))
        brush_slider_t.set_size_request(130, -1)
        brush_slider_t.set_value_pos(gtk.POS_RIGHT)
        brush_slider_t.set_digits(0)
        brush_slider_t.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
        brush_slider_t.connect("value-changed", self.__set_size)
        brush_slider = gtk.ToolItem()
        brush_slider.add(brush_slider_t)
                
        ### toolbar
        self.set_show_arrow(True)
        self.insert(color_button, -1)
        self.insert(gtk.SeparatorToolItem(), -1)
        self.insert(paint_button, -1)
        self.insert(erase_button, -1)
        self.insert(gtk.SeparatorToolItem(), -1)
        self.insert(undo_button, -1)
        self.insert(redo_button, -1)
        self.insert(gtk.SeparatorToolItem(), -1)
        self.insert(clear, -1)
        self.insert(gtk.SeparatorToolItem(), -1)
        self.insert(grid_button, -1)
        self.insert(gtk.SeparatorToolItem(), -1)
        self.insert(brushsmall, -1)
        self.insert(brush_slider, -1)
        self.insert(brushlarge, -1)

    def __color_set(self, widget, color, paint_button):
        print color.to_string()
        self._color_label.set_color(color)
        self._inkcanvas.set_stroke_color(color)
        self._inkcanvas.set_tool_type(ToolType.Paintbrush)
        paint_button.set_active(True)

    def __set_paint(self, widget=None):
        self._inkcanvas.set_tool_type(ToolType.Paintbrush)

    def __set_eraser(self, widget=None):
        self._inkcanvas.set_tool_type(ToolType.Eraser)

    def __clear_canvas(self, widget):
        self._inkcanvas.clear_canvas()

    def __set_grid_type(self, widget, grid_type):
        self._inkcanvas.set_grid_type(grid_type)

    def __undo(self, widget):
        self._inkcanvas.undo()
        
    def __redo(self, widget):
        self._inkcanvas.redo()
 
    def __set_size(self, range_widget):
        self._inkcanvas.set_stroke_size(range_widget.get_value())

gobject.type_register(InkToolbar)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.