Gtk2::CellRendererSpinButton-Z
- From: zentara <zentara1 sbcglobal net>
- To: gtk-perl-list gnome org
- Subject: Gtk2::CellRendererSpinButton-Z
- Date: Mon, 6 Mar 2006 15:57:30 -0500
Hi,
Here is a working package, for the
Gtk2::CellRendererSpinButton.
It sets initial value, updates itself, and sets
new initial value at each edit.
I use a package global to hold the current value,
and if anyone knows a better way, my ears are open. :-)
#!/usr/bin/perl -w
use strict;
use Gtk2 -init;
# package Gtk2::CellRendererSpinButtonZ;
#
# with a simple example usage
#
#this package is based on the Mup::CellRendererSpinButton
#by muppet, but added
#
# 1. SET_PROPERTY sub to load and show initial values
# 2. an extra signal handler for the focus-out to set
# the spinbox, when going out of focus
# 3. a global $cur_val to maintain the initial editing
# start point
package Gtk2::CellRendererSpinButtonZ;
use POSIX qw(DBL_MAX UINT_MAX);
use constant x_padding => 2;
use constant y_padding => 3;
use Gtk2::Gdk::Keysyms;
#global to hold current value to load when start editing
my $cur_val;
use Glib::Object::Subclass "Gtk2::CellRenderer",
signals => {
edited => {
flags => [ qw(run-last) ],
param_types => [ qw(Glib::String Glib::Double) ],
},
},
properties => [
Glib::ParamSpec->double(
"xalign", "Horizontal Alignment",
"Where am i?", 0.0, 1.0, 1.0, [ qw(readable writable) ]
),
Glib::ParamSpec->boolean(
"editable", "Editable",
"Can I change that?", 0,
[ qw(readable writable) ]
),
Glib::ParamSpec->uint(
"digits", "Digits",
"How picky are you?", 0,
UINT_MAX, 2,
[ qw(readable writable) ]
),
map {
Glib::ParamSpec->double(
$_->[ 0 ],
$_->[ 1 ],
$_->[ 2 ],
0.0, DBL_MAX,
$_->[ 3 ],
[ qw(readable writable) ]
)
} (
[ "value", "Value", "How much is the fish?", 0.0 ],
[ "min", "Min", "No way, I have to live!", 0.0 ],
[ "max", "Max", "Ah, you're too generous.", 100.0 ],
[ "step", "Step", "Okay.", 5.0 ]
)
];
sub INIT_INSTANCE {
my $self = shift;
$self->{ editable } = 0;
$self->{ digits } = 2;
$self->{ value } = 0.0;
$self->{ min } = 0.0;
$self->{ max } = 100.0;
$self->{ step } = 5.0;
$self->{ xalign } = 1.0;
}
sub SET_PROPERTY {
my ($self, $pspec, $val) = @_;
$self->{ $pspec->get_name } = $val;
# set the initial editing value
if ($pspec->get_name eq 'value') {
$cur_val = $val;
}
}
sub calc_size {
my ( $cell, $layout, $area ) = @_;
my ( $width, $height ) = $layout->get_pixel_size();
return (
$area
? $cell->{ xalign } * ( $area->width - ( $width + 3 * x_padding ) )
: 0,
0,
$width + x_padding * 2,
$height + y_padding * 2
);
}
sub format_text {
my $cell = shift;
my $format = sprintf '%%.%df', $cell->{ digits };
sprintf $format, $cell->{ value };
}
sub GET_SIZE {
my ( $cell, $widget, $area ) = @_;
my $layout = $cell->get_layout( $widget );
$layout->set_text( $cell->format_text );
return $cell->calc_size( $layout, $area );
}
sub get_layout {
my ( $cell, $widget ) = @_;
return $widget->create_pango_layout( "" );
}
sub RENDER {
my ( $cell, $window, $widget, $background_area, $cell_area, $expose_area,
$flags )
= @_;
my $state;
if ( $flags & 'selected' ) {
$state =
$widget->has_focus()
? 'selected'
: 'active';
}
else {
$state =
$widget->state() eq 'insensitive'
? 'insensitive'
: 'normal';
}
my $layout = $cell->get_layout( $widget );
$layout->set_text( $cell->format_text );
my ( $x_offset, $y_offset, $width, $height ) =
$cell->calc_size( $layout, $cell_area );
$widget->get_style->paint_layout(
$window,
$state,
1,
$cell_area,
$widget,
"cellrenderertext",
$cell_area->x() + $x_offset + x_padding,
$cell_area->y() + $y_offset + y_padding,
$layout
);
}
sub START_EDITING {
my ( $cell, $event, $view, $path, $background_area, $cell_area, $flags ) =
@_;
my $spin_button =
Gtk2::SpinButton->new_with_range( $cell->get( qw(min max step) ) );
$spin_button->set_value( $cell->get( "value" ) );
$spin_button->set_digits( $cell->get( "digits" ) );
#set initial point for editing
$spin_button->set_value( $cur_val );
$spin_button->grab_focus();
$spin_button->signal_connect(
key_press_event => sub {
my ( $event_box, $event ) = @_;
if ( $event->keyval == $Gtk2::Gdk::Keysyms{ Return }
|| $event->keyval == $Gtk2::Gdk::Keysyms{ KP_Enter } )
{
$spin_button->update();
$cell->signal_emit( edited => $path, $spin_button->get_value() );
$spin_button->destroy();
return 1;
}
elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{ Up } ) {
$spin_button->spin( 'step-forward',
( $spin_button->get_increments() )[ 0 ] );
return 1;
}
elsif ( $event->keyval == $Gtk2::Gdk::Keysyms{ Down } ) {
$spin_button->spin( 'step-backward',
( $spin_button->get_increments() )[ 0 ] );
return 1;
}
return 0;
}
);
$spin_button->signal_connect(
'focus-out-event' => sub {
my ( $event_box, $event ) = @_;
$spin_button->update();
$cell->signal_emit( edited => $path, $spin_button->get_value() );
#set the init value for next edit
$cur_val = $spin_button->get_value();
return 0;
}
);
$spin_button->show_all();
return $spin_button;
}
1;
################################################################
package main;
my $window = Gtk2::Window->new( "toplevel" );
$window->set_title( "CellRendererSpinButtonZ demo" );
$window->signal_connect( delete_event => sub { Gtk2->main_quit(); } );
my $model = Gtk2::ListStore->new( qw(Glib::Double) );
my $view = Gtk2::TreeView->new( $model );
#setup init value
$model->set( $model->append(), 0 => 42.42 );
my $renderer = Gtk2::CellRendererSpinButtonZ->new();
$renderer->set(
mode => "editable",
min => 0,
max => 1000,
step => 1.0,
digits => 2
);
$renderer->signal_connect( edited => \&cell_edited );
my $column =
Gtk2::TreeViewColumn->new_with_attributes( "2 digit", $renderer, value => 0 );
$view->append_column( $column );
my $vbox = Gtk2::VBox->new( 0, 5 );
$vbox->pack_start( $view, 1, 1, 0 );
my $button = Gtk2::Button->new( "Show Values" );
$button->signal_connect( "clicked" => sub { &show_values( @_ ); } );
$vbox->pack_start( $button, 0, 0, 0 );
$window->add( $vbox );
$window->show_all();
Gtk2->main();
####################################################################
sub cell_edited {
my ( $cell, $path, $new_value ) = @_;
$model->set( $model->get_iter( Gtk2::TreePath->new_from_string( $path ) ),
0 => $new_value );
}
####################################################################
sub show_values {
my $treeselection = $view->get_selection;
my $iter = $treeselection->get_selected;
print $model->get( $iter, 0 ), "\n";
}
__END__
--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]