~timo-jyrinki/ubuntu/trusty/pitivi/backport_utopic_fixes

« back to all changes in this revision

Viewing changes to pitivi/utils/ui.py

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2014-03-29 15:22:50 UTC
  • mto: (3.1.23 experimental)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: package-import@ubuntu.com-20140329152250-flg9onx416bqf3e3
Tags: upstream-0.93
Import upstream version 0.93

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
"""
28
28
 
29
29
 
30
 
from decimal import Decimal
 
30
import cairo
 
31
import decimal
 
32
import os
 
33
import urllib
 
34
 
31
35
from gettext import ngettext, gettext as _
 
36
 
 
37
from gi.repository import Clutter
 
38
from gi.repository import Cogl
32
39
from gi.repository import GLib
33
40
from gi.repository import GES
 
41
from gi.repository import Gdk
 
42
from gi.repository import Gio
34
43
from gi.repository import Gst
35
44
from gi.repository import Gtk
36
45
from gi.repository.GstPbutils import DiscovererVideoInfo, DiscovererAudioInfo,\
37
 
    DiscovererStreamInfo, DiscovererSubtitleInfo
38
 
from itertools import izip
39
 
from urllib import unquote
40
 
import cairo
41
 
import os
 
46
    DiscovererStreamInfo, DiscovererSubtitleInfo, DiscovererInfo
 
47
 
 
48
from pitivi.utils.misc import path_from_uri
42
49
 
43
50
from pitivi.utils.loggable import doLog, ERROR
44
51
 
47
54
##
48
55
# UI pixels information constants
49
56
##
 
57
 
50
58
LAYER_HEIGHT_EXPANDED = 50
51
59
LAYER_HEIGHT_COLLAPSED = 15
52
60
TRACK_SPACING = 8
56
64
PADDING = 6
57
65
SPACING = 10
58
66
 
59
 
PLAYHEAD_WIDTH = 2
 
67
PLAYHEAD_WIDTH = 1
60
68
CANVAS_SPACING = 21
61
69
KEYFRAME_SIZE = 8
62
70
 
 
71
PLAYHEAD_COLOR = Clutter.Color.new(200, 0, 0, 255)
 
72
 
63
73
# Layer creation blocking time in s
64
74
LAYER_CREATION_BLOCK_TIME = 0.2
65
75
 
91
101
LAYER_CONTROL_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/layer-control", 0, TYPE_PITIVI_LAYER_CONTROL)
92
102
 
93
103
 
 
104
def _get_settings(schema):
 
105
    if schema not in Gio.Settings.list_schemas():
 
106
        return None
 
107
    return Gio.Settings(schema=schema)
 
108
 
 
109
 
 
110
def _get_font(font_spec, default):
 
111
    raw_font = default
 
112
    settings = _get_settings("org.gnome.desktop.interface")
 
113
    if settings:
 
114
        if font_spec in settings.list_keys():
 
115
            raw_font = settings.get_string(font_spec)
 
116
    face = raw_font.rsplit(" ", 1)[0]
 
117
    return cairo.ToyFontFace(face)
 
118
 
 
119
NORMAL_FONT = _get_font("font-name", "Cantarell")
 
120
DOCUMENT_FONT = _get_font("document-font-name", "Sans")
 
121
MONOSPACE_FONT = _get_font("monospace-font-name", "Monospace")
 
122
 
 
123
 
94
124
# ---------------------- ARGB color helper-------------------------------------#
95
125
def pack_color_32(red, green, blue, alpha=0xFFFF):
96
126
    """Packs the specified 16bit color values in a 32bit RGBA value."""
169
199
    return tuple(float(int(value[i:i + 2], 16)) / 255.0 for i in range(0, 6, 2))
170
200
 
171
201
 
172
 
#------ Helper to help beatify indos so they can be displayed in the UI -----#
 
202
def create_cogl_color(red, green, blue, alpha):
 
203
    color = Cogl.Color()
 
204
    color.init_from_4ub(red, green, blue, alpha)
 
205
    return color
 
206
 
 
207
 
 
208
def set_cairo_color(context, color):
 
209
    if type(color) is Clutter.Color:
 
210
        color = (color.red, color.green, color.blue)
 
211
 
 
212
    if type(color) is Gdk.RGBA:
 
213
        cairo_color = (float(color.red), float(color.green), float(color.blue))
 
214
    elif type(color) is tuple:
 
215
        # Cairo's set_source_rgb function expects values from 0.0 to 1.0
 
216
        cairo_color = map(lambda x: max(0, min(1, x / 255.0)), color)
 
217
    else:
 
218
        raise Exception("Unexpected color parameter: %s, %s" % (type(color), color))
 
219
    context.set_source_rgb(*cairo_color)
 
220
 
 
221
 
173
222
def beautify_info(info):
 
223
    """
 
224
    Formats the specified info for display.
 
225
 
 
226
    @type info: L{DiscovererInfo}
 
227
    """
174
228
    ranks = {
175
229
        DiscovererVideoInfo: 0,
176
230
        DiscovererAudioInfo: 1,
190
244
            beautified_string = beautify_stream(stream)
191
245
        except NotImplementedError:
192
246
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
193
 
        else:
194
 
            if beautified_string is not None:
195
 
                nice_streams_txts.append(beautified_string)
 
247
            continue
 
248
        if beautified_string:
 
249
            nice_streams_txts.append(beautified_string)
196
250
 
197
 
    return ("<b>" + info_name(info) + "</b>\n" +
198
 
        "\n".join((nice for nice in nice_streams_txts)))
 
251
    return ("<b>" + path_from_uri(info.get_uri()) + "</b>\n" +
 
252
        "\n".join(nice_streams_txts))
199
253
 
200
254
 
201
255
def info_name(info):
202
 
    """Return a human-readable filename (without the path and quoting)."""
 
256
    """
 
257
    Return a human-readable filename (without the path and quoting).
 
258
 
 
259
    @type info: L{GES.Asset} or L{DiscovererInfo}
 
260
    """
203
261
    if isinstance(info, GES.Asset):
204
 
        filename = unquote(os.path.basename(info.get_id()))
 
262
        filename = urllib.unquote(os.path.basename(info.get_id()))
 
263
    elif isinstance(info, DiscovererInfo):
 
264
        filename = urllib.unquote(os.path.basename(info.get_uri()))
205
265
    else:
206
 
        filename = unquote(os.path.basename(info.get_uri()))
 
266
        raise Exception("Unsupported argument type: %s" % type(info))
207
267
    return GLib.markup_escape_text(filename)
208
268
 
209
269
 
335
395
    return ", ".join(parts)
336
396
 
337
397
 
338
 
#--------------------- UI drawing helper -------------------------------------#
339
 
# from http://cairographics.org/cookbook/roundedrectangles/
340
 
def roundedrec(context, x, y, w, h, r=10):
341
 
    "Draw a rounded rectangle"
342
 
    #   A****BQ
343
 
    #  H      C
344
 
    #  *      *
345
 
    #  G      D
346
 
    #   F****E
347
 
 
348
 
    context.move_to(x + r, y)      # Move to A
349
 
    context.line_to(x + w - r, y)  # Straight line to B
350
 
 
351
 
    # Curve to C, Control points are both at Q
352
 
    context.curve_to(x + w, y, x + w, y, x + w, y + r)
353
 
    context.line_to(x + w, y + h - r)                               # Move to D
354
 
    context.curve_to(x + w, y + h, x + w, y + h, x + w - r, y + h)  # Curve to E
355
 
    context.line_to(x + r, y + h)                                   # Line to F
356
 
    context.curve_to(x, y + h, x, y + h, x, y + h - r)              # Curve to G
357
 
    context.line_to(x, y + r)                                       # Line to H
358
 
    context.curve_to(x, y, x, y, x + r, y)                          # Curve to A
359
 
    return
360
 
 
361
 
 
362
398
#--------------------- Gtk widget helpers ------------------------------------#
363
399
def model(columns, data):
364
400
    ret = Gtk.ListStore(*columns)
391
427
        if row[1] == key:
392
428
            return str(row[0])
393
429
    if isinstance(key, Gst.Fraction):
394
 
        return "%.3f" % Decimal(float(key.num) / key.denom)
 
430
        return "%.3f" % decimal.Decimal(float(key.num) / key.denom)
395
431
    return str(key)
396
432
 
 
433
 
 
434
def alter_style_class(style_class, target_widget, css_style):
 
435
    css_provider = Gtk.CssProvider()
 
436
    toolbar_css = "%s { %s }" % (style_class, css_style)
 
437
    css_provider.load_from_data(toolbar_css.encode('UTF-8'))
 
438
    style_context = target_widget.get_style_context()
 
439
    style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
 
440
 
 
441
 
397
442
#------------------------ encoding datas ----------------------------------------#
398
443
# FIXME This should into a special file
399
444
frame_rates = model((str, object), (
451
496
    (_("Anamorphic (2.39)"), Gst.Fraction(239, 100)),
452
497
    (_("Anamorphic (2.4)"), Gst.Fraction(24, 10)),
453
498
))
454
 
 
455
 
 
456
 
# ---------------------- Classes ---------------------------------------------#
457
 
class Point(tuple):
458
 
 
459
 
    def __new__(cls, x, y):
460
 
        return tuple.__new__(cls, (x, y))
461
 
 
462
 
    def __pow__(self, scalar):
463
 
        """Returns the scalar multiple self, scalar"""
464
 
        return Point(self[0] * scalar, self[1] * scalar)
465
 
 
466
 
    def __rpow__(self, scalar):
467
 
        """Returns the scalar multiple of self, scalar"""
468
 
        return self ** scalar
469
 
 
470
 
    def __mul__(self, p2):
471
 
        return Point(*(a * b for a, b in izip(self, p2)))
472
 
 
473
 
    def __div__(self, other):
474
 
        return Point(*(a / b for a, b in izip(self, p2)))
475
 
 
476
 
    def __floordiv__(self, scalar):
477
 
        """Returns the scalar division of self and scalar"""
478
 
        return Point(self[0] / scalar, self[1] / scalar)
479
 
 
480
 
    def __add__(self, p2):
481
 
        """Returns the 2d vector sum self + p2"""
482
 
        return Point(*(a + b for a, b in izip(self, p2)))
483
 
 
484
 
    def __sub__(self, p2):
485
 
        """Returns the 2-dvector difference self - p2"""
486
 
        return Point(*(a - b for a, b in izip(self, p2)))
487
 
 
488
 
    def __abs__(self):
489
 
        return Point(*(abs(a) for a in self))
490
 
 
491
 
    @classmethod
492
 
    def from_item_bounds(self, item):
493
 
        bounds = item.get_bounds()
494
 
        return Point(bounds.x1, bounds.y1), Point(bounds.x2, bounds.y2)
495
 
 
496
 
    @classmethod
497
 
    def from_widget_bounds(self, widget):
498
 
        x1, y1, x2, y2 = widget.get_bounds()
499
 
        return Point(x1, y1), Point(x2, y2)