File: cellrenderer_progress.pl

package info (click to toggle)
libgtk2-perl 2%3A1.244-1%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,524 kB
  • sloc: perl: 21,568; ansic: 122; makefile: 6
file content (185 lines) | stat: -rw-r--r-- 4,653 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/perl -w

# ported from Tim-Philipp Meuller's Tree View tutorial,
# http://scentric.net/tutorial/sec-custom-cell-renderers.html#sec-custom-cell-renderer-example-body
# by muppet, 6 feb 04.
#
# This is based mainly on GtkCellRendererProgress
#  in GAIM, written and (c) 2002 by Sean Egan
#  (Licensed under the GPL), which in turn is
#  based on Gtk's GtkCellRenderer[Text|Toggle|Pixbuf]
#  implementation by Jonathan Blandford */

package Mup::CellRendererProgress;

use strict;
use warnings;
use Glib qw(G_PARAM_READWRITE);
use Gtk2;
use Glib::Object::Subclass
  Gtk2::CellRenderer::,
  properties => [
    Glib::ParamSpec->double ('percentage',
                             'Percentage',
                             'The fractional progress to display',
                             0.0, 1.0, 0.0, G_PARAM_READWRITE),
  ],
  ;


sub INIT_INSTANCE {
  my $self = shift;
  $self->set (mode => 'inert',
              xpad => 2,
              ypad => 2);
  $self->{percentage} = 0.0;
}

# we'll use the default new, GET_PROPERTY and SET_PROPERTY provided by
# Glib::Object::Subclass.


#
# calculate the size of our cell, taking into account padding and
# alignment properties of parent.
#

use constant FIXED_WIDTH  => 100;
use constant FIXED_HEIGHT => 10;

sub MAX { $_[0] > $_[1] ? $_[0] : $_[1] }

sub GET_SIZE {
  my ($cell, $widget, $cell_area) = @_;
  my ($x_offset, $y_offset) = (0, 0);

  my $width  = int ($cell->get ('xpad') * 2 + FIXED_WIDTH);
  my $height = int ($cell->get ('ypad') * 2 + FIXED_HEIGHT);

  if ($cell_area) {

    $x_offset = $cell->get ('xalign') * ($cell_area->width - $width);
    $x_offset = MAX ($x_offset, 0);

    $y_offset = $cell->get ('yalign') * ($cell_area->height - $height);
    $y_offset = MAX ($y_offset, 0);
  }

  return ($x_offset, $y_offset, $width, $height);
}


sub RENDER {
  my ($cell, $window, $widget, $background_area, $cell_area, $expose_area, $flags) = @_;

  # invoke GET_SIZE directly to avoid a lot of marshalling overhead.
  my ($x_offset, $y_offset, $width, $height)
            = $cell->GET_SIZE ($widget, $cell_area);

  my $state = $widget->has_focus ? 'active' : 'normal';

  my ($xpad, $ypad) = $cell->get (qw(xpad ypad));

  $width  -= $xpad*2;
  $height -= $ypad*2;

  my $style = $widget->style;
  $style->paint_box ($window,
                     'normal', 'in',
                     undef, $widget, "trough",
                     $cell_area->x + $x_offset + $xpad,
                     $cell_area->y + $y_offset + $ypad,
                     $width - 1, $height - 1);

  $style->paint_box ($window,
                     $state, 'out',
                     undef, $widget, "bar",
                     $cell_area->x + $x_offset + $xpad,
                     $cell_area->y + $y_offset + $ypad,
                     $width * $cell->{percentage},
                     $height - 1);
}


package main;

use strict;
use Glib qw(TRUE FALSE);
use Gtk2 -init;

my $liststore;
my $increasing = TRUE; # direction of progress bar change

use constant {
  COL_PERCENTAGE => 0,
  COL_TEXT       => 1,
  NUM_COLS       => 2,

  STEP           => 0.01,
};


sub increase_progress_timeout {
  my $renderer = shift;
  my $iter = $liststore->get_iter_first; # first and only row

  my $perc = $liststore->get ($iter, COL_PERCENTAGE);

  if ($perc > (1.0 - STEP)  ||  ($perc < STEP && $perc > 0.0) ) {
    $increasing = (!$increasing);
  }

  if ($increasing) {
    $perc += STEP;
  } else {
    $perc -= STEP;
  }

  my $buf = sprintf '%u %%', $perc*100;

  $liststore->set ($iter, COL_PERCENTAGE, $perc, COL_TEXT, $buf);

  return TRUE; # Call again
}


sub create_view_and_model {
  $liststore = Gtk2::ListStore->new (qw(Glib::Double Glib::String));
  my $iter = $liststore->append;
  $liststore->set ($iter, COL_PERCENTAGE, 0.5); # start at 50%

  my $view = Gtk2::TreeView->new ($liststore);

  my $renderer = Gtk2::CellRendererText->new;
  my $col = Gtk2::TreeViewColumn->new;
  $col->pack_start ($renderer, TRUE);
  $col->add_attribute ($renderer, text => COL_TEXT);
  $col->set_title ("Progress");
  $view->append_column ($col);

  $renderer = Mup::CellRendererProgress->new;
  $col = Gtk2::TreeViewColumn->new;
  $col->pack_start ($renderer, TRUE);
  $col->add_attribute ($renderer, percentage => COL_PERCENTAGE);
  $col->set_title ("Progress");
  $view->append_column ($col);

  Glib::Timeout->add (50, \&increase_progress_timeout);

  return $view;
}


my $window = Gtk2::Window->new;
$window->set_default_size (150, 100);
$window->signal_connect (delete_event => sub {Gtk2->main_quit});

my $view = create_view_and_model();

$window->add ($view);

$window->show_all;

Gtk2->main;