diff --git a/eiconman/DesktopConfig.cpp b/eiconman/DesktopConfig.cpp index ce29c08..cdc9d10 100644 --- a/eiconman/DesktopConfig.cpp +++ b/eiconman/DesktopConfig.cpp @@ -12,6 +12,8 @@ #include "DesktopConfig.h" #include "Utils.h" +#include "eiconman.h" + #include #include #include @@ -27,15 +29,23 @@ void close_cb(fltk::Widget*, void* 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->disable_wp(); + dc->wp_disable(); } void color_box_cb(fltk::Widget*, void* w) { DesktopConfig* dc = (DesktopConfig*)w; - fltk::Color col = dc->bkg_color(); + fltk::Color col = dc->bg_color(); if(fltk::color_chooser(_("Background color"), col)) dc->set_color(col); } @@ -67,8 +77,7 @@ void PreviewBox::draw(void) { } } -DesktopConfig::DesktopConfig() : fltk::Window(540, 265, _("Background settings")) { - +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); @@ -89,18 +98,6 @@ DesktopConfig::DesktopConfig() : fltk::Window(540, 265, _("Background settings") new fltk::Item(_("All desktops")); - char** names; - int nsz = net_get_workspace_names(names); - EDEBUG("nsz: %i\n", nsz); - - if(nsz > 0) { - for(int i = 0; i < nsz; i++) { - fltk::Item* item = new fltk::Item(); - item->copy_label(names[i]); - } - - XFreeStringList(names); - } ws_names->end(); // rest @@ -127,8 +124,12 @@ DesktopConfig::DesktopConfig() : fltk::Window(540, 265, _("Background settings") color_box->align(fltk::ALIGN_RIGHT); color_box->callback(color_box_cb, this); - new fltk::Button(250, 230, 90, 25, _("&OK")); - new fltk::Button(345, 230, 90, 25, _("&Apply")); + 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(); @@ -146,7 +147,7 @@ void DesktopConfig::run(void) { fltk::wait(); } -void DesktopConfig::disable_wp(void) { +void DesktopConfig::wp_disable(void) { if(!use_wp->value()) { img_path->deactivate(); img_browse->deactivate(); @@ -156,16 +157,25 @@ void DesktopConfig::disable_wp(void) { 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) { - color_box->color(c); - color_box->redraw(); + if(c != color_box->color()) { + color_box->color(c); + color_box->redraw(); + } set_preview_color(c); } @@ -173,9 +183,12 @@ void DesktopConfig::set_color(unsigned int 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(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 index 29c1ef0..02f6eea 100644 --- a/eiconman/DesktopConfig.h +++ b/eiconman/DesktopConfig.h @@ -19,6 +19,7 @@ #include #include #include +#include #include class PreviewBox : public fltk::InvisibleBox { @@ -30,6 +31,9 @@ class PreviewBox : public fltk::InvisibleBox { 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; @@ -44,11 +48,13 @@ class DesktopConfig : public fltk::Window { ~DesktopConfig(); void run(void); - void disable_wp(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 bkg_color(void) { return color_box->color(); } + unsigned int bg_color(void) { return color_box->color(); } }; #endif diff --git a/eiconman/DesktopIcon.cpp b/eiconman/DesktopIcon.cpp index 26c2dd3..469af6e 100644 --- a/eiconman/DesktopIcon.cpp +++ b/eiconman/DesktopIcon.cpp @@ -287,6 +287,9 @@ int DesktopIcon::handle(int event) { 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); diff --git a/eiconman/eiconman.conf b/eiconman/eiconman.conf index 23cc081..a65eec8 100644 --- a/eiconman/eiconman.conf +++ b/eiconman/eiconman.conf @@ -1,9 +1,8 @@ - # general settings for desktop [Desktop] Color=35 WallpaperUse=1 - Wallpaper=/home/sanel/blentavo/EDE/art/wallpaper.png + Wallpaper=/home/sanel/wallpapers/Abaddon.png # general settings for icons on desktop [Icons] diff --git a/eiconman/eiconman.cpp b/eiconman/eiconman.cpp index a19b98e..ee22c33 100644 --- a/eiconman/eiconman.cpp +++ b/eiconman/eiconman.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ #include // rand, srand #include // time +#include // snprintf /* * NOTE: DO NOT set 'using namespace fltk' here @@ -62,6 +64,7 @@ */ #define EDAMAGE_OVERLAY 2 +Desktop* Desktop::pinstance = NULL; bool running = true; inline unsigned int random_pos(int max) { @@ -112,19 +115,26 @@ Desktop::Desktop() : fltk::Window(0, 0, 100, 100, "") { 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->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(); - color(bg_color); + read_config(); begin(); @@ -150,10 +160,14 @@ Desktop::Desktop() : fltk::Window(0, 0, 100, 100, "") pmenu->type(fltk::PopupMenu::POPUP3); end(); + + if(dsett->wp_use) + set_wallpaper(dsett->wp_path.c_str(), false); + else + set_bg_color(dsett->color, false); } -Desktop::~Desktop() -{ +Desktop::~Desktop() { EDEBUG(ESTRLOC ": Desktop::~Desktop()\n"); if(selbox) @@ -165,10 +179,28 @@ Desktop::~Desktop() * will cleanup fltk::Group array. */ icons.clear(); + + if(dsett) + delete dsett; } -void Desktop::default_gisett(void) { - // TODO +void Desktop::init(void) { + if(Desktop::pinstance != NULL) + return; + Desktop::pinstance = new Desktop(); +} + +void Desktop::shutdown(void) { + if(Desktop::pinstance == NULL) + return; + + delete Desktop::pinstance; + Desktop::pinstance = NULL; +} + +Desktop* Desktop::instance(void) { + EASSERT(Desktop::pinstance != NULL && "Desktop::init() should be run first"); + return Desktop::pinstance; } void Desktop::update_workarea(void) { @@ -177,6 +209,47 @@ void Desktop::update_workarea(void) { resize(X,Y,W,H); } +void Desktop::set_bg_color(unsigned int c, bool do_redraw) { + EASSERT(dsett != NULL); + + 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(); +} + void Desktop::read_config(void) { edelib::Config conf; if(!conf.load(CONFIG_NAME)) { @@ -191,12 +264,20 @@ void Desktop::read_config(void) { */ // read Desktop section - conf.get("Desktop", "Color", bg_color, fltk::BLUE); - conf.get("Desktop", "WallpaperUse", wp_use, false); - if(wp_use) { - char wp_path[1024]; - conf.get("Desktop", "Wallpaper", wp_path, sizeof(wp_path)); - EDEBUG(ESTRLOC ": Wallpaper %s\n", wp_path); + int default_bg_color = fltk::BLUE; + int default_wp_use = false; + char wpath[256]; + + 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; + } else { + // color is already filled + dsett->wp_use = default_wp_use; } // read Icons section @@ -319,7 +400,8 @@ bool Desktop::read_desktop_file(const char* path, IconSettings& is, int& icon_ty if(dconf.get("Desktop Entry", "EmptyIcon", buff, buffsz)) { icon_type = ICON_TRASH; is.icon = buff; - } + } else + icon_type = ICON_NORMAL; if(dconf.error() == edelib::CONF_ERR_SECTION) { EDEBUG(ESTRLOC ": %s is not valid .desktop file\n"); @@ -535,6 +617,8 @@ 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; } @@ -542,9 +626,69 @@ DesktopIcon* Desktop::below_mouse(int px, int py) { 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)"; + + 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, ICON_NORMAL); + add_icon(dic); +} + void Desktop::draw(void) { - if(damage() & fltk::DAMAGE_ALL) +#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(); @@ -597,6 +741,7 @@ int Desktop::handle(int event) { return 1; } + // from here, all events are managed for icons DesktopIcon* tmp_icon = (DesktopIcon*)clicked; @@ -666,7 +811,7 @@ int Desktop::handle(int event) { EDEBUG(ESTRLOC ": clicks: %i\n", fltk::event_is_click()); if(selbox->show) { - selbox->w = selbox->h = 0; + selbox->x = selbox->y = selbox->w = selbox->h = 0; selbox->show = false; redraw(EDAMAGE_OVERLAY); /* @@ -688,19 +833,14 @@ int Desktop::handle(int event) { return 1; } - if(!selectionbuff.empty() && moving) { - EDEBUG(ESTRLOC ": CLEARING BUFFER\n"); + if(!selectionbuff.empty() && moving) move_selection(fltk::event_x_root(), fltk::event_y_root(), true); - } /* * Do not send fltk::RELEASE during move * * TODO: should be alowed fltk::RELEASE to multiple icons? (aka. run * command for all selected icons ? - * - * TODO: or to make something like selectionbuff[0]->execute() - * so icon execute whatever it have ? */ if(selectionbuff.size() == 1 && !moving) selectionbuff[0]->handle(fltk::RELEASE); @@ -709,14 +849,10 @@ int Desktop::handle(int event) { return 1; case fltk::DND_ENTER: - EDEBUG("DND_ENTER\n"); - return 1; case fltk::DND_DRAG: - EDEBUG("DND_DRAG\n"); - return 1; case fltk::DND_LEAVE: - EDEBUG("DND_LEAVE\n"); 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()); @@ -727,8 +863,15 @@ int Desktop::handle(int event) { } return 1; } - case fltk::PASTE: - EDEBUG("PASTE on desktop with %s\n", fltk::event_text()); + 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: @@ -765,8 +908,8 @@ int main() { fltk::register_images(); - Desktop *desktop = new Desktop(); - desktop->show(); + Desktop::init(); + Desktop::instance()->show(); /* * XSelectInput will redirect PropertyNotify messages, which @@ -778,6 +921,8 @@ int main() { while(running) fltk::wait(); - delete desktop; + Desktop::shutdown(); + edelib::IconTheme::shutdown(); + return 0; } diff --git a/eiconman/eiconman.h b/eiconman/eiconman.h index 9ddb5f5..8307bfe 100644 --- a/eiconman/eiconman.h +++ b/eiconman/eiconman.h @@ -15,15 +15,16 @@ #include #include +#include #include #include #include -// settings realted to specific desktop view struct DesktopSettings { - bool wp_use; - int color; - edelib::String wallpaper; + 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 { @@ -60,9 +61,14 @@ struct SelectionOverlay { class DesktopIcon; +typedef edelib::vector DesktopIconList; + class Desktop : public fltk::Window { private: + static Desktop* pinstance; + int desktops_num; + int curr_desktop; int bg_color; bool wp_use; @@ -72,17 +78,18 @@ class Desktop : public fltk::Window { SelectionOverlay* selbox; - //DesktopSettings* dsett; - GlobalIconSettings gisett; IconSettings isett; - edelib::vector icons; - edelib::vector selectionbuff; + DesktopSettings* dsett; + + DesktopIconList icons; + DesktopIconList selectionbuff; fltk::PopupMenu* pmenu; - void default_gisett(void); + void init_desktops(void); + void load_icons(const char* path, edelib::Config& conf); bool read_desktop_file(const char* path, IconSettings& is, int& icon_type); @@ -99,13 +106,23 @@ class Desktop : public fltk::Window { 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); public: + 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 create(void); virtual void draw(void); virtual int handle(int event);