#!/usr/bin/perl use strict; use XML::Simple; use URI::file; use Gtk2; { # GCS file to load my $uriIn = URI->new($ARGV[0]); my $fileIn = $uriIn->file; my $maxIcons = 16; my $itemsPerRow = 4; my $skin; my $skinFile; # Find user selected skin # Fix - hardcoded path open (CONF, $ENV{'HOME'}.'/.config/gcstar/GCstar.conf'); my $line; foreach $line () { if ($line =~ /listImgSkin=(.*)/) { $skinFile= $1; } } if (!$skinFile) { $skinFile = "Wood"; } close (CONF); # Fix - hardcoded path $skin = "/usr/local/share/gcstar/list_bg/".$skinFile."/list_bg.png"; # Load the collection file temporarily, to grab the model type my $collectionXML= XMLin($fileIn, forcearray => 1); # Load the collection model to determine id and cover fields # Fix - hardcoded path my $collectionModel = XMLin("/usr/local/lib/gcstar/GCModels/".$collectionXML->{type}.".gcm"); my $idField = $collectionModel->{options}->{fields}->{id}; my $picField = $collectionModel->{options}->{fields}->{cover}; # Now that we now the id field, reopen collection xml using proper id $collectionXML= XMLin($fileIn, forcearray => 1, keyattr=>$idField); my $collectionItems=$collectionXML->{item}; my $count; my $favCount; my $nonFavCount; my @images; my @favourites; my @nonFavourites; # Hacky part, but for some reason items won't load as an array, so just jump through collection grabbing the first few covers # (Prefer favourites - so I don't see romantic comedies as the thumbnail for my films!!) foreach my $collectionItem (values %$collectionItems) { if ($collectionItem->{$picField}) { if ($collectionItem->{favourite}) { if ($favCount < $maxIcons) { @favourites[$favCount] = $collectionItem->{$picField}; $favCount++; } } else { @nonFavourites[$nonFavCount] = $collectionItem->{$picField}; $nonFavCount++; } } } # Load a few pixbufs my $gcstarIconPixBuf; my $backgroundPixBuf; # Fix - hardcoded path $gcstarIconPixBuf = Gtk2::Gdk::Pixbuf->new_from_file("/usr/local/share/gcstar/icons/gcstar_24x24.png"); $backgroundPixBuf = Gtk2::Gdk::Pixbuf->new_from_file($skin); my $tempPixbuf; my @pixBuf; my $bgWidth = $backgroundPixBuf->get_width; my $bgHeight = $backgroundPixBuf->get_height; my $maxHeight; # Load covers to pixbufs, scale them to fit in background for (my $imgCount = 0; $imgCount < $maxIcons; $imgCount++) { if (@favourites[$imgCount]) { @pixBuf[$imgCount] = Gtk2::Gdk::Pixbuf->new_from_file(@favourites[$imgCount]); # Scale to 80% of background size (seems like a good size) @pixBuf[$imgCount] = scaleMaxPixbuf(@pixBuf[$imgCount], $bgWidth*.80, $bgHeight*.80); if (@pixBuf[$imgCount]->get_height > $maxHeight) { $maxHeight = @pixBuf[$imgCount]->get_height; } } elsif (@nonFavourites[$imgCount - $favCount]) { @pixBuf[$imgCount] = Gtk2::Gdk::Pixbuf->new_from_file(@nonFavourites[$imgCount - $favCount]); # Scale to 80% of background size (seems like a good size) @pixBuf[$imgCount] = scaleMaxPixbuf(@pixBuf[$imgCount], $bgWidth*.80, $bgHeight*.80); if (@pixBuf[$imgCount]->get_height > $maxHeight) { $maxHeight = @pixBuf[$imgCount]->get_height; } } else { # If we run out of items in the collection with covers, just make empty pixbufs for simplicity @pixBuf[$imgCount] = Gtk2::Gdk::Pixbuf->new('rgb',1,8,$bgWidth * .80,$bgHeight * .80); @pixBuf[$imgCount]->fill(0x00000000); } } my $factor; my $rows; my $destHeight; # Change the positioning slightly if it's a reflection type skin (items sit higher on shelf) # Work out number of rows of pictures, and desired height of rows (not much logic to these numbers, # it's just what looks good) if ($skinFile =~ /Glass/) { $factor = 40; if ($maxHeight < 70) { $rows = 4; $destHeight = $bgHeight - 145; } elsif ($maxHeight < 130) { $rows = 3; $destHeight = $bgHeight - 100; } else { $rows = 2; $destHeight = $bgHeight; } } else { $factor = 10; if ($maxHeight < 70) { $rows = 4; $destHeight = $bgHeight - 60; } elsif ($maxHeight < 130) { $rows = 3; $destHeight = $bgHeight - 15; } else { $rows = 3; $destHeight = $bgHeight; } } # Put covers on background for (my $imgCount = 0; $imgCount < $itemsPerRow * $rows; $imgCount++) { $tempPixbuf = $backgroundPixBuf->copy; @pixBuf[$imgCount]->composite($tempPixbuf, ( $bgWidth - @pixBuf[$imgCount]->get_width ) / 2, $bgHeight - @pixBuf[$imgCount]->get_height - $factor, @pixBuf[$imgCount]->get_width, @pixBuf[$imgCount]->get_height, ( $bgWidth - @pixBuf[$imgCount]->get_width ) / 2, $bgHeight - @pixBuf[$imgCount]->get_height - $factor, 1, 1, 'nearest', 255); if ($rows > 2) { # If needed, crop image to avoid wasted space $tempPixbuf = $tempPixbuf->new_subpixbuf(0,$bgHeight-$destHeight,$bgWidth,$destHeight); } @pixBuf[$imgCount] = $tempPixbuf; } # Get pixbuf ready for final image $tempPixbuf = Gtk2::Gdk::Pixbuf->new('rgb',1,8,$bgWidth * $itemsPerRow,$destHeight * $rows); $tempPixbuf->fill(0x00000000); # Put each cover in place for (my $imgCount = 0; $imgCount < $itemsPerRow * $rows; $imgCount++) { @pixBuf[$imgCount]->composite($tempPixbuf, @pixBuf[0]->get_width * ($imgCount % $itemsPerRow), @pixBuf[0]->get_height * int($imgCount / $itemsPerRow), @pixBuf[5]->get_width, @pixBuf[5]->get_height, @pixBuf[0]->get_width * ($imgCount % $itemsPerRow), @pixBuf[0]->get_height * int($imgCount / $itemsPerRow), 1, 1, 'nearest', 255); } # Scale to specified size, or else to max 128 pixels wide/high if ($ARGV[2]) { $tempPixbuf = scaleMaxPixbuf($tempPixbuf,$ARGV[2],$ARGV[2]); } else { $tempPixbuf = scaleMaxPixbuf($tempPixbuf,128,128); } # Place little gcstar icon in corner $gcstarIconPixBuf->composite($tempPixbuf, $tempPixbuf->get_width - $gcstarIconPixBuf->get_width - 4, $tempPixbuf->get_height - $gcstarIconPixBuf->get_height - 5, $gcstarIconPixBuf->get_width, $gcstarIconPixBuf->get_height, $tempPixbuf->get_width - $gcstarIconPixBuf->get_width - 4, $tempPixbuf->get_height - $gcstarIconPixBuf->get_height - 5, 1,1,'nearest',255); # Save pixbuf $tempPixbuf->save($ARGV[1],"png"); } sub scaleMaxPixbuf { my ($pixbuf, $maxWidth, $maxHeight) = @_; my ($width, $height) = ($pixbuf->get_width, $pixbuf->get_height); if (($height > $maxHeight) || ($width > $maxWidth)) { my ($newWidth, $newHeight); my $ratio = $height / $width; if (($width) * ($maxHeight / $height) < $maxWidth) { $newHeight = $maxHeight; $newWidth = $newHeight / $ratio; } else { $newWidth = $maxWidth; $newHeight = $newWidth * $ratio; } $pixbuf = $pixbuf->scale_simple($newWidth, $newHeight, 'bilinear'); } return $pixbuf; }