Gtk3-Ex-DBI

 view release on metacpan or  search on metacpan

lib/Gtk3/Ex/DBI/Datasheet.pm  view on Meta::CPAN

#


use strict;
use Gtk3 -init;

package Gtk3::Ex::DBI::Datasheet::CellRendererDate;

use Glib::Object::Subclass
    "Gtk3::CellRenderer",
    signals     => {
                        edited => {
                                    flags       => [qw(run-last)],
                                    param_types => [qw(Glib::String Glib::Scalar)],
                                  },
                   },
    properties  => [
                    Glib::ParamSpec->boolean(
                        "editable",
                        "Editable",
                        "Can I change that?",
                        0,
                        [qw(readable writable)]
                    ),
                    Glib::ParamSpec->string(
                        "date",
                        "Date",
                        "What's the date again?",
                        "",
                        [qw(readable writable)]
                    ),
                    Glib::ParamSpec->string(
                        "format",
                        "Format",
                        "What day-month-year formatting?",
                        "yyyy-mm-dd",
                        [qw(readable writable)]
                    ),
                    Glib::ParamSpec->string(
                        "font",
                        "Font",
                        "What size fonts should be used?",
                        12,
                        [qw(readable writable)]
                    ),
                    Glib::ParamSpec->string(
                        "foreground",
                        "Foreground",
                        "What colour should foreground text be?",
                        "",
                        [qw(readable writable)]
                    )
    ];

use constant x_padding => 2;
use constant y_padding => 3;

use constant arrow_width => 15;
use constant arrow_height => 15;

sub hide_popup {
    
    my ( $cell ) = @_;
    
    Gtk3->grab_remove( $cell->{ _popup } );
    $cell->{ _popup }->hide();
    
}

sub get_today {
    
    my ( $cell ) = @_;
  
    my ( $day, $month, $year ) = (localtime())[3, 4, 5];
    
    $year += 1900;
    $month += 1;
  
    return ( $year, $month, $day );
    
}

sub get_date {
    
    my ( $cell ) = @_;
    
    my $text = $cell->get("date");
    
    my ( $year, $month, $day ) = $text
        ? split(/[\/-]/, $text)
        : $cell->get_today();
    
    return ( $year, $month, $day );
    
}

sub add_padding {
    
    my ( $cell, $year, $month, $day ) = @_;
    return ( $year, sprintf("%02d", $month), sprintf("%02d", $day) );
    
}

sub INIT_INSTANCE {
    
    my ( $cell ) = @_;
    
    my $popup = Gtk3::Window->new ('popup');
    my $vbox = Gtk3::VBox->new( 0, 0 );
    
    my $calendar = Gtk3::Calendar->new();
    
    #$calendar->modify_font( Gtk3::Pango::FontDescription->from_string( "Arial " . $cell->get( "font" ) ) );
    $calendar->modify_font( Pango::FontDescription::from_string( "Arial " . $cell->get( "font" ) ) );
    
    my $hbox = Gtk3::HBox->new( 0, 0 );
    
    my $today = Gtk3::Button->new('Today');
    my $none = Gtk3::Button->new('None');
    
    # $cell -> {_arrow} = Gtk3::Arrow->new( "down", "none" );
    
    # We can't just provide the callbacks now because they might need access to
    # cell-specific variables.  And we can't just connect the signals in
    # START_EDITING because we'd be connecting many signal handlers to the same
    # widgets.
    $today->signal_connect( clicked => sub {
        $cell->{ _today_clicked_callback }->( @_ )
            if ( exists( $cell->{ _today_clicked_callback } ) );
    } );
    
    $none->signal_connect( clicked => sub {
        $cell->{ _none_clicked_callback }->( @_ )
            if ( exists( $cell->{ _none_clicked_callback } ) );
    } );
    
    $calendar->signal_connect( day_selected_double_click => sub {
        $cell->{ _day_selected_double_click_callback }->( @_ )
            if ( exists( $cell->{ _day_selected_double_click_callback } ) );
    } );
    
    $calendar->signal_connect( month_changed => sub {
        $cell->{ _month_changed }->( @_ )
            if ( exists( $cell->{ _month_changed } ) );
    } );
    
    $hbox->pack_start( $today, 1, 1, 0 );
    $hbox->pack_start( $none, 1, 1, 0 );
    
    $vbox->pack_start( $calendar, 1, 1, 0 );
    $vbox->pack_start( $hbox, 0, 0, 0 );
    
    # Find out if the click happended outside of our window.  If so, hide it.
    # Largely copied from Planner (the former MrProject).
    
    # Implement via Gtk3::get_event_widget?
    $popup->signal_connect( button_press_event => sub {
      my ( $popup, $event ) = @_;
    
      if ( $event->button() == 1 ) {
        my ( $x, $y ) = ( $event->x_root(), $event->y_root() );
        my ( $xoffset, $yoffset ) = $popup->window()->get_root_origin();
    
        my $allocation = $popup->allocation();
    
        my $x1 = $xoffset + 2 * $allocation->x();
        my $y1 = $yoffset + 2 * $allocation->y();
        my $x2 = $x1 + $allocation->width();
        my $y2 = $y1 + $allocation->height();
    
        unless ( $x > $x1 && $x < $x2 && $y > $y1 && $y < $y2 ) {
          $cell->hide_popup();
          return 1;
        }
      }
    
      return 0;
    } );
    
    $popup->add( $vbox );
    
    $cell->{ _popup } = $popup;
    $cell->{ _calendar } = $calendar;
}

sub START_EDITING {
    
    my ( $cell, $event, $view, $path, $background_area, $cell_area, $flags ) = @_;
    
    my $popup = $cell -> { _popup };
    my $calendar = $cell->{ _calendar };
    
    # Specify the callbacks.  Will be called by the signal handlers set up in
    # INIT_INSTANCE.
    $cell->{ _today_clicked_callback } = sub {
        
        my ($button) = @_;
        my ($year, $month, $day) = $cell -> get_today();
        
        $cell->signal_emit( edited=>$path, join( "-", $cell->add_padding( $year, $month, $day ) ) );
        $cell->hide_popup();
        
    };
    
    $cell->{ _none_clicked_callback } = sub {
        
        my ( $button ) = @_;
      
        $cell->signal_emit( edited=>$path, "" );
        $cell->hide_popup();
        
    };
    
    $cell->{ _day_selected_double_click_callback } = sub {
        
        my ( $calendar ) = @_;
        my ( $year, $month, $day ) = $calendar->get_date();
        
        $cell->signal_emit( edited => $path, join( "-", $cell -> add_padding( $year, ++$month, $day ) ) );
        $cell->hide_popup();
        
    };
    
    $cell->{ _month_changed } = sub {
        
        my ( $calendar ) = @_;
        
        my ( $selected_year, $selected_month ) = $calendar->get_date();
        my ( $current_year, $current_month, $current_day ) = $cell->get_today();
        
        if ( $selected_year == $current_year && ++$selected_month == $current_month ) {
            $calendar->mark_day( $current_day );
        }
        else {
            $calendar->unmark_day( $current_day );
        }
        
    };
    
    my ( $year, $month, $day ) = $cell->get_date();
    
    $calendar->select_month( $month - 1, $year );
    $calendar->select_day( $day );
    
    # Necessary to get the correct allocation of the popup.
    $popup->move( -500, -500 );
    $popup->show_all();
    
    # Figure out where to put the popup - ie don't put it offscreen,
    # as it's not movable ( by the user )
    my $screen_height = $popup->get_screen->get_height;
    my $requisition = $popup->size_request();
    my $popup_width = $requisition->width;
    my $popup_height = $requisition->height;
    my ( $x_origin, $y_origin ) = $view->get_bin_window()->get_origin();
    my ( $popup_x, $popup_y );
    
    $popup_x = $x_origin + $cell_area->{x} + $cell_area->{width} - $popup_width;
    $popup_x = 0 if $popup_x < 0;
    
    $popup_y = $y_origin + $cell_area->{y} + $cell_area->{height};
    
    if ( $popup_y + $popup_height > $screen_height ) {
      $popup_y = $y_origin + $cell_area->{y} - $popup_height;
    }
    
    $popup->move( $popup_x, $popup_y );
    
    # Grab the focus and the pointer.
    #Gtk3->grab_add( $popup );
    $popup->grab_add;
    
    $popup->grab_focus();
    
#    Gtk3::Gdk::pointer_grab(
#        $popup,
#        1,
#        [ qw( button-press-mask button-release-mask pointer-motion-mask ) ],
#        undef,
#        undef,
#        0
#    );
    
    return;
    
}

sub get_date_string {
    
    my ( $cell ) = @_;
    
    return $cell->get('date');
    
}

sub calc_size {
    
    my ( $cell, $layout ) = @_;
    
    my ( $width, $height ) = $layout -> get_pixel_size();
    
    return (
                0,
                0,
                $width + x_padding * 2 + arrow_width,
                $height + y_padding * 2
           );
    
}

sub GET_SIZE {
    
    my ( $cell, $widget, $cell_area ) = @_;
    
    my $layout = $cell->get_layout( $widget );
    $layout->set_text( $cell->get_date_string() || '' );
    
    return $cell->calc_size( $layout );
    
}

sub get_layout {
    
    my ( $cell, $widget ) = @_;
    
    return $widget->create_pango_layout("");
    
}

sub RENDERS {
    
    my ( $cell, $cairo, $widget, $background_area, $cell_area, $flags ) = @_;
    
    my $state;
    
    if ( $flags & 'selected' ) {

lib/Gtk3/Ex/DBI/Datasheet.pm  view on Meta::CPAN

#        $cell->{ _arrow },
#        "",
#        "down",
#        1,
#        $cell_area->x + $cell_area->width - arrow_width,
#        $cell_area->y + $cell_area->height - arrow_height + 3, #
#        arrow_width - 3,
#        arrow_height
#    );

}

1;
#
########################################################################################
## CellRendererTime
########################################################################################
#
## Copyright (C) 2005 by Daniel Kasak ...
##  ... basically a slightly modified CellRendererDate ( see above )
## 
## This library is free software; you can redistribute it and/or modify it under
## the terms of the GNU Library General Public License as published by the Free
## Software Foundation; either version 2.1 of the License, or (at your option)
## any later version.
## 
## This library is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
## more details.
## 
## You should have received a copy of the GNU Library General Public License
## along with this library; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA  02111-1307  USA.
#
#use strict;
#use Gtk3 -init;
#
#package Gtk3::Ex::Datasheet::DBI::CellRendererTime;
#
#use Glib::Object::Subclass
#  "Gtk3::CellRenderer",
#  signals => {
#    edited => {
#      flags => [ qw( run-last ) ],
#      param_types => [ qw( Glib::String Glib::Scalar ) ],
#    },
#  },
#  properties => [
#    Glib::ParamSpec->boolean( "editable", "Editable", "Can I change that?", 0, [qw(readable writable)] ),
#    Glib::ParamSpec->string( "time", "Time", "What's the time again?", "", [qw(readable writable)] ),
#  ]
#;
#
#use constant x_padding => 2;
#use constant y_padding => 3;
#
#use constant arrow_width => 15;
#use constant arrow_height => 15;
#
#sub hide_popup {
#    
#    my $cell = shift;
#    
#    Gtk3->grab_remove( $cell->{ _popup } );
#    $cell->{ _popup }->hide();
#    
#}
#
#sub get_time {
#    
#    my $cell = shift;
#    
#    my $text = $cell->get( "time" );
#    my ( $h, $m, $s ) = split( /:/, $text );
#    
#    return ( $h, $m, $s );
#    
#}
#
#sub add_padding {
#    
#    my ( $cell, $h, $m, $s ) = @_;
#    
#    return ( sprintf( "%02d",$h ), sprintf( "%02d", $m ), sprintf( "%02d", $s ) );
#    
#}
#
#sub INIT_INSTANCE {
#    
#    my $cell = shift;
#    
#    my $popup = Gtk3::Window->new( 'popup' );
#    my $vbox = Gtk3::VBox->new( 0, 0 );
#    
#    my $h_spinbutton = Gtk3::SpinButton -> new_with_range( 0, 23, 1 );
#    my $m_spinbutton = Gtk3::SpinButton -> new_with_range( 0, 59, 1 );
#    my $s_spinbutton = Gtk3::SpinButton -> new_with_range( 0, 59, 1 );
#    my $colon_1 = Gtk3::Label->new( ":" );
#    my $colon_2 = Gtk3::Label->new( ":" );
#    
#    my $spin_hbox = Gtk3::HBox->new( 0, 0 );
#    my $buttons_hbox = Gtk3::HBox->new( 0, 0 );
#    
#    $cell->{_arrow} = Gtk3::Arrow->new( "down", "none" );
#    
#    $spin_hbox->pack_start( $h_spinbutton,    1, 1, 0 );
#    $spin_hbox->pack_start( $colon_1,         1, 1, 0 );
#    $spin_hbox->pack_start( $m_spinbutton,    1, 1, 0 );
#    $spin_hbox->pack_start( $colon_2,         1, 1, 0 );
#    $spin_hbox->pack_start( $s_spinbutton,    1, 1, 0 );
#    
#    my $ok = Gtk3::Button->new_from_stock( 'gtk-ok' );
#    
#    $buttons_hbox->pack_start( $ok, 1, 1, 0 );
#    
#    $vbox->pack_start( $spin_hbox, 0, 0, 0 );
#    $vbox->pack_start( $buttons_hbox, 0, 0, 0 );
#    
#    # We can't just provide the callbacks now because they might need access to
#    # cell-specific variables.  And we can't just connect the signals in
#    # START_EDITING because we'd be connecting many signal handlers to the same
#    # widgets.
#    
#    $ok->signal_connect( clicked => sub {
#        $cell->{ _ok_clicked_callback }->( @_ )
#            if ( exists( $cell->{ _ok_clicked_callback } ) );
#    } );
#    
#    # Find out if the click happended outside of our window.  If so, hide it.
#    # Largely copied from Planner (the former MrProject).
#    
#    # Implement via Gtk3::get_event_widget?
#    $popup -> signal_connect( button_press_event => sub {
#        my ( $popup, $event ) = @_;
#        if ( $event->button() == 1 ) {
#            my ( $x, $y ) = ( $event->x_root, $event->y_root );
#            my ( $xoffset, $yoffset ) = $popup->window->get_root_origin;
#            my $allocation = $popup->allocation;
#            my $x1 = $xoffset + 2 * $allocation->x;
#            my $y1 = $yoffset + 2 * $allocation->y;
#            my $x2 = $x1 + $allocation->width;
#            my $y2 = $y1 + $allocation->height;
#            unless ( $x > $x1 && $x < $x2 && $y > $y1 && $y < $y2 ) {
#                $cell->hide_popup;
#                return 1;
#            }
#        }
#        return 0;
#    } );
#    
#    $popup->add( $vbox );
#    
#    $cell->{ _popup } = $popup;
#    $cell->{ _h_spinbutton } = $h_spinbutton;
#    $cell->{ _m_spinbutton } = $m_spinbutton;
#    $cell->{ _s_spinbutton } = $s_spinbutton;
#    
#}
#
#sub START_EDITING {
#    
#    my ( $cell, $event, $view, $path, $background_area, $cell_area, $flags ) = @_;
#    
#    my $popup = $cell->{ _popup };
#    my $h_spinbutton = $cell->{ _h_spinbutton };
#    my $m_spinbutton = $cell->{ _m_spinbutton };
#    my $s_spinbutton = $cell->{ _s_spinbutton };
#    
#    my ( $h, $m, $s ) = $cell->get_time;
#    
#    $h_spinbutton->set_value( $h );
#    $m_spinbutton->set_value( $m );
#    $s_spinbutton->set_value( $s );
#    
#    $cell->{ _ok_clicked_callback } = sub {
#        
#        my ( $button ) = @_;
#        my $h = $h_spinbutton->get_text;
#        my $m = $m_spinbutton->get_text;
#        my $s = $s_spinbutton->get_text;
#        
#        $cell->signal_emit(
#            edited => $path,
#            join( ":", $cell -> add_padding( $h, $m, $s ) )
#        );
#        
#        $cell->hide_popup;
#        
#    };
#    
#    # Necessary to get the correct allocation of the popup.
#    $popup->move( -500, -500 );
#    $popup->show_all;
#    
#    # Figure out where to put the popup - ie don't put it offscreen,
#    # as it's not movable ( by the user )
#    my $screen_height = $popup->get_screen->get_height;
#    my $requisition = $popup->size_request;
#    my $popup_width = $requisition->width;
#    my $popup_height = $requisition->height;
#    my ( $x_origin, $y_origin ) =  $view->get_bin_window->get_origin;
#    my ( $popup_x, $popup_y );
#    
#    $popup_x = $x_origin + $cell_area->{x} + $cell_area->{width} - $popup_width;
#    $popup_x = 0 if $popup_x < 0;
#    
#    $popup_y = $y_origin + $cell_area->{y} + $cell_area->{height};
#    
#    if ( $popup_y + $popup_height > $screen_height ) {
#        $popup_y = $y_origin + $cell_area->{y} - $popup_height;
#    }
#    
#    $popup -> move( $popup_x, $popup_y );
#    
#    # Grab the focus and the pointer.
#    Gtk3->grab_add( $popup );
#    $popup->grab_focus;
#    
#    Gtk3::Gdk->pointer_grab(
#        $popup->window,
#        1,
#        [ qw( button-press-mask button-release-mask pointer-motion-mask ) ],
#        undef,
#        undef,
#        0
#    );
#    
#    return;
#    
#}
#
#sub get_time_string {
#    
#    my $cell = shift;
#    return $cell->get( 'time' );
#    
#}
#
#sub calc_size {
#    
#    my ( $cell, $layout ) = @_;
#    my ( $width, $height ) = $layout->get_pixel_size;
#    
#    return (
#        0,
#        0,
#        $width + x_padding * 2 + arrow_width,
#        $height + y_padding * 2
#    );
#    
#}
#
#sub GET_SIZE {
#    
#    my ( $cell, $widget, $cell_area ) = @_;
#    
#    my $layout = $cell->get_layout( $widget );
#    $layout->set_text( $cell->get_time_string || '' );
#    
#    return $cell->calc_size( $layout );
#    
#}
#
#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'



( run in 2.353 seconds using v1.01-cache-2.11-cpan-364913b4093 )