#!/usr/bin/perl use strict; use lib qw(/usr/lib/libDrakX); use standalone; use common; use ugtk2 qw(:create :dialogs :helpers :wrappers); use interactive; use bootsplash; use Xconfig::resolution_and_depth; my $in = 'interactive'->vnew('su'); my $window = ugtk2->new('DrakSplash'); $window->{rwindow}->signal_connect(delete_event => \&close_window); my ($image_area, $image_pixbuf); create_image_area(); #- verification of package image magik unless ($in->do_pkgs->ensure_is_installed('ImageMagick', '/usr/bin/convert')) { $in->ask_okcancel(N("Error"), N("package 'ImageMagick' is required to be able to complete configuration.\nClick \"Ok\" to install 'ImageMagick' or \"Cancel\" to quit")) && $in->do_pkgs->install('ImageMagick') or close_window(); } my @resolutions = uniq(map { "$_->{X}x$_->{Y}" } Xconfig::resolution_and_depth::bios_vga_modes()); my %scale_settings = ( tx => [ 1/10, N("x coordinate of text box\nin number of characters") ], ty => [ 1/10, N("y coordinate of text box\nin number of characters") ], tw => [ 8/10, N("text width") ], th => [ 8/10, N("text box height") ], px => [ 2/10, N("the progress bar x coordinate\nof its upper left corner") ], py => [ 7/10, N("the progress bar y coordinate\nof its upper left corner") ], pw => [ 6/10, N("the width of the progress bar") ], ph => [ 1/10, N("the height of the progress bar") ], ); my (%theme, %adj); set_theme('new_theme'); set_resolution(@resolutions); gtkadd($window->{window}, gtkadd(Gtk2::HBox->new(1, 5), gtkadd(Gtk2::VBox->new(0, 5), gtkadd(Gtk2::Frame->new(N("first step creation")), create_packtable({ col_spacings => 10, row_spacings => 5 }, [ Gtk2::Label->new(N("Theme name")), gtksignal_connect(Gtk2::ComboBoxEntry->new_with_strings([ bootsplash::themes_list() ], $theme{name}), changed => sub { set_theme($_[0]->entry->get_text) }) ], [ Gtk2::Label->new(N("final resolution")), gtksignal_connect(Gtk2::ComboBox->new_with_strings(\@resolutions, $theme{res}), changed => sub { set_resolution($_[0]->entry->get_text) }) ], [ Gtk2::Label->new(N("choose image file")), gtksignal_connect(Gtk2::Button->new(N("Browse")), clicked => \&choose_image) ])), gtkadd(Gtk2::Frame->new(N("Configure bootsplash picture")), create_packtable({ col_spacings => 10, row_spacings => 5 }, (map { [ Gtk2::Label->new($scale_settings{$_}[1]), new_scale($_) ] } sort keys %scale_settings), [ Gtk2::Label->new(N("the color of the progress bar")), gtksignal_connect(Gtk2::Button->new(N("Choose color")), clicked => \&choose_color) ], [ gtksignal_connect(Gtk2::CheckButton->new(N("Display logo on Console")), toggled => sub { $theme{conf}{logo} = bool2yesno($_[0]->get_active); }) ])), gtksignal_connect(Gtk2::Button->new(N("Save theme")), clicked => \&save_theme), gtksignal_connect(Gtk2::Button->new(N("Quit")), clicked => \&close_window)), $image_area)); my %scale_links = (tx => 'tw', ty => 'th', px => 'pw', py => 'ph'); while (my ($n1, $n2) = each(%scale_links)) { $adj{$n1}->signal_connect(value_changed => sub { check_scale_value($n1, $n2); apply_scale($n1) }); $adj{$n2}->signal_connect(value_changed => sub { check_scale_value($n2, $n1); apply_scale($n2) }); } update_scale_values(); $window->{rwindow}->set_border_width(5); $window->{rwindow}->set_position('center'); $window->{rwindow}->show_all; $window->main; # Should never get here ugtk2->exit(0); sub close_window() { ugtk2->exit(0); } sub read_theme_config { my $conf = bootsplash::theme_get_config_for_resolution($theme{name}, $theme{res}); -f $conf and $theme{conf} = bootsplash::theme_read_config_for_resolution($theme{name}, $theme{res}); -f $theme{conf}{silentjpeg} && load_image($theme{conf}{silentjpeg}) and $theme{image} = $theme{conf}{silentjpeg}; $theme{conf}{pc} ||= '0x21459d'; update_scale_values(); } sub set_theme { my ($name) = @_; $theme{name} = $name; read_theme_config(); } sub set_resolution { my ($res) = @_; $theme{res} = $res; ($theme{res_w}, $theme{res_h}) = $theme{res} =~ /([^x]+)x([^x]+)/; read_theme_config(); foreach (keys %scale_settings) { $theme{conf}{$_} eq '' and $theme{conf}{$_} = get_scale_max($_) * $scale_settings{$_}[0]; } update_scale_values(); $image_area->set_size_request($theme{res_w}, $theme{res_w}); } sub save_theme() { my $_w = $in->wait_message('', N("saving Bootsplash theme...")); bootsplash::theme_set_image_for_resolution($theme{name}, $theme{res}, $theme{image}); bootsplash::theme_write_config_for_resolution($theme{name}, $theme{res}, $theme{conf}); } sub load_image { my ($img) = @_; $image_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($img); $image_pixbuf = $image_pixbuf->scale_simple($theme{res_w}, $theme{res_h}, 'hyper'); $image_area->queue_draw; 1; } sub choose_image() { my $file_dialog = Gtk2::FileChooserDialog->new(N("choose image"), $window->{real_window}, 'open', N("Cancel") => 'cancel', N("Ok") => 'ok'); $file_dialog->set_filename($theme{image} || '~/'); $file_dialog->show; while (my $answer = $file_dialog->run) { if (member($answer, qw(cancel delete-event))) { $file_dialog->destroy; return; } elsif ($answer eq 'ok' && load_image(my $img = $file_dialog->get_filename)) { $theme{image} = $img; $file_dialog->destroy; return; } } } sub choose_color() { my $color = gtkshow(Gtk2::ColorSelectionDialog->new(N("ProgressBar color selection"))); my @rgb = $theme{boot_conf}{pc} =~ m/0x(.{2})(.{2})(.{2})/ && map { hex($_)/255 } ($1, $2, $3); $color->colorsel->set_current_color(gtkcolor(@rgb)); $color->cancel_button->signal_connect(clicked => sub { $color->destroy }); $color->ok_button->signal_connect(clicked => sub { my $colour = $color->colorsel->get_current_color; $theme{boot_conf}{pc} = "0x" . join('', map { print "$_\n"; sprintf("%x", $_*255) } $colour->red, $colour->green, $colour->blue); $color->destroy; }); } #- Adjustement widgets sub new_scale { my ($name) = @_; my $w = Gtk2::HScale->new($adj{$name} = Gtk2::Adjustment->new(0, 0, 0, 1, 10, 0)); $w->set_digits(0); $w; } sub get_scale_max { my ($name) = @_; $theme{$name =~ /[xw]$/ ? "res_w" : "res_h"}; } sub apply_scale { my ($name) = @_; $theme{conf}{$name} = $adj{$name}->get_value; $image_area->queue_draw; } sub check_scale_value { my ($changed, $linked) = @_; my $max = get_scale_max($changed) - $adj{$changed}->get_value; $adj{$linked}->get_value > $max and $adj{$linked}->set_value($max); } sub update_scale_values { foreach (keys %adj) { $adj{$_}->upper(get_scale_max($_)); $adj{$_}->set_value($theme{conf}{$_}); } } #- FIXME duplicate with draksplash2 sub create_image_area() { $image_area = Gtk2::DrawingArea->new; $image_area->can_focus(1); $image_area->add_events('button-press-mask'); $image_area->signal_connect(expose_event => \&image_expose); my $keys = { $Gtk2::Gdk::Keysyms{q} => \&close_window, $Gtk2::Gdk::Keysyms{Escape} => \&close_window, }; $image_area->signal_connect(key_press_event => sub { my (undef, $event) = @_; if (my $f = $keys->{$event->keyval}) { $f->(member('control-mask', @{$event->state})); } 1; }); $image_area->grab_focus; $image_area->show; $image_area; } sub image_expose { my ($widget) = @_; my $window = $widget->window; $window->draw_pixbuf($widget->style->white_gc, $image_pixbuf, 0, 0, 0, 0, -1, -1, 'none', 0, 0) if $image_pixbuf; $window->draw_rectangle($widget->style->black_gc, 0, @{$theme{conf}}{'tx', 'ty', 'tw', 'th'}); my ($tx1, $ty1) = @{$theme{conf}}{'tx', 'ty'}; my ($tx2, $ty2) = ($tx1 + $theme{conf}{tw}, $ty1 + $theme{conf}{th}); $window->draw_line($widget->style->white_gc, $tx1, $ty1, $tx2, $ty2); $window->draw_line($widget->style->white_gc, $tx1, $ty2, $tx2, $ty1); 0; }