List Info

Thread: Gtk2::CellRendererSpinButton-Z




Gtk2::CellRendererSpinButton-Z
user name
2006-03-06 20:57:30
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:ouble)
],
   },
 },
 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-> = 0;
   $self->   = 2;
   $self->    = 0.0;
   $self->      = 0.0;
   $self->      = 100.0;
   $self->     = 5.0;
   $self->   = 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-> * ( $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->;
   sprintf $format, $cell->;
}

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
            || $event->keyval == $Gtk2::Gdk::Keysyms )
         {
            $spin_button->update();
            $cell->signal_emit( edited => $path,
$spin_button->get_value() );
            $spin_button->destroy();
            return 1;
         }
         elsif ( $event->keyval == $Gtk2::Gdk::Keysyms ) {
            $spin_button->spin( 'step-forward',
               ( $spin_button->get_increments() )[ 0 ] );
            return 1;
         }
         elsif ( $event->keyval == $Gtk2::Gdk::Keysyms ) {
            $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:ouble)
);
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
_______________________________________________
gtk-perl-list mailing list
gtk-perl-listgnome.org

http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Gtk2::CellRendererSpinButton-Z
user name
2006-03-07 03:32:57
On Mar 6, 2006, at 3:57 PM, zentara wrote:

> 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.


You don't need the global at all.  You pass the new value
through  
the  "new value" parameter of the edited signal.
 The cell renderer  
should not alter its own value --- that's for client code
to do, if  
desired, in the "edited" callback.  (Definitely
"if desired" --  
imagine a situation in which the SpinButton is used in a
TreeView  
using a custom TreeModel, whose data actually reflects state
 
elsewhere in the system.  In this situation, having the
CellRenderer  
set the value directly on the model may be quite bad.  This
is always  
left for the client code to perform.)

I simply removed from your new code all lines that refer to
$cur_val,  
and it all works as expected.  In fact, if you press Enter
in the  
spinbutton after editing, the 'edited' signal gets emitted
twice ---  
once explictly from key-press-event., and again from
focus-out-event  
as the cell editor is being destroyed.

The original code required you to press "Enter"
to "commit" the  
value, and allowed you to press "Esc" to cancel
changing it.  If you  
don't care about the distinction, then you don't even need
to handle  
"Enter" specially, and can just rely on the
focus-out-event.


> 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;
>      }
> }

After you remove the global, you have a SET_PROPERTY which
is merely  
a perl implementation of what the XS code already does.




--
And then mama would throw the live crawdads in the boilin'
water.   
And one day I decided I'd make my own crawdads.  So I threw
the  
crawdads in the pot, but without any water.  It was just
like makin'  
popcorn.
    -- Ear-bending cellmate, "Raising Arizona"


_______________________________________________
gtk-perl-list mailing list
gtk-perl-listgnome.org

http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Gtk2::CellRendererSpinButton-Z
user name
2006-03-07 22:06:06
On Mon, 6 Mar 2006 22:32:57 -0500
muppet <scottasofyet.org> wrote:

>
>On Mar 6, 2006, at 3:57 PM, zentara wrote:
>
>> 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.

>
>You don't need the global at all.  You pass the new
value through  
>the  "new value" parameter of the edited
signal.  The cell renderer  
>
>> 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;
>>      }
>> }
>
>After you remove the global, you have a SET_PROPERTY
which is merely  
>a perl implementation of what the XS code already does.

Yes, I am humbled.   I caused
all these problems for myself, by upgrading
to Perl 5.8.8 , while not getting the latest Glib and
Gtk-1.116 perl modules.
I should have read more closely the post by Daniel Kasak a
few days ago 
concerning this.

So all of the above module hacking....... is just BS caused
by me not noticing
the upgrade problems.

Sorry  I wasted your time, but I sure learned alot. 

zentara

-- 
I'm not really a human, but I play one on earth.
http://zentara.net/japh.
html
_______________________________________________
gtk-perl-list mailing list
gtk-perl-listgnome.org

http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Gtk2::CellRendererSpinButton-Z
user name
2006-03-08 01:15:13
On Mar 7, 2006, at 5:06 PM, zentara wrote:

> Sorry  I wasted your time, but I sure learned alot.


If something was learned, then the time was not wasted.

--
elysse (pregnant): are your hands cold?
me: uh, i suppose so.
elysse: will you put them on me?

_______________________________________________
gtk-perl-list mailing list
gtk-perl-listgnome.org

http://mail.gnome.org/mailman/listinfo/gtk-perl-list
[1-4]

about | contact  Other archives ( Real Estate discussion Medical topics )