Subversion Repositories Filer-Free

Rev

Rev 24 | Blame | Compare with Previous | Last modification | View Log | RSS feed

// This file is part of the free Filer module for RISC OS.
// Copyright © 2007 Graham Shaw.
// Redistribution and modification are permitted under the terms of the
// GNU General Public License (version 2 or any later version).

#include <string.h>
#include <stdio.h>

#include "oslib/os.h"
#include "oslib/wimpspriteop.h"

#include "filer_sprite.h"

filer_sprite::filer_sprite(const osgbpb_info& info,sprite_size display_size):
        _xsize(0),
        _ysize(0),
        _half_size(false)
{
        // If a small icon was requested then attempt to find one.
        if ((display_size==sprite_small)&&
                find(info,0,sprite_small,display_size)) return;

        // Attempt to find a large icon (whether or not that was
        // the size requested).
        if (find(info,0,sprite_large,display_size)) return;

        // If a small icon was requested then attempt to find a
        // generic small icon.
        if ((display_size==sprite_small)&&
                find(info,1,sprite_small,display_size)) return;

        // Attempt to find a generic large icon (whether or not that
        // was the size requested).
        if (find(info,1,sprite_large,display_size)) return;
}

bool filer_sprite::find(const osgbpb_info& info,int priority,
        sprite_size original_size,sprite_size display_size)
{
        if ((info.obj_type&fileswitch_IS_DIR)&&(info.name[0]=='!'))
        {
                // If the object is a directory or an image file, and its name
                // begins with a bang, then show it as an application.
                if (priority==0)
                {
                        // If a sprite for that application is available then
                        // show that sprite.
                        if (original_size==sprite_small)
                        {
                                sprintf(_name,"sm%.10s",info.name);
                        }
                        else
                        {
                                sprintf(_name,"%.12s",info.name);
                        }
                }
                else
                {
                        // If there is no sprite for that application then show
                        // the generic sprite for an application.
                        if (original_size==sprite_small)
                        {
                                strcpy(_name,"small_app");
                        }
                        else
                        {
                                strcpy(_name,"application");
                        }
                }
        }
        else if ((info.obj_type&fileswitch_IS_DIR)&&
                !(info.obj_type&fileswitch_IS_FILE))
        {
                // Otherwise, if the object is a directory (not an image file)
                // then show it as a directory.
                if (original_size==sprite_small)
                {
                        strcpy(_name,"small_dir");
                }
                else
                {
                        strcpy(_name,"directory");
                }
        }
        else
        {
                // Otherwise, show the object as a file.
                if (((info.load_addr&0xfff00000)==0xfff00000)&&(priority==0))
                {
                        // If the file has a filetype, and if a sprite for that
                        // filetype is available, then show that sprite.
                        int filetype=(info.load_addr>>8)&0xfff;
                        if (original_size==sprite_small)
                        {
                                sprintf(_name,"small_%3x",filetype);
                        }
                        else
                        {
                                sprintf(_name,"file_%3x",filetype);
                        }
                }
                else
                {
                        // If the file is untyped, or if there is no sprite for that
                        // filetype, then show the generic sprite for a file.
                        if (original_size==sprite_small)
                        {
                                strcpy(_name,"small_xxx");
                        }
                        else
                        {
                                strcpy(_name,"file_xxx");
                        }
                }
        }

        // Attempt to read the dimensions of the chosen sprite.
        int xpixels=0;
        int ypixels=0;
        os_error* err=xwimpspriteop_read_sprite_info(_name,&xpixels,&ypixels,0,0);

        if (!err)
        {
                // The sprite should be plotted at half size if a small sprite
                // was requested but a large sprite was chosen.
                _half_size=
                        (original_size==sprite_large)&&(display_size==sprite_small);

                // If plotting at half size then halve the reported dimensions
                // (rounding up).
                if (_half_size)
                {
                        xpixels=(xpixels+1)/2;
                        ypixels=(ypixels+1)/2;
                }

                // Convert from pixels to OS units.
                int xeig=0;
                int yeig=0;
                xos_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_XEIG_FACTOR,&xeig,0);
                xos_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_YEIG_FACTOR,&yeig,0);
                _xsize=xpixels<<xeig;
                _ysize=ypixels<<yeig;
        }

        return err==0;
}