ede/eiconman/DesktopIcon.cpp

322 lines
7.1 KiB
C++
Raw Normal View History

2007-05-22 18:53:17 +04:00
/*
* $Id$
*
* Eiconman, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include "DesktopIcon.h"
#include "eiconman.h"
#include <edelib/Debug.h>
#include <edelib/IconTheme.h>
#include <edelib/Nls.h>
#include <edelib/Item.h>
2007-05-23 16:43:50 +04:00
#include <edelib/Ask.h>
2007-05-22 18:53:17 +04:00
#include <fltk/SharedImage.h>
#include <fltk/Color.h>
#include <fltk/Divider.h>
#include <fltk/draw.h>
#include <fltk/events.h>
2007-05-23 16:43:50 +04:00
#include <fltk/damage.h>
2007-05-22 18:53:17 +04:00
#include <fltk/x11.h> // Pixmap
// fuck !
#define Window XWindow
#include <X11/extensions/shape.h>
#undef Window
// default icon size
#define ICONSIZE 48
// spaces around box in case of large/small icons
#define OFFSET_W 16
#define OFFSET_H 16
2007-05-23 16:43:50 +04:00
void icon_delete_cb(fltk::Widget*, void* di) {
DesktopIcon* dicon = (DesktopIcon*)di;
edelib::ask(_("Delete '%s' ?"), dicon->label());
2007-05-22 18:53:17 +04:00
}
DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) :
2007-05-22 18:53:17 +04:00
fltk::Widget(isett->x, isett->y, ICONSIZE, ICONSIZE), settings(NULL)
{
EASSERT(gisett != NULL); EASSERT(isett != NULL);
lwidth = lheight = 0;
focus = false;
micon = false;
image_w = image_h = ICONSIZE;
/*
* GlobalIconSettings is shared from desktop so we only
* reference it. On other hand IconSettings is not shared
* and we must construct a copy from given parameter
*/
globals = gisett;
settings = new IconSettings;
settings->name = isett->name;
settings->cmd = isett->cmd;
settings->icon = isett->icon;
settings->type = isett->type;
settings->key_name= isett->key_name;
2007-05-22 18:53:17 +04:00
// x,y are not needed since x(), y() are filled with it
label(settings->name.c_str());
if(!settings->icon.empty()) {
const char* nn = settings->icon.c_str();
edelib::IconSizes isize = edelib::ICON_SIZE_MEDIUM;
edelib::String ipath = edelib::IconTheme::get(nn, isize);
/*
* Resize box according to size from IconSizes.
*
* Here is avoided image()->measure() since looks like
* that function messes up icon's alpha blending if is widget
* resizes (but not icon). This is a bug in fltk.
*/
if(isize >= ICONSIZE) {
image_w = isize;
image_h = isize;
resize(image_w + OFFSET_W, image_h + OFFSET_H);
}
nn = ipath.c_str();
image(fltk::SharedImage::get(nn));
}
EDEBUG(ESTRLOC ": Got label: %s\n", label());
EDEBUG(ESTRLOC ": Got image: %s\n", settings->icon.c_str());
EDEBUG(ESTRLOC ": Got x/y : %i %i\n", x(), y());
align(fltk::ALIGN_WRAP);
update_label_size();
pmenu = new fltk::PopupMenu(0, 0, 100, 100);
pmenu->begin();
if(settings->type == ICON_TRASH) {
2007-05-22 18:53:17 +04:00
edelib::Item* it = new edelib::Item(_("&Open"));
it->offset_x(12, 12);
it = new edelib::Item(_("&Properties"));
it->offset_x(12, 12);
new fltk::Divider();
it = new edelib::Item(_("&Empty"));
it->offset_x(12, 12);
} else {
edelib::Item* it = new edelib::Item(_("&Open"));
it->offset_x(12, 12);
it = new edelib::Item(_("&Rename"));
it->offset_x(12, 12);
it = new edelib::Item(_("&Delete"));
it->offset_x(12, 12);
2007-05-23 16:43:50 +04:00
it->callback(icon_delete_cb, this);
2007-05-22 18:53:17 +04:00
new fltk::Divider();
it = new edelib::Item(_("&Properties"));
it->offset_x(12, 12);
}
pmenu->end();
pmenu->type(fltk::PopupMenu::POPUP3);
}
DesktopIcon::~DesktopIcon()
{
if(settings) {
EDEBUG(ESTRLOC ": IconSettings clearing from ~DesktopIcon()\n");
delete settings;
}
if(micon)
delete micon;
2007-05-23 16:43:50 +04:00
if(pmenu)
delete pmenu;
2007-05-22 18:53:17 +04:00
}
void DesktopIcon::update_label_size(void) {
lwidth = globals->label_maxwidth;
lheight= 0;
// FIXME: really needed ???
fltk::setfont(labelfont(), labelsize());
//fltk::measure(label(), lwidth, lheight, fltk::ALIGN_WRAP);
fltk::measure(label(), lwidth, lheight, flags());
lwidth += 8;
lheight += 4;
}
void DesktopIcon::drag(int x, int y, bool apply) {
if(!micon) {
micon = new MovableIcon(this);
micon->show();
}
EASSERT(micon != NULL);
micon->position(x, y);
if(apply) {
position(micon->x(), micon->y());
delete micon;
micon = 0;
}
}
// Used only in Desktop::move_selection
int DesktopIcon::drag_icon_x(void) {
if(!micon)
return x();
else
return micon->x();
}
// Used only in Desktop::move_selection
int DesktopIcon::drag_icon_y(void) {
if(!micon)
return y();
else
return micon->y();
}
void DesktopIcon::draw(void) {
2007-05-23 16:43:50 +04:00
if(image() && (damage() & fltk::DAMAGE_ALL)) {
2007-05-22 18:53:17 +04:00
fltk::Image* ii = (fltk::Image*)image();
int ix = (w()/2) - (ii->w()/2);
/*
* Make sure to pickup image's w() and h() since if fltk is compiled
* with Xrender it will be scaled to rectangle's w()/h().
*
* On other hand, if fltk is _not_ compiled with Xrender,
* scaling will not be done.
* Yuck !
*/
fltk::Rectangle ir(ix, 5, ii->w(), ii->h());
ii->draw(ir);
}
2007-05-23 16:43:50 +04:00
if(globals->label_draw && (damage() & (fltk::DAMAGE_ALL | fltk::DAMAGE_CHILD_LABEL))) {
2007-05-22 18:53:17 +04:00
int X = w()-(w()/2)-(lwidth/2);
int Y = h()+2;
if(!globals->label_transparent) {
fltk::setcolor(globals->label_background);
fltk::fillrect(X, Y, lwidth, lheight);
}
Rectangle r(X, Y, lwidth, lheight);
fltk::setcolor(globals->label_foreground);
drawtext(label(), r, flags());
if(is_focused()) {
/*
* draw focused box on our way so later
* this can be used to draw customised boxes
*/
fltk::line_style(fltk::DOT);
fltk::push_matrix();
//fltk::setcolor(fltk::WHITE);
fltk::setcolor(globals->label_foreground);
fltk::addvertex(X,Y);
fltk::addvertex(X+lwidth,Y);
fltk::addvertex(X+lwidth,Y+lheight);
fltk::addvertex(X,Y+lheight);
fltk::addvertex(X,Y);
fltk::strokepath();
fltk::pop_matrix();
// revert to default line style
fltk::line_style(0);
}
2007-05-23 16:43:50 +04:00
set_damage(damage() & ~fltk::DAMAGE_CHILD_LABEL);
2007-05-22 18:53:17 +04:00
}
}
int DesktopIcon::handle(int event) {
switch(event) {
2007-05-23 16:43:50 +04:00
case fltk::FOCUS:
case fltk::UNFOCUS:
2007-05-22 18:53:17 +04:00
return 1;
2007-05-23 16:43:50 +04:00
case fltk::ENTER:
2007-05-22 18:53:17 +04:00
case fltk::LEAVE:
return 1;
/*
* We have to handle fltk::MOVE too, if
* want to get only once fltk::ENTER when
* entered or fltk::LEAVE when leaved.
*/
case fltk::MOVE:
return 1;
case fltk::PUSH:
if(fltk::event_button() == 3)
pmenu->popup();
return 1;
case fltk::RELEASE:
if(fltk::event_clicks() > 0)
EDEBUG(ESTRLOC ": EXECUTE: %s\n", settings->cmd.c_str());
return 1;
2007-05-23 16:43:50 +04:00
case fltk::DND_ENTER:
EDEBUG("Icon DND_ENTER\n");
return 1;
case fltk::DND_DRAG:
EDEBUG("Icon DND_DRAG\n");
return 1;
case fltk::DND_LEAVE:
EDEBUG("Icon DND_LEAVE\n");
return 1;
case fltk::DND_RELEASE:
EDEBUG("Icon DND_RELEASE\n");
2007-05-22 18:53:17 +04:00
return 1;
case fltk::PASTE:
EDEBUG("Icon PASTE\n");
return 1;
2007-05-22 18:53:17 +04:00
}
return fltk::Widget::handle(event);
}
MovableIcon::MovableIcon(DesktopIcon* ic) : fltk::Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) {
EASSERT(icon != NULL);
set_override();
create();
fltk::Image* img = icon->icon_image();
if(img)
image(img);
#if 0
if(img) {
#ifdef SHAPE
Pixmap mask = create_pixmap_mask(img->width(), img->height());
XShapeCombineMask(fltk::xdisplay, fltk::xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
#else
image(img);
#endif
}
#endif
}
MovableIcon::~MovableIcon()
{
}