App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Gtk2/IntradayImage.pm view on Meta::CPAN
('symbol',
__('Symbol'),
'The symbol of the stock or commodity to be shown.',
'', # default
Glib::G_PARAM_READWRITE),
Glib::ParamSpec->string
('mode',
'Mode',
'The intraday mode, such as "1d" for one day. The possible values here depend on the symbol\'s data source code.',
'', # default
Glib::G_PARAM_READWRITE)];
sub INIT_INSTANCE {
my ($self) = @_;
$self->{'symbol'} = '';
$self->{'mode'} = '';
# Single pixbuf draw operation doesn't need double buffering.
$self->set_double_buffered (0);
$self->set_app_paintable (1);
App::Chart::chart_dirbroadcast()->connect_for_object
('intraday-changed', \&_do_intraday_changed, $self);
}
sub SET_PROPERTY {
my ($self, $pspec, $newval) = @_;
my $pname = $pspec->get_name;
### IntradayImage SET_PROPERTY(): "$pname $newval"
my $oldval = $self->{$pname};
$self->{$pname} = $newval; # per default GET_PROPERTY
### stored to: ''.\$self->{$pname}
if ($oldval eq $newval) {
return;
}
if ($pname eq 'symbol' || $pname eq 'mode') {
# new image (or new no image)
delete $self->{'xor_background'}; # new colour scheme
$self->queue_resize;
$self->queue_draw;
}
}
# 'size-request' class closure
sub _do_size_request {
my ($self, $req) = @_;
### IntradayImage _do_size_request()
my $pixbuf = _load_pixbuf ($self);
if (ref $pixbuf) {
$req->width ($pixbuf->get_width);
$req->height ($pixbuf->get_height);
} else {
$req->width (35 * Gtk2::Ex::Units::em($self));
$req->height (6 * Gtk2::Ex::Units::line_height($self));
}
### _do_size_request() decide: $req->width."x".$req->height
}
# 'expose-event' class closure
sub _do_expose_event {
my ($self, $event) = @_;
### IntradayImage _do_expose_event(): $self->get_name.' "'.($self->{'symbol'}||'[nosymbol]').'" "'.($self->{'mode'}||'[nomode]').'"'
my $win = $self->window;
# Reading the database on every expose probably isn't fast, but we're not
# expecting to scroll or anything much, so leaving the data on disk might
# save a little memory.
#
my $pixbuf = _load_pixbuf ($self);
if (! ref $pixbuf) {
my $errmsg = $pixbuf;
### pixbuf load error: $errmsg
$win->clear;
App::Chart::Gtk2::GUI::draw_text_centred ($self, undef, $errmsg);
return Gtk2::EVENT_PROPAGATE;
}
my $pix_width = $pixbuf->get_width;
my $pix_height = $pixbuf->get_height;
### pixbuf: "${pix_width}x${pix_height}"
my ($x, $y, $alloc_width, $alloc_height) = $self->allocation->values;
### alloc size: "${alloc_width}x${alloc_height} at $x,$y"
# windowed
$x = 0; $y = 0;
# align in allocated space, if alloc bigger than pixbuf
my $x_offset = max(0, ($alloc_width - $pix_width) / 2);
my $y_offset = max(0, ($alloc_height - $pix_height) / 2);
# restrict to alloc width/height, in case pixbuf+pad is bigger than alloc
my $width = min ($alloc_width - $x_offset, $pix_width);
my $height = min ($alloc_height - $y_offset, $pix_height);
my $gc = $self->get_style->bg_gc($self->state);
$gc->set_clip_region ($event->region);
$win->draw_pixbuf ($gc, $pixbuf,
0, 0, # source x,y
$x+$x_offset, $y+$y_offset, # dest x,y
$width, $height,
'normal', # dither
0, 0); # dither x,y
my $region = $event->region->copy;
$region->subtract (Gtk2::Gdk::Region->rectangle
(Gtk2::Gdk::Rectangle->new
($x+$x_offset, $y+$y_offset, $width, $height)));
$gc->set_clip_region ($region);
$win->draw_rectangle ($gc, 1, $event->area->values);
$gc->set_clip_region (undef);
return Gtk2::EVENT_PROPAGATE;
}
sub _load_pixbuf {
( run in 0.839 second using v1.01-cache-2.11-cpan-39bf76dae61 )