Difference between revisions of "Features/GTK3/Porting/Typing Turtle"

From Sugar Labs
< Features‎ | GTK3‎ | Porting
Jump to navigation Jump to search
Line 7: Line 7:
 
= Port to Cairo =
 
= Port to Cairo =
  
'''README''': before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.
+
'''README''': before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [PATCH http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch]
  
 
== Code Snippets ==
 
== Code Snippets ==
Line 104: Line 104:
  
 
  cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)
 
  cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)
 +
cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),
 +
              self.backgroundpixbuf.get_height())
 +
cr.paint()
 +
 +
==== Gtk3 version ====
 +
 +
Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)
 
  cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),
 
  cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),
 
               self.backgroundpixbuf.get_height())
 
               self.backgroundpixbuf.get_height())
Line 182: Line 189:
 
  Gdk.EventType.KEY_RELEASE
 
  Gdk.EventType.KEY_RELEASE
  
----
+
== Gdk.Keymap.translate_keyboard_state ==
  
 
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state
 
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state
 
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state
 
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state
  
----
+
Old way:
  
  -   def expose_cb(self, area, event):
+
  t = self.keymap.translate_keyboard_state(key['key-scan'], self.active_state, self.active_group)
-        self.draw()
+
 
  +    def draw_cb(self, area, cr):
+
New way:
+        self.draw(cr)
+
 
 +
success, keyval, effective_group, level, consumed_modifiers = self.keymap.translate_keyboard_state(key['key-scan'], self.active_state, self.active_group)
 +
 
 +
 
 +
== 'expose-event' & 'draw' event ==
 +
 
 +
The new ''draw'' event that refers to the old ''expose-event'' into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:
 +
 
 +
''expose-event''
 +
 
 +
def expose_cb(self, area, event):
 +
    self.draw()
 +
 
 +
''draw'' event
 +
 
 +
  def draw_cb(self, area, cr):
 +
    self.draw(cr)
  
 
= Notes =
 
= Notes =
Line 205: Line 228:
 
* [<span style="color: green;">SOLVED</span>] <del>This method, ''set_source_pixbuf'', is not available.</del>
 
* [<span style="color: green;">SOLVED</span>] <del>This method, ''set_source_pixbuf'', is not available.</del>
  
cr = self.get_window().cairo_create()
+
* [<span style="color: green;">SOLVED</span>] <del>We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen</del>
# README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf
 
# Although this methos is not available in Python
 
cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)
 
 
 
Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)
 
 
 
* We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen
 
  
* PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680
+
* [<span style="color: green;">SOLVED</span>] <del>PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680</del>
  
* Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663
+
* [<span style="color: green;">SOLVED</span>] <del>Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663</del>
  
 
= Useful links =
 
= Useful links =

Revision as of 08:56, 2 August 2012

This page is being performed while I'm porting Typing Turtle Activity to Gtk3.

There is a ticket with some useful information that I'm using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I'm having on the port and maybe can be useful for someone else.

I will take this guide as reference on the Gtk3 porting.

Port to Cairo

README: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [PATCH http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch]

Code Snippets

Draw a rectangle

To draw a rectangle we used to do:

gc = self.window.new_gc()
gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)
self.area.window.draw_rectangle(gc, True, x, y, w, h)

The arguments for alloc_color are between 0-65535 and the set_source_rgb method from cairo are between 0-1, so we have to convert these values as well:

cr.set_source_rgb(0.762, 0.762, 0.762)
cr.rectangle(x, y, w, h)
cr.fill()

Note that the second attributo of draw_rectangle tells us about if the rectangle is filled or not. In this case is True, so we use cr.fill() in the new way but if we want just the outside lines of the rectangle we should use cr.stroke()

Write some text

This is the old way to do it:

title = _('You finished!')
layout = self.area.create_pango_layout(title)
layout.set_font_description(pango.FontDescription('Serif Bold 16'))    
size = layout.get_size()
tx = x+w/2-(size[0]/pango.SCALE)/2
ty = y + 100
self.area.window.draw_layout(gc, tx, ty, layout)

and this is the way that I used to do it with pangocairo:

title = _('You finished!')
pango_cr = pangocairo.CairoContext(cr)
pango_cr.set_source_rgb(0, 0, 0)
pango_layout = cr.create_layout()
pango_layout.set_font_description(pango.FontDescription('Serif Bold 16'))
pango_layout.set_text(title)
size = pango_layout.get_size()
tx = x + (w / 2) - (size[0] / pango.SCALE) / 2
ty = y + 100
pango_cr.move_to(tx, ty)
pango_cr.show_layout(pango_layout)
pango_cr.stroke()


Draw a line

This is the old way:

gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)
self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), 
                           int(b.x), int(b.y + b.size))

and should be replaced by this new way using cairo

cr.set_source_rgb(0, 0, 0)
cr.move_to(int(b.x), int(b.y + b.size / 2))
cr.line_to(int(b.x), int(b.y + b.size))
cr.stroke()

Draw an arc

Old way to do it (notice the second argument of draw_arc: filled):

gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])
self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)

new way:

cr.set_source_rgb(b.color[0], b.color[1], b.color[2])
cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)
cr.fill()

Tips & tricks

Convert cairo.Surface to GdkPixbuf

import StringIO
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)
cr = cairo.Context(surface)
[... draw something into the surface ...]
pixbuf_data = StringIO.StringIO()
surface.write_to_png(pixbuf_data)
pxb_loader = gtk.gdk.PixbufLoader(image_type='png')
pxb_loader.write(pixbuf_data.getvalue())
temp_pix = pxb_loader.get_pixbuf()
pxb_loader.close()

Paint a GdkPixbuf into the canvas

cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)
cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),
             self.backgroundpixbuf.get_height())
cr.paint()

Gtk3 version

Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)
cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),
             self.backgroundpixbuf.get_height())
cr.paint()

Code Snippets

Gtk.TextBuffer

self.lessonbuffer = gtk.TextBuffer(self.tagtable)
self.lessontext = gtk.TextView(self.lessonbuffer)

replaced by:

self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)
self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)

Gdk.Event

event.state

replaced by:

event.get_state()

Rsvg

import rsvg
image = rsvg.Handle(file=filename)

replaced by:

from gi.repository import Rsvg
image = Rsvg.Handle.new_from_file(filename)

Gtk.TextTag

instructions_tag = Gtk.TextTag('instructions')

replaced by:

instructions_tag = Gtk.TextTag.new('instructions')

Gdk.Keymap

entries = self.keymap.get_entries_for_keyval(keyval)
for e in entries:
    e[0], e[1], e[2]

replaced by:

valid, entries = self.keymap.get_entries_for_keyval(keyval)
for e in entries:
    e.keycode, e.group, e.level

Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.

GdkPixbuf.PixbufLoader

Change this:

pxb_loader = gtk.gdk.PixbufLoader(image_type='png')

by:

pxb_loader = GdkPixbuf.PixbufLoader.new_with_type('png')

KEY_PRESS

This should be done by the pygi-convert.sh script.

gtk.gdk.KEY_PRESS
gtk.gdk.KEY_RELEASE

replaced by

Gdk.EventType.KEY_PRESS
Gdk.EventType.KEY_RELEASE

Gdk.Keymap.translate_keyboard_state

Old way:

t = self.keymap.translate_keyboard_state(key['key-scan'], self.active_state, self.active_group)

New way:

success, keyval, effective_group, level, consumed_modifiers = self.keymap.translate_keyboard_state(key['key-scan'], self.active_state, self.active_group)


'expose-event' & 'draw' event

The new draw event that refers to the old expose-event into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:

expose-event

def expose_cb(self, area, event):
    self.draw()

draw event

def draw_cb(self, area, cr):
    self.draw(cr)

Notes

  • I found this chunk of code in the source (keyboard.py L515) and I didn't understand what it means
# Hack to get the current modifier state - which will not be represented by the event.
state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]

Missing / problematic things

  • [SOLVED] This method, set_source_pixbuf, is not available.
  • [SOLVED] We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen

Useful links