eiconman based on fltk1. Most of the stuff is

revised from scratch.
This commit is contained in:
Sanel Zukan 2007-06-18 14:18:35 +00:00
parent 95a3034827
commit 202b4ffb29
13 changed files with 563 additions and 1136 deletions

View File

@ -1,194 +0,0 @@
/*
* $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 "DesktopConfig.h"
#include "Utils.h"
#include "eiconman.h"
#include <edelib/Nls.h>
#include <edelib/Debug.h>
#include <fltk/Item.h>
#include <fltk/ColorChooser.h>
#include <fltk/file_chooser.h>
#include <fltk/SharedImage.h>
#include <fltk/run.h>
#include <fltk/draw.h>
#include <fltk/x11.h>
void close_cb(fltk::Widget*, void* w) {
DesktopConfig* dc = (DesktopConfig*)w;
dc->hide();
}
void ok_cb(fltk::Widget*, void* w) { }
void apply_cb(fltk::Widget*, void* w) {
DesktopConfig* dc = (DesktopConfig*)w;
//Desktop::instance()->set_bg_color(dc->bg_color());
}
void wp_use_cb(fltk::Widget*, void* w) {
DesktopConfig* dc = (DesktopConfig*)w;
dc->wp_disable();
}
void color_box_cb(fltk::Widget*, void* w) {
DesktopConfig* dc = (DesktopConfig*)w;
fltk::Color col = dc->bg_color();
if(fltk::color_chooser(_("Background color"), col))
dc->set_color(col);
}
void img_browse_cb(fltk::Widget*, void* w) {
DesktopConfig* dc = (DesktopConfig*)w;
const char* f = fltk::file_chooser(_("Choose image"), "Image files (*.{jpg,png,xpm})", 0);
if(f)
dc->set_preview_image(f);
};
PreviewBox::PreviewBox(int x, int y, int w, int h, const char* l) : fltk::InvisibleBox(x,y,w,h)
{
}
PreviewBox::~PreviewBox()
{
}
void PreviewBox::draw(void) {
draw_box();
if(image()) {
fltk::Rectangle ir(0,0,w(),h());
box()->inset(ir);
fltk::Image* im = (fltk::Image*)image();
im->draw(ir);
}
}
DesktopConfig::DesktopConfig() : fltk::Window(540, 265, _("Background settings")), img_enable(false), wp_img(NULL) {
begin();
// monitor
fltk::InvisibleBox* m1 = new fltk::InvisibleBox(75, 175, 100, 15);
m1->box(fltk::BORDER_BOX);
fltk::InvisibleBox* m2 = new fltk::InvisibleBox(20, 20, 210, 160);
m2->box(fltk::THIN_UP_BOX);
preview = new PreviewBox(30, 30, 190, 140);
preview->box(fltk::DOWN_BOX);
preview->color(56);
fltk::InvisibleBox* m4 = new fltk::InvisibleBox(50, 185, 145, 15);
m4->box(fltk::THIN_UP_BOX);
// fetch workspace names
fltk::Choice* ws_names = new fltk::Choice(310, 20, 220, 25, _("Desktop:"));
ws_names->begin();
new fltk::Item(_("All desktops"));
ws_names->end();
// rest
use_wp = new fltk::CheckButton(310, 60, 20, 20, _("Use wallpaper"));
use_wp->align(fltk::ALIGN_RIGHT);
use_wp->callback(wp_use_cb, this);
use_wp->value(1);
img_path = new fltk::Input(310, 95, 190, 25, _("Image:"));
img_browse = new fltk::Button(505, 95, 25, 25, "...");
img_browse->callback(img_browse_cb, this);
img_choice = new fltk::Choice(310, 130, 220, 25, _("Mode:"));
img_choice->begin();
new fltk::Item(_("Normal"));
new fltk::Item(_("Center"));
new fltk::Item(_("Stretch"));
new fltk::Item(_("Aspect stretch"));
new fltk::Item(_("Tile"));
img_choice->end();
color_box = new fltk::Button(310, 175, 25, 25, _("Background color"));
color_box->color((fltk::Color)0x3ca700);
color_box->align(fltk::ALIGN_RIGHT);
color_box->callback(color_box_cb, this);
fltk::Button* ok = new fltk::Button(250, 230, 90, 25, _("&OK"));
ok->callback(ok_cb, this);
fltk::Button* apply = new fltk::Button(345, 230, 90, 25, _("&Apply"));
apply->callback(apply_cb, this);
fltk::Button* close = new fltk::Button(440, 230, 90, 25, _("&Cancel"));
close->callback(close_cb, this);
end();
}
DesktopConfig::~DesktopConfig()
{
}
void DesktopConfig::run(void) {
if(!shown())
show();
while(visible())
fltk::wait();
}
void DesktopConfig::wp_disable(void) {
if(!use_wp->value()) {
img_path->deactivate();
img_browse->deactivate();
img_choice->deactivate();
} else {
img_path->activate();
img_browse->activate();
img_choice->activate();
}
img_enable = false;
preview->image(NULL);
set_color(color_box->color());
}
void DesktopConfig::set_preview_color(unsigned int c) {
if(c == preview->color())
return;
preview->color(c);
preview->redraw();
}
void DesktopConfig::set_color(unsigned int c) {
if(c != color_box->color()) {
color_box->color(c);
color_box->redraw();
}
set_preview_color(c);
}
void DesktopConfig::set_preview_image(const char* path) {
EASSERT(path != NULL);
if(wp_path == path)
return;
wp_path = path;
wp_img = fltk::SharedImage::get(wp_path.c_str());
preview->image(wp_img);
preview->redraw();
img_path->value(wp_path.c_str());
}

View File

@ -1,60 +0,0 @@
/*
* $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.
*/
#ifndef __DESKTOPCONFIG_H__
#define __DESKTOPCONFIG_H__
#include <fltk/Window.h>
#include <fltk/Button.h>
#include <fltk/Input.h>
#include <fltk/InvisibleBox.h>
#include <fltk/Choice.h>
#include <fltk/CheckButton.h>
#include <fltk/Image.h>
#include <edelib/String.h>
class PreviewBox : public fltk::InvisibleBox {
public:
PreviewBox(int x, int y, int w, int h, const char* l = 0);
~PreviewBox();
virtual void draw(void);
};
class DesktopConfig : public fltk::Window {
private:
bool img_enable;
fltk::Image* wp_img;
fltk::Input* img_path;
fltk::Button* img_browse;
fltk::Choice* img_choice;
fltk::CheckButton* use_wp;
PreviewBox* preview;
fltk::Button* color_box;
edelib::String wp_path;
public:
DesktopConfig();
~DesktopConfig();
void run(void);
void wp_disable(void);
bool wp_enabled(void) { return img_enable; }
void set_preview_color(unsigned int c);
void set_preview_image(const char* path);
void set_color(unsigned int c);
unsigned int bg_color(void) { return color_box->color(); }
};
#endif

View File

@ -12,63 +12,50 @@
#include "DesktopIcon.h" #include "DesktopIcon.h"
#include "eiconman.h" #include "eiconman.h"
#include "Utils.h"
#include <FL/Fl.h>
#include <FL/fl_draw.h>
#include <FL/Fl_Shared_Image.h>
#include <FL/x.h>
#include <edelib/Debug.h> #include <edelib/Debug.h>
#include <edelib/IconTheme.h> #include <edelib/IconTheme.h>
#include <edelib/Nls.h>
#include <edelib/Item.h>
#include <edelib/Ask.h>
#include <fltk/SharedImage.h> #include <X11/extensions/shape.h>
#include <fltk/Color.h>
#include <fltk/Divider.h>
#include <fltk/draw.h>
#include <fltk/events.h>
#include <fltk/damage.h>
#include <fltk/x11.h> // Pixmap // minimal icon size
// fuck !
#define Window XWindow
#include <X11/extensions/shape.h>
#undef Window
// default icon size
#define ICONSIZE 48 #define ICONSIZE 48
// spaces around box in case of large/small icons // spaces around box in case of large/small icons
#define OFFSET_W 16 #define OFFSET_W 16
#define OFFSET_H 16 #define OFFSET_H 16
void icon_delete_cb(fltk::Widget*, void* di) { // label offset from icon y()+h(), so selection box can be drawn nicely
DesktopIcon* dicon = (DesktopIcon*)di; #define LABEL_OFFSET 2
edelib::ask(_("Delete '%s' ?"), dicon->label());
}
DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) : DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
fltk::Widget(isett->x, isett->y, ICONSIZE, ICONSIZE), settings(NULL) Fl_Button(is->x, is->y, ICONSIZE, ICONSIZE) {
{
EASSERT(gisett != NULL); EASSERT(isett != NULL); EASSERT(gs != NULL);
lwidth = lheight = 0; lwidth = lheight = 0;
focus = false; focus = false;
micon = false; micon = NULL;
image_w = image_h = ICONSIZE;
/* /*
* GlobalIconSettings is shared from desktop so we only * GlobalIconSettings is shared from desktop so we only
* reference it. On other hand IconSettings is not shared * reference it. On other hand IconSettings is not shared
* and we must construct a copy from given parameter * and we must construct a copy from given parameter
*/ */
globals = gisett; globals = gs;
settings = new IconSettings; settings = new IconSettings;
settings->name = isett->name; settings->name = is->name;
settings->cmd = isett->cmd; settings->cmd = is->cmd;
settings->icon = isett->icon; settings->icon = is->icon;
settings->type = isett->type; settings->type = is->type;
settings->key_name= isett->key_name; settings->key_name= is->key_name;
// x,y are not needed since x(), y() are filled with it // x,y are not needed since x(), y() are filled with it
@ -77,83 +64,52 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) :
if(!settings->icon.empty()) { if(!settings->icon.empty()) {
const char* nn = settings->icon.c_str(); const char* nn = settings->icon.c_str();
edelib::IconSizes isize = edelib::ICON_SIZE_MEDIUM; edelib::String ipath = edelib::IconTheme::get(nn, edelib::ICON_SIZE_MEDIUM);
edelib::String ipath = edelib::IconTheme::get(nn, isize); Fl_Image* img = Fl_Shared_Image::get(ipath.c_str());
if(img) {
int img_w = img->w();
int img_h = img->h();
/* // resize box if icon is larger
* Resize box according to size from IconSizes. if(img_w > ICONSIZE || img_h > ICONSIZE)
* size(img_w + OFFSET_W, img_h + OFFSET_H);
* 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); image(img);
} } else
EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str());
nn = ipath.c_str();
image(fltk::SharedImage::get(nn));
} }
/*
EDEBUG(ESTRLOC ": Got label: %s\n", label()); EDEBUG(ESTRLOC ": Got label: %s\n", label());
EDEBUG(ESTRLOC ": Got image: %s\n", settings->icon.c_str()); EDEBUG(ESTRLOC ": Got image: %s\n", settings->icon.c_str());
EDEBUG(ESTRLOC ": Got x/y : %i %i\n", x(), y()); EDEBUG(ESTRLOC ": Got x/y : %i %i\n", x(), y());
*/
//Use desktop color as color for icon background
color(bg);
align(fltk::ALIGN_WRAP); align(FL_ALIGN_WRAP);
update_label_size(); update_label_size();
pmenu = new fltk::PopupMenu(0, 0, 100, 100);
pmenu->begin();
if(settings->type == ICON_TRASH) {
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);
it->callback(icon_delete_cb, this);
new fltk::Divider();
it = new edelib::Item(_("&Properties"));
it->offset_x(12, 12);
}
pmenu->end();
pmenu->type(fltk::PopupMenu::POPUP3);
} }
DesktopIcon::~DesktopIcon() DesktopIcon::~DesktopIcon() {
{ EDEBUG("DesktopIcon::~DesktopIcon()\n");
if(settings) {
EDEBUG(ESTRLOC ": IconSettings clearing from ~DesktopIcon()\n");
delete settings;
}
if(settings)
delete settings;
if(micon) if(micon)
delete micon; delete micon;
if(pmenu)
delete pmenu;
} }
void DesktopIcon::update_label_size(void) { void DesktopIcon::update_label_size(void) {
lwidth = globals->label_maxwidth; lwidth = globals->label_maxwidth;
lheight= 0; lheight= 0;
// FIXME: really needed ??? /*
fltk::setfont(labelfont(), labelsize()); * make sure current font size/type is set (internaly to fltk)
* so fl_measure() can correctly calculate label width and height
*/
fl_font(labelfont(), labelsize());
//fltk::measure(label(), lwidth, lheight, fltk::ALIGN_WRAP); fl_measure(label(), lwidth, lheight, align());
fltk::measure(label(), lwidth, lheight, flags());
lwidth += 8; lwidth += 8;
lheight += 4; lheight += 4;
@ -172,7 +128,7 @@ void DesktopIcon::drag(int x, int y, bool apply) {
if(apply) { if(apply) {
position(micon->x(), micon->y()); position(micon->x(), micon->y());
delete micon; delete micon;
micon = 0; micon = NULL;
} }
} }
@ -192,130 +148,94 @@ int DesktopIcon::drag_icon_y(void) {
return micon->y(); return micon->y();
} }
void DesktopIcon::fast_redraw(void) {
EASSERT(parent() != NULL && "Impossible !");
// LABEL_OFFSET + 2 include selection box line height too
parent()->damage(FL_DAMAGE_ALL, x(), y(), w(), h() + lheight + LABEL_OFFSET + 2);
}
void DesktopIcon::draw(void) { void DesktopIcon::draw(void) {
if(image() && (damage() & fltk::DAMAGE_ALL)) { //draw_box(FL_UP_BOX, FL_BLACK);
fltk::Image* ii = (fltk::Image*)image();
int ix = (w()/2) - (ii->w()/2); if(image() && (damage() & FL_DAMAGE_ALL)) {
/* Fl_Image* im = image();
* 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(). // center image in the box
* int ix = (w()/2) - (im->w()/2);
* On other hand, if fltk is _not_ compiled with Xrender, int iy = (h()/2) - (im->h()/2);
* scaling will not be done. ix += x();
* Yuck ! iy += y();
*/
fltk::Rectangle ir(ix, 5, ii->w(), ii->h()); im->draw(ix, iy);
ii->draw(ir);
} }
if(globals->label_draw && (damage() & (fltk::DAMAGE_ALL | fltk::DAMAGE_CHILD_LABEL))) { if(globals->label_draw && (damage() & (FL_DAMAGE_ALL))) {
int X = w()-(w()/2)-(lwidth/2); int X = x() + w()-(w()/2)-(lwidth/2);
int Y = h()+2; int Y = y() + h() + LABEL_OFFSET;
Fl_Color old = fl_color();
if(!globals->label_transparent) { if(!globals->label_transparent) {
fltk::setcolor(globals->label_background); fl_color(globals->label_background);
fltk::fillrect(X, Y, lwidth, lheight); fl_rectf(X, Y, lwidth, lheight);
} }
Rectangle r(X, Y, lwidth, lheight); fl_color(globals->label_foreground);
fl_draw(label(), X, Y, lwidth, lheight, align(), 0, 0);
fltk::setcolor(globals->label_foreground);
drawtext(label(), r, flags());
if(is_focused()) { if(is_focused()) {
/* /*
* draw focused box on our way so later * draw focused box on our way so later
* this can be used to draw customised boxes * this can be used to draw customised boxes
*/ */
fltk::line_style(fltk::DOT); fl_line_style(FL_DOT);
fltk::push_matrix(); fl_color(globals->label_foreground);
//fltk::setcolor(fltk::WHITE); fl_push_matrix();
fltk::setcolor(globals->label_foreground); fl_begin_loop();
fltk::addvertex(X,Y); fl_vertex(X,Y);
fltk::addvertex(X+lwidth,Y); fl_vertex(X+lwidth,Y);
fltk::addvertex(X+lwidth,Y+lheight); fl_vertex(X+lwidth,Y+lheight);
fltk::addvertex(X,Y+lheight); fl_vertex(X,Y+lheight);
fltk::addvertex(X,Y); fl_vertex(X,Y);
fltk::strokepath(); fl_end_loop();
fl_pop_matrix();
fltk::pop_matrix();
// revert to default line style // revert to default line style
fltk::line_style(0); fl_line_style(0);
} }
set_damage(damage() & ~fltk::DAMAGE_CHILD_LABEL); // revert to old color whatever that be
fl_color(old);
} }
} }
int DesktopIcon::handle(int event) { int DesktopIcon::handle(int event) {
switch(event) { return Fl_Button::handle(event);
case fltk::FOCUS:
case fltk::UNFOCUS:
return 1;
case fltk::ENTER:
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;
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");
return 1;
case fltk::PASTE:
EDEBUG("Icon PASTE\n");
return 1;
}
return fltk::Widget::handle(event);
} }
MovableIcon::MovableIcon(DesktopIcon* ic) : fltk::Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) { MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) {
EASSERT(icon != NULL); EASSERT(icon != NULL);
set_override(); set_override();
create(); color(ic->color());
fltk::Image* img = icon->icon_image(); begin();
if(img) icon_box = new Fl_Box(0, 0, w(), h());
image(img); icon_box->image(ic->icon_image());
end();
}
MovableIcon::~MovableIcon() {
}
void MovableIcon::show(void) {
if(!shown())
Fl_X::make_xid(this);
#if 0 #if 0
if(img) { Pixmap mask = create_mask((Fl_RGB_Image*)icon->icon_image());
#ifdef SHAPE XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
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 #endif
} }
MovableIcon::~MovableIcon()
{
}

View File

@ -13,16 +13,17 @@
#ifndef __DESKTOPICON_H__ #ifndef __DESKTOPICON_H__
#define __DESKTOPICON_H__ #define __DESKTOPICON_H__
#include <fltk/Widget.h> #include <FL/Fl_Widget.h>
#include <fltk/Window.h> #include <FL/Fl_Window.h>
#include <fltk/Image.h> #include <FL/Fl_Box.h>
#include <fltk/PopupMenu.h> #include <FL/Fl_Button.h>
#include <FL/Fl_Image.h>
class GlobalIconSettings; class GlobalIconSettings;
class IconSettings; class IconSettings;
class MovableIcon; class MovableIcon;
class DesktopIcon : public fltk::Widget { class DesktopIcon : public Fl_Button {
private: private:
IconSettings* settings; IconSettings* settings;
const GlobalIconSettings* globals; const GlobalIconSettings* globals;
@ -31,24 +32,33 @@ class DesktopIcon : public fltk::Widget {
int lheight; int lheight;
bool focus; bool focus;
// pseudosizes (nor real icon sizes)
int image_w;
int image_h;
fltk::PopupMenu* pmenu;
MovableIcon* micon; MovableIcon* micon;
void update_label_size(void); void update_label_size(void);
public: public:
DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett); DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett, int bg);
~DesktopIcon(); ~DesktopIcon();
virtual void draw(void); virtual void draw(void);
virtual int handle(int event); virtual int handle(int event);
void drag(int x, int y, bool apply); void drag(int x, int y, bool apply);
int drag_icon_x(void); int drag_icon_x(void);
int drag_icon_y(void); int drag_icon_y(void);
/*
* This is 'enhanced' (in some sense) redraw(). Redrawing
* icon will not fully redraw label nor focus box, which laid outside
* icon box. It will use damage() on given region, but called from
* parent, so parent can redraw that region on itself (since label does
* not laid on any box)
*
* Alternative way would be to redraw whole parent, but it is pretty unneeded
* and slow.
*/
void fast_redraw(void);
/* /*
* Here is implemented localy focus schema avoiding * Here is implemented localy focus schema avoiding
* messy fltk one. Focus/unfocus is handled from Desktop. * messy fltk one. Focus/unfocus is handled from Desktop.
@ -57,19 +67,20 @@ class DesktopIcon : public fltk::Widget {
void do_unfocus(void) { focus = false; } void do_unfocus(void) { focus = false; }
bool is_focused(void) { return focus; } bool is_focused(void) { return focus; }
fltk::Image* icon_image(void) { return (fltk::Image*)image(); } Fl_Image* icon_image(void) { return image(); }
const IconSettings* get_settings(void) const { return settings; } const IconSettings* get_settings(void) const { return settings; }
}; };
class MovableIcon : public Fl_Window {
class MovableIcon : public fltk::Window {
private: private:
DesktopIcon* icon; DesktopIcon* icon;
Fl_Box* icon_box;
public: public:
MovableIcon(DesktopIcon* i); MovableIcon(DesktopIcon* i);
~MovableIcon(); ~MovableIcon();
virtual void show(void);
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -lfltk2_images -lpng -lfltk2_images -ljpeg -lz -lfltk2 -L/usr/X11R6/lib -lX11 -lXi -lXinerama -lpthread -lm -lXext -lstdc++ ; #LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -lfltk2_images -lpng -lfltk2_images -ljpeg -lz -lfltk2 -L/usr/X11R6/lib -lX11 -lXi -lXinerama -lpthread -lm -lXext -lstdc++ ;
LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -lfltk2_images -lpng -lfltk2_images -ljpeg -lz -lfltk2 -L/usr/X11R6/lib -lX11 -lXi -lXinerama -lpthread -lm -lXft -lXext -lstdc++ ; LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -L/usr/X11R6/lib -lfltk_images -lpng -lz -ljpeg -lfltk -ldl -lm -lXext -lX11 -lstdc++ ;
C++FLAGS += -g3 -I/opt/ede/include ; C++FLAGS += -Wall -g3 -I/opt/ede/include ;
Main eiconman : eiconman.cpp Utils.cpp DesktopIcon.cpp DesktopConfig.cpp ; Main eiconman : eiconman.cpp Utils.cpp Wallpaper.cpp DesktopIcon.cpp ;

View File

@ -12,9 +12,11 @@
#include "Utils.h" #include "Utils.h"
#include <X11/Xproto.h> // CARD32 #include <X11/Xproto.h> // CARD32
#include <fltk/x11.h> #include <FL/x.h>
#include <edelib/Debug.h> #include <edelib/Debug.h>
#include <string.h> // strrchr
Atom NET_WORKAREA = 0; Atom NET_WORKAREA = 0;
Atom NET_WM_WINDOW_TYPE = 0; Atom NET_WM_WINDOW_TYPE = 0;
Atom NET_WM_WINDOW_TYPE_DESKTOP = 0; Atom NET_WM_WINDOW_TYPE_DESKTOP = 0;
@ -27,20 +29,22 @@ int overlay_y = 0;
int overlay_w = 0; int overlay_w = 0;
int overlay_h = 0; int overlay_h = 0;
Fl_Window* overlay_drawable = NULL;
char dash_list[] = {1}; char dash_list[] = {1};
bool net_get_workarea(int& x, int& y, int& w, int &h) { bool net_get_workarea(int& x, int& y, int& w, int &h) {
Atom real; Atom real;
if(!NET_WORKAREA) if(!NET_WORKAREA)
NET_WORKAREA= XInternAtom(fltk::xdisplay, "_NET_WORKAREA", 1); NET_WORKAREA= XInternAtom(fl_display, "_NET_WORKAREA", 1);
int format; int format;
unsigned long n, extra; unsigned long n, extra;
unsigned char* prop; unsigned char* prop;
x = y = w = h = 0; x = y = w = h = 0;
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
NET_WORKAREA, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop); NET_WORKAREA, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop);
if(status != Success) if(status != Success)
@ -60,18 +64,18 @@ bool net_get_workarea(int& x, int& y, int& w, int &h) {
return false; return false;
} }
void net_make_me_desktop(fltk::Window* w) { void net_make_me_desktop(Fl_Window* w) {
if(!NET_WM_WINDOW_TYPE) if(!NET_WM_WINDOW_TYPE)
NET_WM_WINDOW_TYPE = XInternAtom(fltk::xdisplay, "_NET_WM_WINDOW_TYPE", False); NET_WM_WINDOW_TYPE = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False);
if(!NET_WM_WINDOW_TYPE_DESKTOP) if(!NET_WM_WINDOW_TYPE_DESKTOP)
NET_WM_WINDOW_TYPE_DESKTOP= XInternAtom(fltk::xdisplay, "_NET_WM_WINDOW_TYPE_DESKTOP", False); NET_WM_WINDOW_TYPE_DESKTOP= XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
/* /*
* xid() will return zero if window is not shown; * xid() will return zero if window is not shown;
* make sure it is shown * make sure it is shown
*/ */
EASSERT(fltk::xid(w)); EASSERT(fl_xid(w));
/* /*
* Reminder for me (others possible): * Reminder for me (others possible):
@ -80,20 +84,20 @@ void net_make_me_desktop(fltk::Window* w) {
* *
* I lost two hours messing with this ! (gdb is unusefull in X world) * I lost two hours messing with this ! (gdb is unusefull in X world)
*/ */
XChangeProperty(fltk::xdisplay, fltk::xid(w), NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, XChangeProperty(fl_display, fl_xid(w), NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace,
(unsigned char*)&NET_WM_WINDOW_TYPE_DESKTOP, sizeof(Atom)); (unsigned char*)&NET_WM_WINDOW_TYPE_DESKTOP, sizeof(Atom));
} }
int net_get_workspace_count(void) { int net_get_workspace_count(void) {
if(!NET_NUMBER_OF_DESKTOPS) if(!NET_NUMBER_OF_DESKTOPS)
NET_NUMBER_OF_DESKTOPS = XInternAtom(fltk::xdisplay, "_NET_NUMBER_OF_DESKTOPS", False); NET_NUMBER_OF_DESKTOPS = XInternAtom(fl_display, "_NET_NUMBER_OF_DESKTOPS", False);
Atom real; Atom real;
int format; int format;
unsigned long n, extra; unsigned long n, extra;
unsigned char* prop; unsigned char* prop;
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
NET_NUMBER_OF_DESKTOPS, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, NET_NUMBER_OF_DESKTOPS, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra,
(unsigned char**)&prop); (unsigned char**)&prop);
@ -108,13 +112,13 @@ int net_get_workspace_count(void) {
// desktops are starting from 0 // desktops are starting from 0
int net_get_current_desktop(void) { int net_get_current_desktop(void) {
if(!NET_CURRENT_DESKTOP) if(!NET_CURRENT_DESKTOP)
NET_CURRENT_DESKTOP = XInternAtom(fltk::xdisplay, "_NET_CURRENT_DESKTOP", False); NET_CURRENT_DESKTOP = XInternAtom(fl_display, "_NET_CURRENT_DESKTOP", False);
Atom real; Atom real;
int format; int format;
unsigned long n, extra; unsigned long n, extra;
unsigned char* prop; unsigned char* prop;
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
NET_CURRENT_DESKTOP, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop); NET_CURRENT_DESKTOP, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop);
if(status != Success && !prop) if(status != Success && !prop)
@ -128,11 +132,11 @@ int net_get_current_desktop(void) {
// call on this XFreeStringList(names) // call on this XFreeStringList(names)
int net_get_workspace_names(char**& names) { int net_get_workspace_names(char**& names) {
if(!NET_DESKTOP_NAMES) if(!NET_DESKTOP_NAMES)
NET_DESKTOP_NAMES = XInternAtom(fltk::xdisplay, "_NET_DESKTOP_NAMES", False); NET_DESKTOP_NAMES = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
// FIXME: add _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED ??? // FIXME: add _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED ???
XTextProperty wnames; XTextProperty wnames;
XGetTextProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), &wnames, NET_DESKTOP_NAMES); XGetTextProperty(fl_display, RootWindow(fl_display, fl_screen), &wnames, NET_DESKTOP_NAMES);
// if wm does not understainds _NET_DESKTOP_NAMES this is not set // if wm does not understainds _NET_DESKTOP_NAMES this is not set
if(!wnames.nitems || !wnames.value) if(!wnames.nitems || !wnames.value)
@ -152,14 +156,14 @@ int net_get_workspace_names(char**& names) {
#if 0 #if 0
int net_get_workspace_names(char** names) { int net_get_workspace_names(char** names) {
Atom nd = XInternAtom(fltk::xdisplay, "_NET_DESKTOP_NAMES", False); Atom nd = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
Atom utf8_str = XInternAtom(fltk::xdisplay, "UTF8_STRING", False); Atom utf8_str = XInternAtom(fl_display, "UTF8_STRING", False);
Atom real; Atom real;
int format; int format;
unsigned long n, extra; unsigned long n, extra;
unsigned char* prop; unsigned char* prop;
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
nd, 0L, 0x7fffffff, False, utf8_str, &real, &format, &n, &extra, (unsigned char**)&prop); nd, 0L, 0x7fffffff, False, utf8_str, &real, &format, &n, &extra, (unsigned char**)&prop);
if(status != Success && !prop) if(status != Success && !prop)
@ -185,16 +189,23 @@ void draw_overlay_rect(void) {
if(overlay_w <= 0 || overlay_h <= 0) if(overlay_w <= 0 || overlay_h <= 0)
return; return;
XSetDashes(fltk::xdisplay, fltk::gc, 0, dash_list, 1); XSetDashes(fl_display, fl_gc, 0, dash_list, 1);
XSetLineAttributes(fltk::xdisplay, fltk::gc, 1, LineOnOffDash, CapButt, JoinMiter); XSetLineAttributes(fl_display, fl_gc, 1, LineOnOffDash, CapButt, JoinMiter);
XSetFunction(fltk::xdisplay, fltk::gc, GXxor); XSetFunction(fl_display, fl_gc, GXxor);
XSetForeground(fltk::xdisplay, fltk::gc, 0xffffffff); XSetForeground(fl_display, fl_gc, 0xffffffff);
XDrawRectangle(fltk::xdisplay, fltk::xwindow, fltk::gc, overlay_x, overlay_y, overlay_w-1, overlay_h-1);
XSetFunction(fltk::xdisplay, fltk::gc, GXcopy); Window ow;
if(overlay_drawable)
ow = fl_xid(overlay_drawable);
else
ow = fl_window;
XDrawRectangle(fl_display, ow, fl_gc, overlay_x, overlay_y, overlay_w-1, overlay_h-1);
XSetFunction(fl_display, fl_gc, GXcopy);
// set line to 0 again // set line to 0 again
XSetLineAttributes(fltk::xdisplay, fltk::gc, 0, LineOnOffDash, CapButt, JoinMiter); XSetLineAttributes(fl_display, fl_gc, 0, LineOnOffDash, CapButt, JoinMiter);
} }
void draw_xoverlay(int x, int y, int w, int h) { void draw_xoverlay(int x, int y, int w, int h) {
@ -230,3 +241,15 @@ void clear_xoverlay(void) {
overlay_w = 0; overlay_w = 0;
} }
} }
void set_xoverlay_drawable(Fl_Window* win) {
overlay_drawable = win;
}
char* get_basename(const char* path) {
char* p = strrchr(path, '/');
if(p)
return (p + 1);
return (char*) path;
}

View File

@ -13,15 +13,23 @@
#ifndef __UTILS_H__ #ifndef __UTILS_H__
#define __UTILS_H__ #define __UTILS_H__
#include <fltk/Window.h> #include <FL/Fl_Window.h>
#include <FL/Fl_Image.h>
#include <X11/Xlib.h> // Pixmap
int net_get_workspace_count(void); int net_get_workspace_count(void);
int net_get_current_desktop(void); int net_get_current_desktop(void);
bool net_get_workarea(int& x, int& y, int& w, int &h); bool net_get_workarea(int& x, int& y, int& w, int &h);
void net_make_me_desktop(fltk::Window* w); void net_make_me_desktop(Fl_Window* w);
int net_get_workspace_names(char**& names); int net_get_workspace_names(char**& names);
void draw_xoverlay(int x, int y, int w, int h); void draw_xoverlay(int x, int y, int w, int h);
void clear_xoverlay(void); void clear_xoverlay(void);
void set_xoverlay_drawable(Fl_Window* win);
Pixmap create_mask(Fl_RGB_Image* img);
char* get_basename(const char* path);
#endif #endif

87
eiconman/Wallpaper.cpp Normal file
View File

@ -0,0 +1,87 @@
/*
* $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 "Wallpaper.h"
#include <edelib/Debug.h>
#include <FL/Fl_Shared_Image.h>
#include <FL/fl_draw.h>
Wallpaper::Wallpaper(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H, 0), img(NULL), tiled(false) {
}
Wallpaper::~Wallpaper() {
}
bool Wallpaper::set(const char* path) {
EASSERT(path != NULL);
tiled = false;
Fl_Image* i = Fl_Shared_Image::get(path);
if(!i)
return false;
img = i;
image(img);
return true;
}
bool Wallpaper::set_tiled(const char* path) {
bool ret = set(path);
if(ret)
tiled = true;
return ret;
}
void Wallpaper::draw(void) {
if(!image())
return;
int ix, iy, iw, ih;
Fl_Image* im = image();
iw = im->w();
ih = im->h();
if(iw == 0 || ih == 0)
return;
if(ih < h() || iw < w()) {
if(tiled) {
// tile image across the box
fl_push_clip(x(), y(), w(), h());
int tx = x() - (x() % iw);
int ty = y() - (y() % ih);
int tw = w() + tx;
int th = h() + ty;
for(int j = 0; j < th; j += ih)
for(int i = 0; i < tw; i += iw)
im->draw(i, j);
fl_pop_clip();
return;
} else {
// center image in the box
ix = (w()/2) - (iw/2);
iy = (h()/2) - (ih/2);
ix += x();
iy += y();
}
} else {
ix = x();
iy = y();
}
im->draw(ix, iy);
}

37
eiconman/Wallpaper.h Normal file
View File

@ -0,0 +1,37 @@
/*
* $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.
*/
#ifndef __WALLPAPER_H__
#define __WALLPAPER_H__
#include <FL/Fl_Box.h>
#include <FL/Fl_Image.h>
/*
* Class responsible for displaying images at background
* their scaling (TODO), caching(TODO) and making coffee at spear time.
*/
class Wallpaper : public Fl_Box {
private:
Fl_Image* img;
bool tiled;
public:
Wallpaper(int X, int Y, int W, int H);
~Wallpaper();
bool set(const char* path);
bool set_tiled(const char* path);
virtual void draw(void);
};
#endif

View File

@ -1,5 +1,5 @@
[Desktop] [Desktop]
Color = 35 Color = 45
WallpaperUse = 0 WallpaperUse = 0
Wallpaper = /home/foo/xxx/baz/tax Wallpaper = /home/foo/xxx/baz/tax

View File

@ -12,60 +12,38 @@
#include "eiconman.h" #include "eiconman.h"
#include "DesktopIcon.h" #include "DesktopIcon.h"
#include "DesktopConfig.h"
#include "Utils.h" #include "Utils.h"
#include "Wallpaper.h"
#include <edelib/Nls.h>
#include <edelib/Debug.h> #include <edelib/Debug.h>
#include <edelib/Config.h>
#include <edelib/Directory.h>
#include <edelib/StrUtil.h>
#include <edelib/File.h> #include <edelib/File.h>
#include <edelib/IconTheme.h> #include <edelib/Directory.h>
#include <edelib/Item.h>
#include <edelib/MimeType.h> #include <edelib/MimeType.h>
#include <edelib/StrUtil.h>
#include <edelib/IconTheme.h>
#include <fltk/Divider.h> #include <FL/Fl.h>
#include <fltk/damage.h> #include <FL/Fl_Shared_Image.h>
#include <fltk/Color.h> #include <FL/x.h>
#include <fltk/events.h> #include <FL/Fl_Box.h>
#include <fltk/run.h>
#include <fltk/x11.h>
#include <fltk/SharedImage.h>
#include <signal.h> #include <signal.h>
#include <X11/Xproto.h> // CARD32
#include <stdlib.h> // rand, srand #include <stdlib.h> // rand, srand
#include <time.h> // time #include <time.h> // time
#include <stdio.h> // snprintf
/* #define CONFIG_NAME "eiconman.conf"
* NOTE: DO NOT set 'using namespace fltk' here
* since fltk::Window will collide with Window from X11
* resulting compilation errors.
*
* This is why I hate this namespace shit !
*/
#define CONFIG_NAME "eiconman.conf" #define SELECTION_SINGLE (Fl::event_button() == 1)
#define SELECTION_MULTI (Fl::event_button() == 1 && (Fl::event_key(FL_Shift_L) || Fl::event_key(FL_Shift_R)))
#define SELECTION_SINGLE (fltk::event_button() == 1)
#define SELECTION_MULTI (fltk::event_button() == 1 && \
(fltk::get_key_state(fltk::LeftShiftKey) ||\
fltk::get_key_state(fltk::RightShiftKey)))
#define MIN(x,y) ((x) < (y) ? (x) : (y)) #define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MAX(x,y) ((x) > (y) ? (x) : (y))
/* // which widgets Fl::belowmouse() to skip
* Added since fltk DAMAGE_OVERLAY value is used in few different contexts #define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper))
* and re-using it will do nothing. Yuck!
*/
#define EDAMAGE_OVERLAY 2
Desktop* Desktop::pinstance = NULL; Desktop* Desktop::pinstance = NULL;
bool running = true; bool running = false;
inline unsigned int random_pos(int max) { inline unsigned int random_pos(int max) {
return (rand() % max); return (rand() % max);
@ -76,10 +54,10 @@ inline bool intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, i
MAX(y1, y2) <= MIN(h1, h2)); MAX(y1, y2) <= MIN(h1, h2));
} }
// assume fl_open_display() is called before
inline void dpy_sizes(int& width, int& height) { inline void dpy_sizes(int& width, int& height) {
fltk::open_display(); width = DisplayWidth(fl_display, fl_screen);
width = DisplayWidth(fltk::xdisplay, fltk::xscreen); height = DisplayHeight(fl_display, fl_screen);
height = DisplayHeight(fltk::xdisplay, fltk::xscreen);
} }
void exit_signal(int signum) { void exit_signal(int signum) {
@ -87,103 +65,43 @@ void exit_signal(int signum) {
running = false; running = false;
} }
/* void restart_signal(int signum) {
* It is used to notify desktop when _NET_CURRENT_DESKTOP is triggered. EDEBUG(ESTRLOC ": Restarting (got signal %d)\n", signum);
* FIXME: _NET_WORKAREA is nice thing that could set here too :)
*
* FIXME: XInternAtom should be placed somewhere else
*/
int desktop_xmessage_handler(int e, fltk::Window*) {
Atom nd = XInternAtom(fltk::xdisplay, "_NET_CURRENT_DESKTOP", False);
if(fltk::xevent.type == PropertyNotify) {
if(fltk::xevent.xproperty.atom == nd) {
EDEBUG(ESTRLOC ": Desktop changed !!!\n");
return 1;
}
}
return 0;
} }
void background_cb(fltk::Widget*, void*) { int desktop_xmessage_handler(int event) { return 0; }
DesktopConfig dc;
dc.run();
}
Desktop::Desktop() : fltk::Window(0, 0, 100, 100, "") Desktop::Desktop() : Fl_Window(0, 0, 100, 100, "") {
{
selection_x = selection_y = 0;
moving = false; moving = false;
desktops_num = 0;
curr_desktop = 0;
selbox = new SelectionOverlay;
selbox->x = selbox->y = selbox->w = selbox->h = 0;
selbox->show = false;
dsett = new DesktopSettings; dsett = new DesktopSettings;
dsett->color = 0; dsett->color = FL_GRAY;
dsett->wp_use = false; dsett->wp_use = false;
dsett->wp_image = NULL;
// fallback if update_workarea() fails
int dw, dh;
dpy_sizes(dw, dh);
resize(dw, dh);
update_workarea(); update_workarea();
read_config(); /*
* NOTE: order how childs are added is important. First
* non iconable ones should be added (wallpaper, menu, ...)
* then icons, so they can be drawn at top of them.
*/
begin(); begin();
wallpaper = new Wallpaper(0, 0, w(), h());
pmenu = new fltk::PopupMenu(0, 0, 450, 50); //wallpaper->set_tiled("/home/sanel/wallpapers/katesmall.jpg");
pmenu->begin();
edelib::Item* it = new edelib::Item(_("&New desktop item"));
it->offset_x(12, 12);
new fltk::Divider();
it = new edelib::Item(_("&Line up vertical"));
it->offset_x(12, 12);
it = new edelib::Item(_("&Line up horizontal"));
it->offset_x(12, 12);
it = new edelib::Item(_("&Arrange by name"));
it->offset_x(12, 12);
new fltk::Divider();
it = new edelib::Item(_("&Icon settings"));
it->offset_x(12, 12);
edelib::Item* itbg = new edelib::Item(_("&Background settings"));
itbg->offset_x(12, 12);
itbg->callback(background_cb);
pmenu->end();
pmenu->type(fltk::PopupMenu::POPUP3);
end(); end();
if(dsett->wp_use) read_config();
set_wallpaper(dsett->wp_path.c_str(), false);
else set_bg_color(dsett->color, false);
set_bg_color(dsett->color, false); running = true;
} }
Desktop::~Desktop() { Desktop::~Desktop() {
EDEBUG(ESTRLOC ": Desktop::~Desktop()\n"); EDEBUG("Desktop::~Desktop()\n");
save_config(); delete dsett;
if(selbox)
delete selbox;
/*
* icons member deleting is not needed, since add_icon will
* append to icons and to fltk::Group array. Desktop at the end
* will cleanup fltk::Group array.
*/
icons.clear();
if(dsett)
delete dsett;
} }
void Desktop::init(void) { void Desktop::init(void) {
@ -205,49 +123,43 @@ Desktop* Desktop::instance(void) {
return Desktop::pinstance; return Desktop::pinstance;
} }
void Desktop::update_workarea(void) { /*
int X,Y,W,H; * This function must be overriden so window can inform
if(net_get_workarea(X, Y, W, H)) * wm to see it as desktop. It will send data when window
resize(X,Y,W,H); * is created, but before is shown.
*/
void Desktop::show(void) {
if(!shown()) {
Fl_X::make_xid(this);
net_make_me_desktop(this);
}
} }
void Desktop::set_bg_color(unsigned int c, bool do_redraw) { /*
EASSERT(dsett != NULL); * If someone intentionaly hide desktop
* then quit from it.
*/
void Desktop::hide(void) {
running = false;
}
void Desktop::update_workarea(void) {
int X, Y, W, H;
if(!net_get_workarea(X, Y, W, H)) {
EWARNING(ESTRLOC ": wm does not support _NET_WM_WORKAREA; using screen sizes...\n");
X = Y = 0;
dpy_sizes(W, H);
}
resize(X, Y, W, H);
}
void Desktop::set_bg_color(int c, bool do_redraw) {
if(color() == c)
return;
dsett->color = c; dsett->color = c;
color(c); color(c);
if(do_redraw)
redraw();
}
void Desktop::set_wallpaper(const char* path, bool do_redraw) {
EASSERT(path != NULL);
EASSERT(dsett != NULL);
/*
* Prevent cases 'set_wallpaper(dsett->wp_path.c_str())' since assignement
* will nullify pointers. Very hard to find bug! (believe me, after few hours)
*/
if(dsett->wp_path.c_str() != path)
dsett->wp_path = path;
dsett->wp_image = fltk::SharedImage::get(path);
/*
* SharedImage::get() will return NULL if is unable to read the image
* and that is exactly what is wanted here since draw() function will
* skip drawing image in nulled case. Blame user for this :)
*/
image(dsett->wp_image);
if(do_redraw)
redraw();
}
void Desktop::set_wallpaper(fltk::Image* im, bool do_redraw) {
if(dsett->wp_image == im)
return;
image(dsett->wp_image);
if(do_redraw) if(do_redraw)
redraw(); redraw();
} }
@ -255,7 +167,7 @@ void Desktop::set_wallpaper(fltk::Image* im, bool do_redraw) {
void Desktop::read_config(void) { void Desktop::read_config(void) {
edelib::Config conf; edelib::Config conf;
if(!conf.load(CONFIG_NAME)) { if(!conf.load(CONFIG_NAME)) {
EDEBUG(ESTRLOC ": Can't load %s, using default...\n", CONFIG_NAME); EWARNING(ESTRLOC ": Can't load %s, using default...\n", CONFIG_NAME);
return; return;
} }
@ -264,20 +176,17 @@ void Desktop::read_config(void) {
* Add IconArea[X,Y,W,H] so icons can live * Add IconArea[X,Y,W,H] so icons can live
* inside that area only (aka margins). * inside that area only (aka margins).
*/ */
int default_bg_color = FL_BLUE;
// read Desktop section
int default_bg_color = fltk::BLUE;
int default_wp_use = false; int default_wp_use = false;
char wpath[256]; char wpath[256];
// read Desktop section
conf.get("Desktop", "Color", dsett->color, default_bg_color); conf.get("Desktop", "Color", dsett->color, default_bg_color);
if(conf.error() != edelib::CONF_ERR_SECTION) { if(conf.error() != edelib::CONF_ERR_SECTION) {
conf.get("Desktop", "WallpaperUse", dsett->wp_use, default_wp_use); conf.get("Desktop", "WallpaperUse", dsett->wp_use, default_wp_use);
conf.get("Desktop", "Wallpaper", wpath, sizeof(wpath)); conf.get("Desktop", "Wallpaper", wpath, sizeof(wpath));
dsett->wp_path = wpath;
// keep path but disable wallpaper if file does not exists // keep path but disable wallpaper if file does not exists
if(!edelib::file_exists(wpath)) { if(!edelib::file_exists(wpath)) {
EDEBUG(ESTRLOC ": %s as wallpaper does not exists\n", wpath); EDEBUG(ESTRLOC ": %s as wallpaper does not exists\n", wpath);
@ -289,15 +198,14 @@ void Desktop::read_config(void) {
} }
// read Icons section // read Icons section
conf.get("Icons", "Label Background", gisett.label_background, 46848); conf.get("Icons", "Label Background", gisett.label_background, FL_BLUE);
conf.get("Icons", "Label Foreground", gisett.label_foreground, fltk::WHITE); conf.get("Icons", "Label Foreground", gisett.label_foreground, FL_WHITE);
conf.get("Icons", "Label Fontsize", gisett.label_fontsize, 12); conf.get("Icons", "Label Fontsize", gisett.label_fontsize, 12);
conf.get("Icons", "Label Maxwidth", gisett.label_maxwidth, 75); conf.get("Icons", "Label Maxwidth", gisett.label_maxwidth, 75);
conf.get("Icons", "Label Transparent",gisett.label_transparent, false); conf.get("Icons", "Label Transparent",gisett.label_transparent, false);
conf.get("Icons", "Label Visible", gisett.label_draw, true); conf.get("Icons", "Label Visible", gisett.label_draw, true);
conf.get("Icons", "Gridspacing", gisett.gridspacing, 16);
conf.get("Icons", "OneClickExec", gisett.one_click_exec, false); conf.get("Icons", "OneClickExec", gisett.one_click_exec, false);
conf.get("Icons", "AutoArrange", gisett.auto_arr, true); conf.get("Icons", "AutoArrange", gisett.auto_arrange, true);
/* /*
* Now try to load icons, first looking inside ~/Desktop directory * Now try to load icons, first looking inside ~/Desktop directory
@ -306,25 +214,17 @@ void Desktop::read_config(void) {
* *
* FIXME: dir_exists() can't handle '~/Desktop' ??? * FIXME: dir_exists() can't handle '~/Desktop' ???
*/ */
//load_icons("/home/sanel/Desktop", conf);
edelib::String dd = edelib::dir_home(); edelib::String dd = edelib::dir_home();
if(dd.empty()) {
EWARNING(ESTRLOC ": Can't read home directory; icons will not be loaded\n");
return;
}
dd += "/Desktop"; dd += "/Desktop";
load_icons(dd.c_str(), conf); load_icons(dd.c_str(), conf);
}
#if 0 void Desktop::save_config(void) {
EDEBUG("----------------------------------------------------------\n"); // TODO
EDEBUG("d Color : %i\n", bg_color);
EDEBUG("d WallpaperUse: %i\n", wp_use);
EDEBUG("i label bkg : %i\n", gisett.label_background);
EDEBUG("i label fg : %i\n", gisett.label_foreground);
EDEBUG("i label fsize : %i\n", gisett.label_fontsize);
EDEBUG("i label maxw : %i\n", gisett.label_maxwidth);
EDEBUG("i label trans : %i\n", gisett.label_transparent);
EDEBUG("i label vis : %i\n", gisett.label_draw);
EDEBUG("i gridspace : %i\n", gisett.gridspacing);
EDEBUG("i oneclick : %i\n", gisett.one_click_exec);
EDEBUG("i auto_arr : %i\n", gisett.auto_arr);
#endif
} }
void Desktop::load_icons(const char* path, edelib::Config& conf) { void Desktop::load_icons(const char* path, edelib::Config& conf) {
@ -372,15 +272,7 @@ void Desktop::load_icons(const char* path, edelib::Config& conf) {
} else { } else {
// then try to figure out it's mime; if fails, ignore it // then try to figure out it's mime; if fails, ignore it
if(mt.set(full_path.c_str())) { if(mt.set(full_path.c_str())) {
/* is.icon = mt.icon_name();
* FIXME: MimeType fails for directories
* Temp solution untill that is fixed in edelib
*/
if(edelib::dir_exists(full_path.c_str()))
is.icon = "folder";
else
is.icon = mt.icon_name();
// icon label is name of file // icon label is name of file
is.name = name; is.name = name;
is.type = ICON_FILE; is.type = ICON_FILE;
@ -402,13 +294,13 @@ void Desktop::load_icons(const char* path, edelib::Config& conf) {
is.x = icon_x; is.x = icon_x;
is.y = icon_y; is.y = icon_y;
DesktopIcon* dic = new DesktopIcon(&gisett, &is); DesktopIcon* dic = new DesktopIcon(&gisett, &is, dsett->color);
add_icon(dic); add_icon(dic);
} }
} }
} }
// reads .desktop file content // read .desktop files
bool Desktop::read_desktop_file(const char* path, IconSettings& is) { bool Desktop::read_desktop_file(const char* path, IconSettings& is) {
EASSERT(path != NULL); EASSERT(path != NULL);
@ -499,79 +391,50 @@ bool Desktop::read_desktop_file(const char* path, IconSettings& is) {
return true; return true;
} }
void Desktop::save_config(void) {
edelib::Config conf;
conf.set("Desktop", "Color", dsett->color);
conf.set("Desktop", "WallpaperUse", dsett->wp_use);
conf.set("Desktop", "Wallpaper", dsett->wp_path.c_str());
conf.set("Icons", "Label Background", gisett.label_background);
conf.set("Icons", "Label Foreground", gisett.label_foreground);
conf.set("Icons", "Label Fontsize", gisett.label_fontsize);
conf.set("Icons", "Label Maxwidth", gisett.label_maxwidth);
conf.set("Icons", "Label Transparent",gisett.label_transparent);
conf.set("Icons", "Label Visible", gisett.label_draw);
conf.set("Icons", "Gridspacing", gisett.gridspacing);
conf.set("Icons", "OneClickExec", gisett.one_click_exec);
conf.set("Icons", "AutoArrange", gisett.auto_arr);
unsigned int sz = icons.size();
const IconSettings* is = NULL;
for(unsigned int i = 0; i < sz; i++) {
is = icons[i]->get_settings();
conf.set(is->key_name.c_str(), "X", icons[i]->x());
conf.set(is->key_name.c_str(), "Y", icons[i]->y());
}
if(!conf.save(CONFIG_NAME))
EDEBUG(ESTRLOC ": Unable to save to %s\n", CONFIG_NAME);
}
void Desktop::add_icon(DesktopIcon* ic) { void Desktop::add_icon(DesktopIcon* ic) {
EASSERT(ic != NULL); EASSERT(ic != NULL);
icons.push_back(ic); icons.push_back(ic);
add(ic); // FIXME: validate this
} add((Fl_Widget*)ic);
void Desktop::move_selection(int x, int y, bool apply) {
unsigned int sz = selectionbuff.size();
if(sz == 0)
return;
int prev_x, prev_y, tmp_x, tmp_y;
for(unsigned int i = 0; i < sz; i++) {
prev_x = selectionbuff[i]->drag_icon_x();
prev_y = selectionbuff[i]->drag_icon_y();
tmp_x = x - selection_x;
tmp_y = y - selection_y;
selectionbuff[i]->drag(prev_x+tmp_x, prev_y+tmp_y, apply);
// very slow if is not checked
if(apply == true)
selectionbuff[i]->redraw();
}
selection_x = x;
selection_y = y;
} }
void Desktop::unfocus_all(void) { void Desktop::unfocus_all(void) {
unsigned int sz = icons.size(); unsigned int sz = icons.size();
DesktopIcon* ic;
for(unsigned int i = 0; i < sz; i++) { for(unsigned int i = 0; i < sz; i++) {
if(icons[i]->is_focused()) { ic = icons[i];
icons[i]->do_unfocus(); if(ic->is_focused()) {
icons[i]->redraw(); ic->do_unfocus();
ic->fast_redraw();
} }
} }
}
redraw(); void Desktop::select(DesktopIcon* ic) {
EASSERT(ic != NULL);
if(in_selection(ic))
return;
selectionbuff.push_back(ic);
if(!ic->is_focused()) {
ic->do_focus();
ic->fast_redraw();
}
}
void Desktop::select_only(DesktopIcon* ic) {
EASSERT(ic != NULL);
unfocus_all();
selectionbuff.clear();
selectionbuff.push_back(ic);
ic->do_focus();
ic->fast_redraw();
} }
bool Desktop::in_selection(const DesktopIcon* ic) { bool Desktop::in_selection(const DesktopIcon* ic) {
@ -586,94 +449,47 @@ bool Desktop::in_selection(const DesktopIcon* ic) {
return false; return false;
} }
void Desktop::select(DesktopIcon* ic) { void Desktop::move_selection(int x, int y, bool apply) {
EASSERT(ic != NULL); unsigned int sz = selectionbuff.size();
if(sz == 0)
if(in_selection(ic))
return; return;
selectionbuff.push_back(ic); int prev_x, prev_y, tmp_x, tmp_y;
DesktopIcon* ic;
if(!ic->is_focused()) {
ic->do_focus();
ic->redraw();
}
redraw();
}
void Desktop::select_noredraw(DesktopIcon* ic) {
EASSERT(ic != NULL);
if(in_selection(ic))
return;
selectionbuff.push_back(ic);
}
void Desktop::select_only(DesktopIcon* ic) {
EASSERT(ic != NULL);
unfocus_all();
selectionbuff.clear();
selectionbuff.push_back(ic);
ic->do_focus();
ic->redraw();
redraw();
}
void Desktop::select_in_area(void) {
if(!selbox->show)
return;
int ax = selbox->x;
int ay = selbox->y;
int aw = selbox->w;
int ah = selbox->h;
if(aw < 0) {
ax += aw;
aw = -aw;
} else if(!aw)
aw = 1;
if(ah < 0) {
ay += ah;
ah = -ah;
} else if(!ah)
ah = 1;
/*
* XXX: This function can fail since icon coordinates are absolute (event_x_root)
* but selbox use relative (event_root). It will work as expected if desktop is at x=0 y=0.
* This should be checked further.
*/
unsigned int sz = icons.size();
DesktopIcon* ic = NULL;
for(unsigned int i = 0; i < sz; i++) { for(unsigned int i = 0; i < sz; i++) {
ic = icons[i]; ic = selectionbuff[i];
EASSERT(ic != NULL && "Impossible to happen");
if(intersects(ax, ay, ax+aw, ay+ah, ic->x(), ic->y(), ic->w()+ic->x(), ic->h()+ic->y())) { prev_x = ic->drag_icon_x();
if(!ic->is_focused()) { prev_y = ic->drag_icon_y();
ic->do_focus();
ic->redraw(); tmp_x = x - selection_x;
} tmp_y = y - selection_y;
} else {
if(ic->is_focused()) { ic->drag(prev_x + tmp_x, prev_y + tmp_y, apply);
ic->do_unfocus();
ic->redraw(); // very slow if not checked
} if(apply == true)
} ic->fast_redraw();
} }
selection_x = x;
selection_y = y;
/*
* Redraw whole screen so it reflects
* new icon position
*/
if(apply)
redraw();
} }
#if 0
/* /*
* Tries to figure out icon below mouse (used for DND) * Tries to figure out icon below mouse. It is alternative to
* If fails, return NULL * Fl::belowmouse() since with this we hunt only icons, not other
* childs (wallpaper, menu), which can be returned by Fl::belowmouse()
* and bad things be hapened.
*/ */
DesktopIcon* Desktop::below_mouse(int px, int py) { DesktopIcon* Desktop::below_mouse(int px, int py) {
unsigned int sz = icons.size(); unsigned int sz = icons.size();
@ -681,129 +497,39 @@ DesktopIcon* Desktop::below_mouse(int px, int py) {
DesktopIcon* ic = NULL; DesktopIcon* ic = NULL;
for(unsigned int i = 0; i < sz; i++) { for(unsigned int i = 0; i < sz; i++) {
ic = icons[i]; ic = icons[i];
EASSERT(ic != NULL && "Impossible to happen");
if(ic->x() < px && ic->y() < py && px < (ic->x() + ic->h()) && py < (ic->y() + ic->h())) if(ic->x() < px && ic->y() < py && px < (ic->x() + ic->h()) && py < (ic->y() + ic->h()))
return ic; return ic;
} }
return NULL; return NULL;
} }
// used to drop dnd context on desktop figuring out what it can be
void Desktop::drop_source(const char* src, int x, int y) {
if(!src)
return;
IconSettings is;
is.x = x;
is.y = y;
// absolute path we (for now) see as non-url
if(src[0] == '/')
is.cmd_is_url = false;
else
is.cmd_is_url = true;
is.name = "XXX";
is.cmd = "(none)";
is.type = ICON_NORMAL;
edelib::MimeType mt;
if(!mt.set(src)) {
EDEBUG("MimeType for %s failed, not dropping icon\n", src);
return;
}
is.icon = mt.icon_name();
EDEBUG("---------> %s\n", is.icon.c_str());
DesktopIcon* dic = new DesktopIcon(&gisett, &is);
add_icon(dic);
}
void Desktop::draw(void) {
#if 0
if(damage() & fltk::DAMAGE_ALL) {
fltk::Window::draw();
}
#endif #endif
if(damage() & fltk::DAMAGE_ALL) {
clear_flag(fltk::HIGHLIGHT);
int nchild = children();
if(damage() & ~fltk::DAMAGE_CHILD) {
draw_box();
draw_label();
for(int i = 0; i < nchild; i++) {
fltk::Widget& ch = *child(i);
draw_child(ch);
draw_outside_label(ch);
}
} else {
for(int i = 0; i < nchild; i++) {
fltk::Widget& ch = *child(i);
if(ch.damage() & fltk::DAMAGE_CHILD_LABEL) {
draw_outside_label(ch);
ch.set_damage(ch.damage() & ~fltk::DAMAGE_CHILD_LABEL);
}
update_child(ch);
}
}
}
if(damage() & (fltk::DAMAGE_ALL|EDAMAGE_OVERLAY)) {
clear_xoverlay();
if(selbox->show)
draw_xoverlay(selbox->x, selbox->y, selbox->w, selbox->h);
/*
* now scan all icons and see if they needs redraw, and if do
* just update their label since it is indicator of selection
*/
for(int i = 0; i < children(); i++) {
if(child(i)->damage() == fltk::DAMAGE_ALL) {
child(i)->set_damage(fltk::DAMAGE_CHILD_LABEL);
update_child(*child(i));
}
}
}
}
int Desktop::handle(int event) { int Desktop::handle(int event) {
switch(event) { switch(event) {
case fltk::FOCUS: case FL_FOCUS:
case fltk::UNFOCUS: case FL_UNFOCUS:
return 1; return 1;
case fltk::PUSH: { case FL_PUSH: {
/* /*
* First check where we clicked. If we do it on desktop * First check where we clicked. If we do it on desktop
* unfocus any possible focused childs, and handle * unfocus any possible focused childs, and handle
* specific clicks. Otherwise, do rest for childs. * specific clicks. Otherwise, do rest for childs.
*/ */
fltk::Widget* clicked = fltk::belowmouse(); Fl_Widget* clicked = Fl::belowmouse();
EDEBUG(ESTRLOC ": %i\n", fltk::event_button());
if(clicked == this) { if(NOT_SELECTABLE(clicked)) {
unfocus_all();
EDEBUG(ESTRLOC ": DESKTOP CLICK !!!\n"); EDEBUG(ESTRLOC ": DESKTOP CLICK !!!\n");
if(!selectionbuff.empty()) {
if(!selectionbuff.empty()) /*
* only focused are in selectionbuff, so this is
* fine to do; also will prevent full redraw when
* is clicked on desktop
*/
unfocus_all();
selectionbuff.clear(); selectionbuff.clear();
if(fltk::event_button() == 3)
pmenu->popup();
// track position so moving can be deduced
if(fltk::event_button() == 1) {
selbox->x = fltk::event_x();
selbox->y = fltk::event_y();
} }
return 1; return 1;
} }
@ -818,15 +544,13 @@ int Desktop::handle(int event) {
return 1; return 1;
if(SELECTION_MULTI) { if(SELECTION_MULTI) {
fltk::event_is_click(0); Fl::event_is_click(0);
select(tmp_icon); select(tmp_icon);
return 1; return 1;
} else if (SELECTION_SINGLE) { } else if(SELECTION_SINGLE) {
if(!in_selection(tmp_icon)) if(!in_selection(tmp_icon))
select_only(tmp_icon); select_only(tmp_icon);
} else if(Fl::event_button() == 3)
} else if (fltk::event_button() == 3)
select_only(tmp_icon); select_only(tmp_icon);
/* /*
@ -834,157 +558,79 @@ int Desktop::handle(int event) {
* Also prevent click on other mouse buttons during move. * Also prevent click on other mouse buttons during move.
*/ */
if(!moving) if(!moving)
tmp_icon->handle(fltk::PUSH); tmp_icon->handle(FL_PUSH);
selection_x = fltk::event_x_root(); EDEBUG(ESTRLOC ": FL_PUSH from desktop\n");
selection_y = fltk::event_y_root(); selection_x = Fl::event_x_root();
EDEBUG(ESTRLOC ": fltk::PUSH from desktop\n"); selection_y = Fl::event_y_root();
return 1; return 1;
} }
case fltk::DRAG: case FL_DRAG:
moving = true; moving = true;
if(!selectionbuff.empty()) { if(!selectionbuff.empty()) {
EDEBUG(ESTRLOC ": DRAG icon from desktop\n"); EDEBUG(ESTRLOC ": DRAG icon from desktop\n");
move_selection(fltk::event_x_root(), fltk::event_y_root(), false); move_selection(Fl::event_x_root(), Fl::event_y_root(), false);
} else { } else {
EDEBUG(ESTRLOC ": DRAG from desktop\n"); EDEBUG(ESTRLOC ": DRAG from desktop\n");
/*
* Moving is started with pushed button.
* From this point selection box is created and is rolled until release
*/
if(selbox->x != 0 || selbox->y != 0) {
selbox->w = fltk::event_x() - selbox->x;
selbox->h = fltk::event_y() - selbox->y;
selbox->show = true;
// see if there some icons inside selection area
select_in_area();
// redraw selection box
redraw(EDAMAGE_OVERLAY);
}
} }
return 1; return 1;
case fltk::RELEASE: case FL_RELEASE:
EDEBUG(ESTRLOC ": RELEASE from desktop\n"); EDEBUG(ESTRLOC ": RELEASE from desktop\n");
EDEBUG(ESTRLOC ": clicks: %i\n", fltk::event_is_click()); EDEBUG(ESTRLOC ": clicks: %i\n", Fl::event_is_click());
if(selbox->show) {
selbox->x = selbox->y = selbox->w = selbox->h = 0;
selbox->show = false;
redraw(EDAMAGE_OVERLAY);
/*
* Now pickup those who are in is_focused() state.
* Here is not used select() since it will fill selectionbuff with
* redrawing whole window each time. This is not what we want.
*
* Possible flickers due overlay will be later removed when is
* called move_selection(), which will in turn redraw icons again
* after position them.
*/
if(!selectionbuff.empty())
selectionbuff.clear();
for(unsigned int i = 0; i < icons.size(); i++) {
if(icons[i]->is_focused())
select_noredraw(icons[i]);
}
return 1;
}
if(!selectionbuff.empty() && moving) if(!selectionbuff.empty() && moving)
move_selection(fltk::event_x_root(), fltk::event_y_root(), true); move_selection(Fl::event_x_root(), Fl::event_y_root(), true);
/* /*
* Do not send fltk::RELEASE during move * Do not send FL_RELEASE during move
* *
* TODO: should be alowed fltk::RELEASE to multiple icons? (aka. run * TODO: should be alowed FL_RELEASE to multiple icons? (aka. run
* command for all selected icons ? * command for all selected icons ?
*/ */
if(selectionbuff.size() == 1 && !moving) if(selectionbuff.size() == 1 && !moving)
selectionbuff[0]->handle(fltk::RELEASE); selectionbuff[0]->handle(FL_RELEASE);
moving = false; moving = false;
return 1; return 1;
case fltk::DND_ENTER:
case fltk::DND_DRAG:
case fltk::DND_LEAVE:
return 1;
case fltk::DND_RELEASE: {
// fltk::belowmouse() can't be used within DND context :)
DesktopIcon* di = below_mouse(fltk::event_x_root(), fltk::event_y_root());
if(di) {
di->handle(event);
} else {
EDEBUG("DND on DESKTOP\n");
}
return 1;
}
case fltk::PASTE: {
DesktopIcon* di = below_mouse(fltk::event_x_root(), fltk::event_y_root());
if(di) {
di->handle(event);
} else {
EDEBUG("PASTE on desktop with %s\n", fltk::event_text());
drop_source(fltk::event_text(), fltk::event_x_root(), fltk::event_y_root());
}
}
return 1;
default: default:
break; break;
} }
return fltk::Window::handle(event); return Fl_Window::handle(event);
}
/*
* This function is executed before desktop is actually showed
* but after is internally created so net_make_me_desktop() specific code can
* be executed correctly.
*
* Calling net_make_me_desktop() after show() will confuse many wm's which will
* in turn partialy register us as desktop type.
*/
void Desktop::create(void) {
fltk::Window::create();
net_make_me_desktop(this);
} }
int main() { int main() {
signal(SIGTERM, exit_signal); signal(SIGTERM, exit_signal);
signal(SIGKILL, exit_signal); signal(SIGKILL, exit_signal);
signal(SIGINT, exit_signal); signal(SIGINT, exit_signal);
signal(SIGHUP, restart_signal);
srand(time(NULL)); srand(time(NULL));
// TODO: init_locale_support() // a lot of preparing code depends on this
fl_open_display();
fl_register_images();
//edelib::IconTheme::init("crystalsvg");
edelib::IconTheme::init("edeneu"); edelib::IconTheme::init("edeneu");
fltk::register_images();
Desktop::init(); Desktop::init();
Desktop::instance()->show(); Desktop::instance()->show();
/* /*
* XSelectInput will redirect PropertyNotify messages, which * XSelectInput will redirect PropertyNotify messages, which
* we are listen for * are listened for
*/ */
XSelectInput(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), PropertyChangeMask | StructureNotifyMask ); XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask );
fltk::add_event_handler(desktop_xmessage_handler); Fl::add_handler(desktop_xmessage_handler);
while(running) while(running)
fltk::wait(); Fl::wait();
Desktop::shutdown(); Desktop::shutdown();
edelib::IconTheme::shutdown(); edelib::IconTheme::shutdown();

View File

@ -13,18 +13,19 @@
#ifndef __EICONMAN_H__ #ifndef __EICONMAN_H__
#define __EICONMAN_H__ #define __EICONMAN_H__
#include <fltk/Window.h> #include <FL/Fl_Window.h>
#include <fltk/PopupMenu.h> #include <FL/Fl_Double_Window.h>
#include <fltk/Image.h> #include <FL/Fl_Image.h>
#include <edelib/String.h> #include <edelib/String.h>
#include <edelib/Config.h> #include <edelib/Config.h>
#include <edelib/Vector.h> #include <edelib/Vector.h>
#define EDAMAGE_LABEL 0x20
struct DesktopSettings { struct DesktopSettings {
int color; // background color int color; // background color
bool wp_use; // use wallpaper or not bool wp_use; // use wallpaper or not
fltk::Image* wp_image; // wallpaper image (can be NULL)
edelib::String wp_path; // wallpaper path
}; };
struct GlobalIconSettings { struct GlobalIconSettings {
@ -32,11 +33,10 @@ struct GlobalIconSettings {
int label_foreground; int label_foreground;
int label_fontsize; int label_fontsize;
int label_maxwidth; int label_maxwidth;
int gridspacing;
bool label_transparent; bool label_transparent;
bool label_draw; bool label_draw;
bool one_click_exec; bool one_click_exec;
bool auto_arr; bool auto_arrange;
bool same_size; bool same_size;
}; };
@ -53,8 +53,8 @@ struct GlobalIconSettings {
* - symlink in ~/Desktop directory pointing to the real file * - symlink in ~/Desktop directory pointing to the real file
*/ */
struct IconSettings { struct IconSettings {
int x, y; int x, y;
int type; int type; // ICON_NORMAL, ICON_TRASH,...
bool cmd_is_url; // interpret cmd as url, like system:/,trash:/,$HOME bool cmd_is_url; // interpret cmd as url, like system:/,trash:/,$HOME
edelib::String name; edelib::String name;
@ -64,79 +64,59 @@ struct IconSettings {
edelib::String key_name; // name used as key when storing positions edelib::String key_name; // name used as key when storing positions
}; };
// selection overlay class Wallpaper;
struct SelectionOverlay {
int x, y, w, h;
bool show;
};
class DesktopIcon; class DesktopIcon;
typedef edelib::vector<DesktopIcon*> DesktopIconList; typedef edelib::vector<DesktopIcon*> DesktopIconList;
class Desktop : public fltk::Window { class Desktop : public Fl_Window {
private: private:
static Desktop* pinstance; static Desktop* pinstance;
int desktops_num; int selection_x, selection_y;
int curr_desktop;
int bg_color;
bool wp_use;
bool moving; bool moving;
int selection_x;
int selection_y;
SelectionOverlay* selbox;
GlobalIconSettings gisett; GlobalIconSettings gisett;
IconSettings isett;
DesktopSettings* dsett; DesktopSettings* dsett;
Wallpaper* wallpaper;
DesktopIconList icons; DesktopIconList icons;
DesktopIconList selectionbuff; DesktopIconList selectionbuff;
fltk::PopupMenu* pmenu;
void init_desktops(void);
void load_icons(const char* path, edelib::Config& conf); void load_icons(const char* path, edelib::Config& conf);
bool read_desktop_file(const char* path, IconSettings& is); bool read_desktop_file(const char* path, IconSettings& is);
void add_icon(DesktopIcon* ic); void add_icon(DesktopIcon* ic);
void unfocus_all(void); void unfocus_all(void);
void select(DesktopIcon* ic); void select(DesktopIcon* ic);
void select_only(DesktopIcon* ic); void select_only(DesktopIcon* ic);
bool in_selection(const DesktopIcon* ic); bool in_selection(const DesktopIcon* ic);
void select_in_area(void);
void select_noredraw(DesktopIcon* ic);
void move_selection(int x, int y, bool apply); void move_selection(int x, int y, bool apply);
DesktopIcon* below_mouse(int x, int y); //DesktopIcon* below_mouse(int px, int py);
void drop_source(const char* src, int x, int y);
public: public:
Desktop();
~Desktop();
virtual void show(void);
virtual void hide(void);
virtual int handle(int event);
static void init(void); static void init(void);
static void shutdown(void); static void shutdown(void);
static Desktop* instance(void); static Desktop* instance(void);
Desktop();
~Desktop();
void update_workarea(void);
void read_config(void); void read_config(void);
void save_config(void); void save_config(void);
void set_wallpaper(const char* path, bool do_redraw = true); void update_workarea(void);
void set_wallpaper(fltk::Image* im, bool do_redraw = true); void set_bg_color(int c, bool do_redraw = true);
void set_bg_color(unsigned int c, bool do_redraw = true);
void create(void); Fl_Window* desktop_window(void) { return this; }
virtual void draw(void);
virtual int handle(int event);
}; };
#endif #endif

View File

@ -1,87 +1,56 @@
# data file for the FLTK User Interface Designer (FLUID) # data file for the Fltk User Interface Designer (fluid)
version 2.1000 version 1.0108
images_dir fltk::Choice
header_name {.h} header_name {.h}
code_name {.cxx} code_name {.cxx}
gridx 5 Function {} {open
gridy 5
snap 1
Function {} {open selected
} { } {
{fltk::Window} {} {open Fl_Window {} {open selected
xywh {363 251 540 260} resizable visible xywh {416 256 540 260} type Double resizable visible
} { } {
{fltk::InvisibleBox} {} { Fl_Box {} {
xywh {75 173 100 15} box BORDER_BOX xywh {75 173 100 15} box BORDER_BOX
} }
{fltk::InvisibleBox} {} { Fl_Box {} {
xywh {20 20 210 158} box THIN_UP_BOX xywh {20 20 210 158} box THIN_UP_BOX
} }
{fltk::InvisibleBox} {} { Fl_Box {} {
xywh {30 30 190 138} box DOWN_BOX color 56 xywh {33 30 184 138} box DOWN_BOX color 56
code0 {/* box size is intentionaly odd so preserve aspect ratio */}
} }
{fltk::InvisibleBox} {} { Fl_Box {} {
xywh {50 183 145 14} box THIN_UP_BOX xywh {50 183 145 14} box THIN_UP_BOX
} }
{fltk::Choice} {} { Fl_Input {} {
label {Desktop:} open
xywh {310 20 220 25}
} {}
{fltk::CheckButton} {} {
label {Use wallpaper}
xywh {310 60 20 19} align 8
}
{fltk::Input} {} {
label {Image:} label {Image:}
xywh {310 94 190 25} xywh {310 55 190 25}
} }
{fltk::Button} {} { Fl_Button {} {
label {...} label {...}
xywh {505 94 25 25} xywh {505 55 25 25}
} }
{fltk::Choice} {} { Fl_Choice {} {
label {Mode:} open label {Mode:} open
xywh {310 129 220 24} xywh {310 91 220 24} down_box BORDER_BOX
} {} } {}
{fltk::Button} {} { Fl_Button {} {
label {Background color} label {Background color}
xywh {310 173 25 24} align 8 color 0x3ca700 xywh {310 136 25 24} color 73 align 8
} }
{fltk::Button} {} { Fl_Button {} {
label {&OK} label {&OK}
xywh {250 227 90 25} xywh {250 227 90 25}
} }
{fltk::Button} {} { Fl_Button {} {
label {&Apply} label {&Apply}
xywh {345 227 90 25} xywh {345 227 90 25}
} }
{fltk::Button} {} { Fl_Button {} {
label {&Cancel} label {&Cancel}
xywh {440 227 90 25} xywh {440 227 90 25}
} }
{fltk::Group} {} {open Fl_Check_Button {} {
xywh {20 210 210 40} label { Use wallpaper}
} { xywh {310 20 220 25} down_box DOWN_BOX
{fltk::InvisibleBox} {} {
xywh {15 5 35 30} box THIN_DOWN_BOX color 0xffff0000
}
{fltk::Button} {} {
label {@<}
xywh {0 5 10 30} box FLAT_BOX
}
{fltk::Button} {} {
label {@>}
xywh {200 5 10 30} box FLAT_BOX
}
{fltk::InvisibleBox} {} {
xywh {55 5 35 30} box THIN_DOWN_BOX color 0x49a47d00
}
{fltk::InvisibleBox} {} {
xywh {95 5 35 30} box THIN_DOWN_BOX color 0x3a488800
}
{fltk::InvisibleBox} {} {
xywh {135 5 35 30} box THIN_DOWN_BOX color 0x808b3f00
}
} }
} }
} }