diff --git a/eiconman/DesktopConfig.cpp b/eiconman/DesktopConfig.cpp deleted file mode 100644 index cdc9d10..0000000 --- a/eiconman/DesktopConfig.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include - -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()); -} diff --git a/eiconman/DesktopConfig.h b/eiconman/DesktopConfig.h deleted file mode 100644 index 02f6eea..0000000 --- a/eiconman/DesktopConfig.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include - -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 diff --git a/eiconman/DesktopIcon.cpp b/eiconman/DesktopIcon.cpp index 692dc58..5b561a3 100644 --- a/eiconman/DesktopIcon.cpp +++ b/eiconman/DesktopIcon.cpp @@ -12,63 +12,50 @@ #include "DesktopIcon.h" #include "eiconman.h" +#include "Utils.h" + +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include // Pixmap - -// fuck ! -#define Window XWindow - #include -#undef Window - -// default icon size +// minimal icon size #define ICONSIZE 48 // spaces around box in case of large/small icons #define OFFSET_W 16 #define OFFSET_H 16 -void icon_delete_cb(fltk::Widget*, void* di) { - DesktopIcon* dicon = (DesktopIcon*)di; - edelib::ask(_("Delete '%s' ?"), dicon->label()); -} +// label offset from icon y()+h(), so selection box can be drawn nicely +#define LABEL_OFFSET 2 -DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) : - fltk::Widget(isett->x, isett->y, ICONSIZE, ICONSIZE), settings(NULL) -{ - EASSERT(gisett != NULL); EASSERT(isett != NULL); +DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) : + Fl_Button(is->x, is->y, ICONSIZE, ICONSIZE) { + + EASSERT(gs != NULL); lwidth = lheight = 0; focus = false; - micon = false; - - image_w = image_h = ICONSIZE; + micon = NULL; /* * 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; + globals = gs; 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; + settings->name = is->name; + settings->cmd = is->cmd; + settings->icon = is->icon; + settings->type = is->type; + settings->key_name= is->key_name; // 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()) { const char* nn = settings->icon.c_str(); - edelib::IconSizes isize = edelib::ICON_SIZE_MEDIUM; - edelib::String ipath = edelib::IconTheme::get(nn, isize); + edelib::String ipath = edelib::IconTheme::get(nn, edelib::ICON_SIZE_MEDIUM); + Fl_Image* img = Fl_Shared_Image::get(ipath.c_str()); + if(img) { + int img_w = img->w(); + int img_h = img->h(); - /* - * 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 box if icon is larger + if(img_w > ICONSIZE || img_h > ICONSIZE) + size(img_w + OFFSET_W, img_h + OFFSET_H); - resize(image_w + OFFSET_W, image_h + OFFSET_H); - } - - nn = ipath.c_str(); - image(fltk::SharedImage::get(nn)); + image(img); + } else + EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str()); } - +/* 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()); +*/ + //Use desktop color as color for icon background + color(bg); - align(fltk::ALIGN_WRAP); + align(FL_ALIGN_WRAP); 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() -{ - if(settings) { - EDEBUG(ESTRLOC ": IconSettings clearing from ~DesktopIcon()\n"); - delete settings; - } +DesktopIcon::~DesktopIcon() { + EDEBUG("DesktopIcon::~DesktopIcon()\n"); + if(settings) + delete settings; if(micon) delete micon; - - if(pmenu) - delete pmenu; } void DesktopIcon::update_label_size(void) { lwidth = globals->label_maxwidth; 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); - fltk::measure(label(), lwidth, lheight, flags()); + fl_measure(label(), lwidth, lheight, align()); lwidth += 8; lheight += 4; @@ -172,7 +128,7 @@ void DesktopIcon::drag(int x, int y, bool apply) { if(apply) { position(micon->x(), micon->y()); delete micon; - micon = 0; + micon = NULL; } } @@ -180,7 +136,7 @@ void DesktopIcon::drag(int x, int y, bool apply) { int DesktopIcon::drag_icon_x(void) { if(!micon) return x(); - else + else return micon->x(); } @@ -192,130 +148,94 @@ int DesktopIcon::drag_icon_y(void) { return micon->y(); } -void DesktopIcon::draw(void) { - if(image() && (damage() & fltk::DAMAGE_ALL)) { - 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); +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) { + //draw_box(FL_UP_BOX, FL_BLACK); + + if(image() && (damage() & FL_DAMAGE_ALL)) { + Fl_Image* im = image(); + + // center image in the box + int ix = (w()/2) - (im->w()/2); + int iy = (h()/2) - (im->h()/2); + ix += x(); + iy += y(); + + im->draw(ix, iy); } - if(globals->label_draw && (damage() & (fltk::DAMAGE_ALL | fltk::DAMAGE_CHILD_LABEL))) { - int X = w()-(w()/2)-(lwidth/2); - int Y = h()+2; + if(globals->label_draw && (damage() & (FL_DAMAGE_ALL))) { + int X = x() + w()-(w()/2)-(lwidth/2); + int Y = y() + h() + LABEL_OFFSET; + + Fl_Color old = fl_color(); if(!globals->label_transparent) { - fltk::setcolor(globals->label_background); - fltk::fillrect(X, Y, lwidth, lheight); + fl_color(globals->label_background); + fl_rectf(X, Y, lwidth, lheight); } - Rectangle r(X, Y, lwidth, lheight); - - fltk::setcolor(globals->label_foreground); - drawtext(label(), r, flags()); + fl_color(globals->label_foreground); + fl_draw(label(), X, Y, lwidth, lheight, align(), 0, 0); if(is_focused()) { /* * draw focused box on our way so later * 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); - 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(); + fl_push_matrix(); + fl_begin_loop(); + fl_vertex(X,Y); + fl_vertex(X+lwidth,Y); + fl_vertex(X+lwidth,Y+lheight); + fl_vertex(X,Y+lheight); + fl_vertex(X,Y); + fl_end_loop(); + fl_pop_matrix(); // 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) { - switch(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); + return Fl_Button::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); set_override(); - create(); + color(ic->color()); - fltk::Image* img = icon->icon_image(); - if(img) - image(img); + begin(); + icon_box = new Fl_Box(0, 0, w(), h()); + icon_box->image(ic->icon_image()); + end(); +} + +MovableIcon::~MovableIcon() { +} + +void MovableIcon::show(void) { + if(!shown()) + Fl_X::make_xid(this); #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 - } + Pixmap mask = create_mask((Fl_RGB_Image*)icon->icon_image()); + XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet); #endif } - -MovableIcon::~MovableIcon() -{ -} diff --git a/eiconman/DesktopIcon.h b/eiconman/DesktopIcon.h index 57b539e..feb111f 100644 --- a/eiconman/DesktopIcon.h +++ b/eiconman/DesktopIcon.h @@ -13,16 +13,17 @@ #ifndef __DESKTOPICON_H__ #define __DESKTOPICON_H__ -#include -#include -#include -#include +#include +#include +#include +#include +#include class GlobalIconSettings; class IconSettings; class MovableIcon; -class DesktopIcon : public fltk::Widget { +class DesktopIcon : public Fl_Button { private: IconSettings* settings; const GlobalIconSettings* globals; @@ -31,24 +32,33 @@ class DesktopIcon : public fltk::Widget { int lheight; bool focus; - // pseudosizes (nor real icon sizes) - int image_w; - int image_h; - - fltk::PopupMenu* pmenu; MovableIcon* micon; void update_label_size(void); public: - DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett); + DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett, int bg); ~DesktopIcon(); + virtual void draw(void); virtual int handle(int event); + void drag(int x, int y, bool apply); int drag_icon_x(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 * messy fltk one. Focus/unfocus is handled from Desktop. @@ -57,19 +67,20 @@ class DesktopIcon : public fltk::Widget { void do_unfocus(void) { focus = false; } 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; } }; - -class MovableIcon : public fltk::Window { +class MovableIcon : public Fl_Window { private: DesktopIcon* icon; + Fl_Box* icon_box; public: MovableIcon(DesktopIcon* i); ~MovableIcon(); + virtual void show(void); }; #endif diff --git a/eiconman/Jamfile b/eiconman/Jamfile index 3fec11a..1a04e0b 100644 --- a/eiconman/Jamfile +++ b/eiconman/Jamfile @@ -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 -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 ; diff --git a/eiconman/Utils.cpp b/eiconman/Utils.cpp index 8bce1e5..80d8bd2 100644 --- a/eiconman/Utils.cpp +++ b/eiconman/Utils.cpp @@ -12,9 +12,11 @@ #include "Utils.h" #include // CARD32 -#include +#include #include +#include // strrchr + Atom NET_WORKAREA = 0; Atom NET_WM_WINDOW_TYPE = 0; Atom NET_WM_WINDOW_TYPE_DESKTOP = 0; @@ -27,20 +29,22 @@ int overlay_y = 0; int overlay_w = 0; int overlay_h = 0; +Fl_Window* overlay_drawable = NULL; + char dash_list[] = {1}; bool net_get_workarea(int& x, int& y, int& w, int &h) { Atom real; if(!NET_WORKAREA) - NET_WORKAREA= XInternAtom(fltk::xdisplay, "_NET_WORKAREA", 1); + NET_WORKAREA= XInternAtom(fl_display, "_NET_WORKAREA", 1); int format; unsigned long n, extra; unsigned char* prop; 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); if(status != Success) @@ -60,18 +64,18 @@ bool net_get_workarea(int& x, int& y, int& w, int &h) { return false; } -void net_make_me_desktop(fltk::Window* w) { +void net_make_me_desktop(Fl_Window* w) { 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) - 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; * make sure it is shown */ - EASSERT(fltk::xid(w)); + EASSERT(fl_xid(w)); /* * 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) */ - 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)); } int net_get_workspace_count(void) { 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; int format; unsigned long n, extra; 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, (unsigned char**)&prop); @@ -108,13 +112,13 @@ int net_get_workspace_count(void) { // desktops are starting from 0 int net_get_current_desktop(void) { 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; int format; unsigned long n, extra; 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); if(status != Success && !prop) @@ -128,11 +132,11 @@ int net_get_current_desktop(void) { // call on this XFreeStringList(names) int net_get_workspace_names(char**& 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 ??? 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(!wnames.nitems || !wnames.value) @@ -152,14 +156,14 @@ int net_get_workspace_names(char**& names) { #if 0 int net_get_workspace_names(char** names) { - Atom nd = XInternAtom(fltk::xdisplay, "_NET_DESKTOP_NAMES", False); - Atom utf8_str = XInternAtom(fltk::xdisplay, "UTF8_STRING", False); + Atom nd = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False); + Atom utf8_str = XInternAtom(fl_display, "UTF8_STRING", False); Atom real; int format; unsigned long n, extra; 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); if(status != Success && !prop) @@ -185,16 +189,23 @@ void draw_overlay_rect(void) { if(overlay_w <= 0 || overlay_h <= 0) return; - XSetDashes(fltk::xdisplay, fltk::gc, 0, dash_list, 1); - XSetLineAttributes(fltk::xdisplay, fltk::gc, 1, LineOnOffDash, CapButt, JoinMiter); + XSetDashes(fl_display, fl_gc, 0, dash_list, 1); + XSetLineAttributes(fl_display, fl_gc, 1, LineOnOffDash, CapButt, JoinMiter); - XSetFunction(fltk::xdisplay, fltk::gc, GXxor); - XSetForeground(fltk::xdisplay, fltk::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); + XSetFunction(fl_display, fl_gc, GXxor); + XSetForeground(fl_display, fl_gc, 0xffffffff); + + 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 - 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) { @@ -230,3 +241,15 @@ void clear_xoverlay(void) { 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; +} diff --git a/eiconman/Utils.h b/eiconman/Utils.h index ba44111..8632a5b 100644 --- a/eiconman/Utils.h +++ b/eiconman/Utils.h @@ -13,15 +13,23 @@ #ifndef __UTILS_H__ #define __UTILS_H__ -#include +#include +#include + +#include // Pixmap int net_get_workspace_count(void); int net_get_current_desktop(void); 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); void draw_xoverlay(int x, int y, int w, int h); 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 diff --git a/eiconman/Wallpaper.cpp b/eiconman/Wallpaper.cpp new file mode 100644 index 0000000..efd9d73 --- /dev/null +++ b/eiconman/Wallpaper.cpp @@ -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 +#include +#include + +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); +} diff --git a/eiconman/Wallpaper.h b/eiconman/Wallpaper.h new file mode 100644 index 0000000..b6b5173 --- /dev/null +++ b/eiconman/Wallpaper.h @@ -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 +#include + +/* + * 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 diff --git a/eiconman/eiconman.conf b/eiconman/eiconman.conf index dfaae73..764a194 100644 --- a/eiconman/eiconman.conf +++ b/eiconman/eiconman.conf @@ -1,5 +1,5 @@ [Desktop] - Color = 35 + Color = 45 WallpaperUse = 0 Wallpaper = /home/foo/xxx/baz/tax diff --git a/eiconman/eiconman.cpp b/eiconman/eiconman.cpp index 6365cd6..0e9620a 100644 --- a/eiconman/eiconman.cpp +++ b/eiconman/eiconman.cpp @@ -12,60 +12,38 @@ #include "eiconman.h" #include "DesktopIcon.h" -#include "DesktopConfig.h" #include "Utils.h" +#include "Wallpaper.h" -#include #include -#include -#include -#include #include -#include -#include +#include #include +#include +#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include // CARD32 - #include // rand, srand #include // time -#include // snprintf -/* - * 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 CONFIG_NAME "eiconman.conf" - -#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 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 MIN(x,y) ((x) < (y) ? (x) : (y)) #define MAX(x,y) ((x) > (y) ? (x) : (y)) -/* - * Added since fltk DAMAGE_OVERLAY value is used in few different contexts - * and re-using it will do nothing. Yuck! - */ -#define EDAMAGE_OVERLAY 2 +// which widgets Fl::belowmouse() to skip +#define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper)) Desktop* Desktop::pinstance = NULL; -bool running = true; +bool running = false; inline unsigned int random_pos(int 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)); } +// assume fl_open_display() is called before inline void dpy_sizes(int& width, int& height) { - fltk::open_display(); - width = DisplayWidth(fltk::xdisplay, fltk::xscreen); - height = DisplayHeight(fltk::xdisplay, fltk::xscreen); + width = DisplayWidth(fl_display, fl_screen); + height = DisplayHeight(fl_display, fl_screen); } void exit_signal(int signum) { @@ -87,103 +65,43 @@ void exit_signal(int signum) { running = false; } -/* - * It is used to notify desktop when _NET_CURRENT_DESKTOP is triggered. - * 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 restart_signal(int signum) { + EDEBUG(ESTRLOC ": Restarting (got signal %d)\n", signum); } -void background_cb(fltk::Widget*, void*) { - DesktopConfig dc; - dc.run(); -} +int desktop_xmessage_handler(int event) { return 0; } -Desktop::Desktop() : fltk::Window(0, 0, 100, 100, "") -{ +Desktop::Desktop() : Fl_Window(0, 0, 100, 100, "") { + + selection_x = selection_y = 0; 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->color = 0; + dsett->color = FL_GRAY; 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(); - 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(); - - pmenu = new fltk::PopupMenu(0, 0, 450, 50); - 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); - + wallpaper = new Wallpaper(0, 0, w(), h()); + //wallpaper->set_tiled("/home/sanel/wallpapers/katesmall.jpg"); end(); - if(dsett->wp_use) - set_wallpaper(dsett->wp_path.c_str(), false); - else - set_bg_color(dsett->color, false); + read_config(); + + set_bg_color(dsett->color, false); + running = true; } -Desktop::~Desktop() { - EDEBUG(ESTRLOC ": Desktop::~Desktop()\n"); +Desktop::~Desktop() { + EDEBUG("Desktop::~Desktop()\n"); - save_config(); - - 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; + delete dsett; } void Desktop::init(void) { @@ -205,49 +123,43 @@ Desktop* Desktop::instance(void) { return Desktop::pinstance; } -void Desktop::update_workarea(void) { - int X,Y,W,H; - if(net_get_workarea(X, Y, W, H)) - resize(X,Y,W,H); +/* + * This function must be overriden so window can inform + * wm to see it as desktop. It will send data when window + * 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; 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) redraw(); } @@ -255,7 +167,7 @@ void Desktop::set_wallpaper(fltk::Image* im, bool do_redraw) { void Desktop::read_config(void) { edelib::Config conf; 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; } @@ -264,20 +176,17 @@ void Desktop::read_config(void) { * Add IconArea[X,Y,W,H] so icons can live * inside that area only (aka margins). */ - - // read Desktop section - int default_bg_color = fltk::BLUE; + int default_bg_color = FL_BLUE; int default_wp_use = false; char wpath[256]; + // read Desktop section conf.get("Desktop", "Color", dsett->color, default_bg_color); if(conf.error() != edelib::CONF_ERR_SECTION) { conf.get("Desktop", "WallpaperUse", dsett->wp_use, default_wp_use); conf.get("Desktop", "Wallpaper", wpath, sizeof(wpath)); - dsett->wp_path = wpath; - // keep path but disable wallpaper if file does not exists if(!edelib::file_exists(wpath)) { EDEBUG(ESTRLOC ": %s as wallpaper does not exists\n", wpath); @@ -289,15 +198,14 @@ void Desktop::read_config(void) { } // read Icons section - conf.get("Icons", "Label Background", gisett.label_background, 46848); - conf.get("Icons", "Label Foreground", gisett.label_foreground, fltk::WHITE); + conf.get("Icons", "Label Background", gisett.label_background, FL_BLUE); + conf.get("Icons", "Label Foreground", gisett.label_foreground, FL_WHITE); conf.get("Icons", "Label Fontsize", gisett.label_fontsize, 12); conf.get("Icons", "Label Maxwidth", gisett.label_maxwidth, 75); conf.get("Icons", "Label Transparent",gisett.label_transparent, false); 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", "AutoArrange", gisett.auto_arr, true); + conf.get("Icons", "AutoArrange", gisett.auto_arrange, true); /* * 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' ??? */ - //load_icons("/home/sanel/Desktop", conf); 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"; load_icons(dd.c_str(), conf); +} -#if 0 - EDEBUG("----------------------------------------------------------\n"); - 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::save_config(void) { + // TODO } 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 { // then try to figure out it's mime; if fails, ignore it if(mt.set(full_path.c_str())) { - /* - * 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(); - + is.icon = mt.icon_name(); // icon label is name of file is.name = name; is.type = ICON_FILE; @@ -402,13 +294,13 @@ void Desktop::load_icons(const char* path, edelib::Config& conf) { is.x = icon_x; is.y = icon_y; - DesktopIcon* dic = new DesktopIcon(&gisett, &is); + DesktopIcon* dic = new DesktopIcon(&gisett, &is, dsett->color); add_icon(dic); } } } -// reads .desktop file content +// read .desktop files bool Desktop::read_desktop_file(const char* path, IconSettings& is) { EASSERT(path != NULL); @@ -499,82 +391,53 @@ bool Desktop::read_desktop_file(const char* path, IconSettings& is) { 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) { EASSERT(ic != NULL); 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(); + DesktopIcon* ic; for(unsigned int i = 0; i < sz; i++) { - if(icons[i]->is_focused()) { - icons[i]->do_unfocus(); - icons[i]->redraw(); + ic = icons[i]; + if(ic->is_focused()) { + ic->do_unfocus(); + ic->fast_redraw(); } } - - redraw(); } -bool Desktop::in_selection(const DesktopIcon* ic) { +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) { EASSERT(ic != NULL); unsigned int sz = selectionbuff.size(); @@ -586,94 +449,47 @@ bool Desktop::in_selection(const DesktopIcon* ic) { return false; } -void Desktop::select(DesktopIcon* ic) { - EASSERT(ic != NULL); - - if(in_selection(ic)) +void Desktop::move_selection(int x, int y, bool apply) { + unsigned int sz = selectionbuff.size(); + if(sz == 0) return; - selectionbuff.push_back(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; + int prev_x, prev_y, tmp_x, tmp_y; + DesktopIcon* ic; for(unsigned int i = 0; i < sz; i++) { - ic = icons[i]; - EASSERT(ic != NULL && "Impossible to happen"); + ic = selectionbuff[i]; - if(intersects(ax, ay, ax+aw, ay+ah, ic->x(), ic->y(), ic->w()+ic->x(), ic->h()+ic->y())) { - if(!ic->is_focused()) { - ic->do_focus(); - ic->redraw(); - } - } else { - if(ic->is_focused()) { - ic->do_unfocus(); - ic->redraw(); - } - } + prev_x = ic->drag_icon_x(); + prev_y = ic->drag_icon_y(); + + tmp_x = x - selection_x; + tmp_y = y - selection_y; + + ic->drag(prev_x + tmp_x, prev_y + tmp_y, apply); + + // 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) - * If fails, return NULL + * Tries to figure out icon below mouse. It is alternative to + * 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) { unsigned int sz = icons.size(); @@ -681,129 +497,39 @@ DesktopIcon* Desktop::below_mouse(int px, int py) { DesktopIcon* ic = NULL; for(unsigned int i = 0; i < sz; 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())) return ic; } 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 - 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) { switch(event) { - case fltk::FOCUS: - case fltk::UNFOCUS: + case FL_FOCUS: + case FL_UNFOCUS: return 1; - case fltk::PUSH: { + case FL_PUSH: { /* * First check where we clicked. If we do it on desktop * unfocus any possible focused childs, and handle * specific clicks. Otherwise, do rest for childs. */ - fltk::Widget* clicked = fltk::belowmouse(); - EDEBUG(ESTRLOC ": %i\n", fltk::event_button()); - - if(clicked == this) { - unfocus_all(); + Fl_Widget* clicked = Fl::belowmouse(); + + if(NOT_SELECTABLE(clicked)) { 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(); - - 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; } @@ -818,15 +544,13 @@ int Desktop::handle(int event) { return 1; if(SELECTION_MULTI) { - fltk::event_is_click(0); + Fl::event_is_click(0); select(tmp_icon); return 1; - } else if (SELECTION_SINGLE) { - + } else if(SELECTION_SINGLE) { if(!in_selection(tmp_icon)) select_only(tmp_icon); - - } else if (fltk::event_button() == 3) + } else if(Fl::event_button() == 3) select_only(tmp_icon); /* @@ -834,157 +558,79 @@ int Desktop::handle(int event) { * Also prevent click on other mouse buttons during move. */ if(!moving) - tmp_icon->handle(fltk::PUSH); + tmp_icon->handle(FL_PUSH); - selection_x = fltk::event_x_root(); - selection_y = fltk::event_y_root(); - EDEBUG(ESTRLOC ": fltk::PUSH from desktop\n"); + EDEBUG(ESTRLOC ": FL_PUSH from desktop\n"); + selection_x = Fl::event_x_root(); + selection_y = Fl::event_y_root(); return 1; } - case fltk::DRAG: + case FL_DRAG: moving = true; - if(!selectionbuff.empty()) { 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 { 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; - case fltk::RELEASE: + case FL_RELEASE: EDEBUG(ESTRLOC ": RELEASE from desktop\n"); - EDEBUG(ESTRLOC ": clicks: %i\n", fltk::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; - } + EDEBUG(ESTRLOC ": clicks: %i\n", Fl::event_is_click()); 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 ? */ if(selectionbuff.size() == 1 && !moving) - selectionbuff[0]->handle(fltk::RELEASE); + selectionbuff[0]->handle(FL_RELEASE); moving = false; 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: break; } - return fltk::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); + return Fl_Window::handle(event); } int main() { signal(SIGTERM, exit_signal); signal(SIGKILL, exit_signal); - signal(SIGINT, exit_signal); + signal(SIGINT, exit_signal); + signal(SIGHUP, restart_signal); 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"); - fltk::register_images(); - Desktop::init(); Desktop::instance()->show(); /* * XSelectInput will redirect PropertyNotify messages, which - * we are listen for + * are listened for */ - XSelectInput(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), PropertyChangeMask | StructureNotifyMask ); - fltk::add_event_handler(desktop_xmessage_handler); + XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask ); + Fl::add_handler(desktop_xmessage_handler); while(running) - fltk::wait(); + Fl::wait(); Desktop::shutdown(); edelib::IconTheme::shutdown(); diff --git a/eiconman/eiconman.h b/eiconman/eiconman.h index dcd5d64..ca227aa 100644 --- a/eiconman/eiconman.h +++ b/eiconman/eiconman.h @@ -13,18 +13,19 @@ #ifndef __EICONMAN_H__ #define __EICONMAN_H__ -#include -#include -#include +#include +#include +#include + #include #include #include +#define EDAMAGE_LABEL 0x20 + struct DesktopSettings { int color; // background color bool wp_use; // use wallpaper or not - fltk::Image* wp_image; // wallpaper image (can be NULL) - edelib::String wp_path; // wallpaper path }; struct GlobalIconSettings { @@ -32,11 +33,10 @@ struct GlobalIconSettings { int label_foreground; int label_fontsize; int label_maxwidth; - int gridspacing; bool label_transparent; bool label_draw; bool one_click_exec; - bool auto_arr; + bool auto_arrange; bool same_size; }; @@ -53,8 +53,8 @@ struct GlobalIconSettings { * - symlink in ~/Desktop directory pointing to the real file */ struct IconSettings { - int x, y; - int type; + int x, y; + int type; // ICON_NORMAL, ICON_TRASH,... bool cmd_is_url; // interpret cmd as url, like system:/,trash:/,$HOME edelib::String name; @@ -64,79 +64,59 @@ struct IconSettings { edelib::String key_name; // name used as key when storing positions }; -// selection overlay -struct SelectionOverlay { - int x, y, w, h; - bool show; -}; - +class Wallpaper; class DesktopIcon; typedef edelib::vector DesktopIconList; -class Desktop : public fltk::Window { +class Desktop : public Fl_Window { private: static Desktop* pinstance; - int desktops_num; - int curr_desktop; - int bg_color; - bool wp_use; - + int selection_x, selection_y; bool moving; - int selection_x; - int selection_y; - - SelectionOverlay* selbox; GlobalIconSettings gisett; - IconSettings isett; - DesktopSettings* dsett; + Wallpaper* wallpaper; + DesktopIconList icons; DesktopIconList selectionbuff; - fltk::PopupMenu* pmenu; - - void init_desktops(void); - void load_icons(const char* path, edelib::Config& conf); bool read_desktop_file(const char* path, IconSettings& is); void add_icon(DesktopIcon* ic); + void unfocus_all(void); void select(DesktopIcon* ic); void select_only(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); - DesktopIcon* below_mouse(int x, int y); - void drop_source(const char* src, int x, int y); + //DesktopIcon* below_mouse(int px, int py); public: + Desktop(); + ~Desktop(); + + virtual void show(void); + virtual void hide(void); + virtual int handle(int event); + static void init(void); static void shutdown(void); static Desktop* instance(void); - Desktop(); - ~Desktop(); - void update_workarea(void); void read_config(void); void save_config(void); - void set_wallpaper(const char* path, bool do_redraw = true); - void set_wallpaper(fltk::Image* im, bool do_redraw = true); - void set_bg_color(unsigned int c, bool do_redraw = true); + void update_workarea(void); + void set_bg_color(int c, bool do_redraw = true); - void create(void); - virtual void draw(void); - virtual int handle(int event); + Fl_Window* desktop_window(void) { return this; } }; #endif diff --git a/eiconman/fl/deskconf.fl b/eiconman/fl/deskconf.fl index 136bf79..68e1a77 100644 --- a/eiconman/fl/deskconf.fl +++ b/eiconman/fl/deskconf.fl @@ -1,87 +1,56 @@ -# data file for the FLTK User Interface Designer (FLUID) -version 2.1000 -images_dir fltk::Choice +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 header_name {.h} -code_name {.cxx} -gridx 5 -gridy 5 -snap 1 -Function {} {open selected +code_name {.cxx} +Function {} {open } { - {fltk::Window} {} {open - xywh {363 251 540 260} resizable visible + Fl_Window {} {open selected + xywh {416 256 540 260} type Double resizable visible } { - {fltk::InvisibleBox} {} { + Fl_Box {} { xywh {75 173 100 15} box BORDER_BOX } - {fltk::InvisibleBox} {} { + Fl_Box {} { xywh {20 20 210 158} box THIN_UP_BOX } - {fltk::InvisibleBox} {} { - xywh {30 30 190 138} box DOWN_BOX color 56 + Fl_Box {} { + 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 } - {fltk::Choice} {} { - label {Desktop:} open - xywh {310 20 220 25} - } {} - {fltk::CheckButton} {} { - label {Use wallpaper} - xywh {310 60 20 19} align 8 - } - {fltk::Input} {} { + Fl_Input {} { label {Image:} - xywh {310 94 190 25} + xywh {310 55 190 25} } - {fltk::Button} {} { + Fl_Button {} { label {...} - xywh {505 94 25 25} + xywh {505 55 25 25} } - {fltk::Choice} {} { + Fl_Choice {} { label {Mode:} open - xywh {310 129 220 24} + xywh {310 91 220 24} down_box BORDER_BOX } {} - {fltk::Button} {} { + Fl_Button {} { 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} xywh {250 227 90 25} } - {fltk::Button} {} { + Fl_Button {} { label {&Apply} xywh {345 227 90 25} } - {fltk::Button} {} { + Fl_Button {} { label {&Cancel} xywh {440 227 90 25} } - {fltk::Group} {} {open - xywh {20 210 210 40} - } { - {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 - } + Fl_Check_Button {} { + label { Use wallpaper} + xywh {310 20 220 25} down_box DOWN_BOX } } }