#!/usr/bin/perl -w

###############################################################################
# Iconbox is a comfortable one-mouse-click application launcher.	      #
# Copyright (C) 2005 Chris Mueller (iconbox@gmx.de)			      #
#									      #
# This program is free software; you can redistribute it and/or		      #
# modify it under the terms of the GNU General Public License		      #
# as published by the Free Software Foundation; either version 2	      #
# of the License, or (at your option) any later version.		      #
#									      #
# This program 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 General Public License for more details.				      #
#									      #
# You should have received a copy of the GNU General Public License	      #
# along with this program; if not, write to the Free Software                 #
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. #
###############################################################################

use strict;
use Gtk2 '-init';

# initialize
my ($wx,$wy,$nc1,$nc2,$nc3,$ac1,$ac2,$ac3,$bg1,$bg2,$bg3,$br1,$br2,$br3,$nf,
    $af,$loc,$a,$s,$t,$bx,$by,$b) = &init(@ARGV);


my (@event, @image, @vbox, @label);
my $m;

# create new objects
my $window = Gtk2::Window->new('toplevel');
my $display = Gtk2::Gdk::Display -> open($ENV{DISPLAY});
my $box = Gtk2::HBox->new(0,0);
my $tooltips = Gtk2::Tooltips->new unless $t;
my $nfd = Gtk2::Pango::FontDescription->from_string($nf);
my $afd = Gtk2::Pango::FontDescription->from_string($af);

# generate object...
open F, "<$ENV{HOME}/.iconbox/progs"; my @pd = <F>; close F;
foreach my $str(@pd){
    chomp $str;
    my ($name,$command,$icon) = split "\t", $str;
    if($t){
	$vbox[$#vbox+1] = Gtk2::VBox->new(0,0);
	$label[$#label+1] = Gtk2::Label->new($name);
	$label[$#label]->modify_font($nfd);
	$label[$#label]->modify_fg ('normal', 
    		Gtk2::Gdk::Color->new($nc1, $nc2, $nc3));
    }
	$event[$#event+1] = Gtk2::EventBox->new;
	$event[$#event]->signal_connect(button_press_event => sub{
    	   	$window->hide; system("$command &"); &wait4cursor;
   	});
    if($t){
    	$event[$#event]->set_events(['pointer-motion-mask','leave-notify-mask']);
    	$event[$#event]->signal_connect('motion_notify_event' => sub{
            $label[$_[2]]->modify_font($afd);
            $label[$_[2]]->modify_fg ('normal', 
	    		Gtk2::Gdk::Color->new($ac1, $ac2, $ac3));
    	    },$#label);
    	$event[$#event]->signal_connect('leave_notify_event' => sub{
            $label[$_[2]]->modify_font($nfd);
            $label[$_[2]]->modify_fg ('normal', 
	    		Gtk2::Gdk::Color->new($nc1, $nc2, $nc3));
    	},$#label);
    }
    $image[$#image+1] = Gtk2::Image->new_from_file($icon);
    if($t){
    	$vbox[$#vbox]->pack_start($image[$#image],1,1,0);
    	$vbox[$#vbox]->pack_start($label[$#label],0,0,0);
    	$event[$#event]->add($vbox[$#vbox]);
    	$vbox[$#vbox]->show;
    	$label[$#label]->show;
    }else{
        $tooltips->set_tip($event[$#event],$name,undef);
    	$event[$#event]->add($image[$#image])
	}
    $event[$#event]->modify_bg('normal',Gtk2::Gdk::Color->new($bg1, $bg2, $bg3));
    $event[$#event]->show;
    $image[$#image]->show;
    $box->pack_start($event[$#event],1,1,0);
}

# set the properties
#$align->set_padding(0,-1,0,-1);
$window->set_decorated(0);
$window->set_title("choose an application...");
$window->set_border_width($b);
$window->modify_bg('normal',Gtk2::Gdk::Color->new($br1, $br2, $br3));
$window->set_skip_taskbar_hint(1);
$window->set_skip_pager_hint(1);
$window->stick;
$window->move($wx,$wy);

$window->signal_connect(focus_out_event => sub{$window->hide;&wait4cursor});

# adding the box...
$window->add($box);

# show'em all!
$box->show;

&wait4cursor;

Gtk2->main;

# the end
0;

# sub routines...

sub init{

die "Config files are incorrect! Please start 'iconboxconf'.\n" 
unless(-e "$ENV{HOME}/.iconbox");

open F, "<$ENV{HOME}/.iconbox/params"; my @pd = <F>; close F;

($m,$wx,$m,$wy) = split " ", $pd[0];
($m,$nc1,$nc2,$nc3) = split " ", $pd[1];
($m,$ac1,$ac2,$ac3) = split " ", $pd[2];
($m,$bg1,$bg2,$bg3) = split " ", $pd[10];
($m,$br1,$br2,$br3) = split " ", $pd[11];
my @nf = split " ", $pd[3]; $nf = "@nf[1..$#nf]";
my @af = split " ", $pd[4]; $af = "@af[1..$#af]";
my @loc = split " ", $pd[5]; $loc = "@loc[1..$#loc]";
($m,$a) = split " ", $pd[7];
($m,$b) = split " ", $pd[12];
($m,$s) = split " ", $pd[8];
($m,$t) = split " ", $pd[9];
my ($m,$res) = split " ", $pd[6]; 

for my $n (0..$#_){
if($_[0] eq '-h' || $_[$n] eq '--short' || $_[$n] eq '--help'){ 
print 'Usage: iconbox [OPTIONS]
iconbox is a desktop tool, that provides fast starting of applications by one
mouse click. Command line options will override configurations defined in
config file.
   -v				version
   -p <int>x<int>		x and y coordinates of iconbox window
   -nfc <int>:<int>:<int>	label font color an icon
   -afc <int>:<int>:<int>	label font color of an active icon
   -bg <int>:<int>:<int>	color of the window background
   -bc <int>:<int>:<int>	border color of the window
   -bw <int>			border width
   -nf <string>			label font name of an icon
   -af <string>			label font name of an active icon
   -l <int>			position of the cursor grabbing
   -r <int>x<int>		your screen resolution
   -a <int>			size of the cursos grabbing area
   -s <int>			sensitivity (speed) of grabbing in miliseconds
   -t [0|1]			show/hide the icon labels

For further information read the man page please!
'; exit 0}
elsif($_[0] eq '-v'){
print 'Iconbox version 0.2
Copyright (C) 2005 by Chris Mueller, Saarbruecken.
This software is licensed under the terms of the GNU GPL.
'; exit 0;
}
elsif($_[$n] eq '-p'){($wx,$wy) = split "x", $_[$n+1]}
elsif($_[$n] eq '-r'){$res = $_[$n+1]}
elsif($_[$n] eq '-nfc'){($nc1,$nc2,$nc3) = split ":", $_[$n+1];
			($nc1,$nc2,$nc3) = ($nc1*257,$nc2*257,$nc3*257)}
elsif($_[$n] eq '-afc'){($ac1,$ac2,$ac3) = split ":", $_[$n+1];
			($ac1,$ac2,$ac3) = ($ac1*257,$ac2*257,$ac3*257)}
elsif($_[$n] eq '-bg'){($bg1,$bg2,$bg3) = split ":", $_[$n+1];
			($bg1,$bg2,$bg3) = ($bg1*257,$bg2*257,$bg3*257)}
elsif($_[$n] eq '-bc'){($br1,$br2,$br3) = split ":", $_[$n+1];
			($br1,$br2,$br3) = ($br1*257,$br2*257,$br3*257)}
elsif($_[$n] eq '-nf'){$nf = $_[$n+1]}
elsif($_[$n] eq '-af'){$af = $_[$n+1]}
elsif($_[$n] eq '-a'){$a = $_[$n+1]}
elsif($_[$n] eq '-t'){$t = $_[$n+1]}
elsif($_[$n] eq '-bw'){$b = $_[$n+1]}
elsif($_[$n] eq '-l'){
	$_ = $_[$n+1];
	if($_ == 1){$loc='top: left corner'}
	elsif($_ == 2){$loc='top: right corner'}
	elsif($_ == 3){$loc='bottom: right corner'}
	else{$loc='bottom: left cornen'}
}
elsif($_[$n] eq '-s'){$s = $_[$n+1]}
}

($bx,$by) = split "x", $res;
if($loc eq 'top: left corner'){$bx=$by=$a}
elsif($loc eq 'top: right corner'){$bx=$bx-$a;$by=$a}
elsif($loc eq 'bottom: right corner'){$bx=$bx-$a;$by=$by-$a}
else{$bx=$a;$by=$by-$a}

if($wx eq '' || $wy eq '' || $nc1 eq '' || $nc2 eq '' || $nc3 eq '' ||
   $ac1 eq '' || $ac2 eq '' || $ac3 eq '' || $bg1 eq '' || $bg2 eq '' || 
   $bg3 eq '' || $br1 eq '' || $br2 eq '' || $br3 eq '' ||  
   $nf eq '' || $af eq '' || $loc eq '' || $a eq '' || 
   $s eq '' || $t eq '' || $bx eq '' || $by eq '' || $b eq ''){
   die "Config files are incorrect! Please start 'iconboxconf'.\n" }

   return ($wx,$wy,$nc1,$nc2,$nc3,$ac1,$ac2,$ac3,$bg1,$bg2,$bg3,$br1,$br2,$br3,
   $nf,$af,$loc,$a,$s,$t,$bx,$by,$b);
}

sub wait4cursor{

Glib::Timeout->add($s,sub{ ($m,my $x,my $y,$m) = $display->get_pointer;
    if($loc eq 'top: left corner'){
        if($x<=$bx && $y<=$by){$window->show; return 0;}else{return 1}
    }elsif($loc eq 'top: right corner'){
        if($x>=$bx && $y<=$by){$window->show; return 0;}else{return 1}
    }elsif($loc eq 'bottom: right corner'){
        if($x>=$bx && $y>=$by){$window->show; return 0;}else{return 1}
    }else{
    if($x<=$bx && $y>=$by){$window->show; return 0;}else{return 1}}
});
}

