1package Gtk2::Ex::FormFactory::Image; 2 3use strict; 4 5use base qw( Gtk2::Ex::FormFactory::Widget ); 6 7sub get_type { "image" } 8 9sub get_with_frame { shift->{with_frame} } 10sub get_bgcolor { shift->{bgcolor} } 11sub get_scale_to_fit { shift->{scale_to_fit} } 12sub get_max_width { shift->{max_width} } 13sub get_max_height { shift->{max_height} } 14sub get_widget_width { shift->{widget_width} } 15sub get_widget_height { shift->{widget_height} } 16sub get_scale { shift->{scale} } 17sub get_scale_hook { shift->{scale_hook} } 18sub get_gtk_event_box { shift->{gtk_event_box} } 19 20sub set_with_frame { shift->{with_frame} = $_[1] } 21sub set_bgcolor { shift->{bgcolor} = $_[1] } 22sub set_scale_to_fit { shift->{scale_to_fit} = $_[1] } 23sub set_max_width { shift->{max_width} = $_[1] } 24sub set_max_height { shift->{max_height} = $_[1] } 25sub set_widget_width { shift->{widget_width} = $_[1] } 26sub set_widget_height { shift->{widget_height} = $_[1] } 27sub set_scale { shift->{scale} = $_[1] } 28sub set_scale_hook { shift->{scale_hook} = $_[1] } 29sub set_gtk_event_box { shift->{gtk_event_box} = $_[1] } 30 31sub get_gtk_signal_widget { 32 shift->get_gtk_event_box; 33} 34 35sub new { 36 my $class = shift; 37 my %par = @_; 38 my ($with_frame, $bgcolor, $scale_to_fit, $max_width) = 39 @par{'with_frame','bgcolor','scale_to_fit','max_width'}; 40 my ($max_height, $scale, $scale_hook) = 41 @par{'max_height','scale','scale_hook'}; 42 43 my $self = $class->SUPER::new(@_); 44 45 $scale ||= 1 unless $scale_to_fit || $scale_hook; 46 47 $self->set_with_frame($with_frame); 48 $self->set_bgcolor($bgcolor); 49 $self->set_scale_to_fit($scale_to_fit); 50 $self->set_max_width($max_width); 51 $self->set_max_height($max_height); 52 $self->set_scale($scale); 53 $self->set_scale_hook($scale_hook); 54 55 return $self; 56} 57 58sub object_to_widget { 59 my $self = shift; 60 61 my $filename = $self->get_object_value; 62 return $self->empty_widget unless $filename and -r $filename; 63 64 my $gtk_image = $self->get_gtk_widget; 65 my $gtk_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($filename); 66 67 my $scale_to_fit = $self->get_scale_to_fit; 68 my $max_width = $self->get_max_width; 69 my $max_height = $self->get_max_height; 70 my $scale = $self->get_scale; 71 my $scale_hook = $self->get_scale_hook; 72 73 if ( defined $scale ) { 74 my $image_width = $gtk_pixbuf->get_width; 75 my $image_height = $gtk_pixbuf->get_height; 76 77 if ( $scale == 1 ) { 78 $gtk_image->set_from_pixbuf ( $gtk_pixbuf ); 79 $gtk_image->set_size_request ($image_width, $image_height); 80 return 1; 81 } 82 83 my $new_width = int($image_width * $scale); 84 my $new_height = int($image_height * $scale); 85 return if $new_width <= 0 or $new_height <= 0; 86 87 my $scaled_pixbuf = $gtk_pixbuf->scale_simple ( 88 $new_width, $new_height, "GDK_INTERP_BILINEAR" 89 ); 90 91 $gtk_image->set_from_pixbuf ( $scaled_pixbuf ); 92 $gtk_image->set_size_request ($image_width, $image_height); 93 94 } elsif ( $scale_hook ) { 95 my $scale = &$scale_hook($self, $gtk_pixbuf); 96 97 my $image_width = $gtk_pixbuf->get_width; 98 my $image_height = $gtk_pixbuf->get_height; 99 100 my $new_width = int($image_width * $scale); 101 my $new_height = int($image_height * $scale); 102 return if $new_width <= 0 or $new_height <= 0; 103 104 my $scaled_pixbuf = $gtk_pixbuf->scale_simple ( 105 $new_width, $new_height, "GDK_INTERP_BILINEAR" 106 ); 107 108 $gtk_image->set_from_pixbuf ( $scaled_pixbuf ); 109 110 } elsif ( $scale_to_fit or $max_width or $max_height ) { 111 my $image_width = $gtk_pixbuf->get_width; 112 my $image_height = $gtk_pixbuf->get_height; 113 114 my $widget_width = $self->get_widget_width; 115 my $widget_height = $self->get_widget_height; 116 117 $widget_width = $max_width if defined $max_width and 118 $max_width < $widget_width; 119 $widget_height = $max_height if defined $max_height and 120 $max_height < $widget_height; 121 122 my $width_scale = $widget_width / $image_width; 123 my $height_scale = $widget_height / $image_height; 124 125 my $scale = $width_scale < $height_scale ? 126 $width_scale : $height_scale; 127 128 my $new_width = int($image_width * $scale); 129 my $new_height = int($image_height * $scale); 130 return if $new_width <= 0 or $new_height <= 0; 131 132 my $scaled_pixbuf = $gtk_pixbuf->scale_simple ( 133 $new_width, $new_height, "GDK_INTERP_BILINEAR" 134 ); 135 136 $gtk_image->set_from_pixbuf ( $scaled_pixbuf ); 137 138 } else { 139 $gtk_image->set_from_pixbuf ( $gtk_pixbuf ); 140 } 141 142 1; 143} 144 145sub empty_widget { 146 my $self = shift; 147 148 $self->get_gtk_widget->set_from_pixbuf(undef); 149 150 1; 151} 152 1531; 154 155__END__ 156 157=head1 NAME 158 159Gtk2::Ex::FormFactory::Image - An Image in a FormFactory framework 160 161=head1 SYNOPSIS 162 163 Gtk2::Ex::FormFactory::Image->new ( 164 bgcolor => Background color of the widget, 165 with_frame => Draw a frame around the image?, 166 scale_to_fit => Automatially scale the image in its container?, 167 max_width => Maximum width the image may scale to, 168 max_height => Maximum height the image may scale to, 169 scale => Display the image with this constant scaling, 170 scale_hook => Callback which returns the actual scale, 171 ... 172 Gtk2::Ex::FormFactory::Widget attributes 173 ); 174 175=head1 DESCRIPTION 176 177This class implements an Image in a Gtk2::Ex::FormFactory framework. 178The image is always displayed with its natural aspect ratio, but 179there are various possibilities to control the scaling of the image. 180 181The value of the associated application object attribute is the 182filename of the displayed image. The file format must be supported 183by Gtk2::Gdk::PixBuf. 184 185=head1 OBJECT HIERARCHY 186 187 Gtk2::Ex::FormFactory::Intro 188 189 Gtk2::Ex::FormFactory::Widget 190 +--- Gtk2::Ex::FormFactory::Image 191 192 Gtk2::Ex::FormFactory::Layout 193 Gtk2::Ex::FormFactory::Rules 194 Gtk2::Ex::FormFactory::Context 195 Gtk2::Ex::FormFactory::Proxy 196 197=head1 ATTRIBUTES 198 199Attributes are handled through the common get_ATTR(), set_ATTR() 200style accessors, but they are mostly passed once to the object 201constructor and must not be altered after the associated FormFactory 202was built. 203 204=over 4 205 206=item B<bgcolor> = "RGB Hex Triple" [optional] 207 208This is the background color of the widget. If set all areas 209of the widget not filled with the image are painted with this 210color. 211 212=item B<with_frame> = BOOL [optional] 213 214If set to TRUE a frame is rendered around the image. 215 216=item B<scale_to_fit> = BOOL [optional] 217 218If set to TRUE the image will automatically scale proportionally 219into to the space the container of this widget allocated for the 220image widget. 221 222=item B<max_width> = INTEGER [optional] 223 224With this attribute you can define a maximm width the image may 225scale to. 226 227=item B<max_height> = INTEGER [optional] 228 229With this attribute you can define a maximm height the image may 230scale to. 231 232=item B<scale> = FLOAT [optional] 233 234If you set this attribute, no dynamic scaling applies, but the 235image will be constantly scaled with this value. This overrides 236all other attributes regarding dynamic scaling. 237 238=item B<scale_hook> = CODEREF(FormFactory::Image, PixBuf) [optional] 239 240This code reference is called if the image needs an update 241e.g. if the associated application object attribute changed or 242the parent was resized and B<scale_to_fit> was set. 243 244The Gtk2::Ex::FormFactory::Image instance and the Gtk2::Gdk::PixBuf 245of the image are passed to the function. 246 247If B<scale_to_fit> is set the widget's dimension are tracked 248automatically. The actual width and height are stored in the 249attributes B<widget_width> and B<widget_height> and thus can 250be accessed from the callback by calling B<get_widget_width> 251and B<get_widget_width>. 252 253=back 254 255For more attributes refer to L<Gtk2::Ex::FormFactory::Widget>. 256 257=head1 AUTHORS 258 259 J�rn Reder <joern at zyn dot de> 260 261=head1 COPYRIGHT AND LICENSE 262 263Copyright 2004-2006 by J�rn Reder. 264 265This library is free software; you can redistribute it and/or modify 266it under the terms of the GNU Library General Public License as 267published by the Free Software Foundation; either version 2.1 of the 268License, or (at your option) any later version. 269 270This library is distributed in the hope that it will be useful, but 271WITHOUT ANY WARRANTY; without even the implied warranty of 272MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 273Library General Public License for more details. 274 275You should have received a copy of the GNU Library General Public 276License along with this library; if not, write to the Free Software 277Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 278USA. 279 280=cut 281