Manualy merging ede-desktop2 branch. SF merging facility (ignores valid login) sux badly.

This commit is contained in:
Sanel Zukan 2013-05-30 13:07:49 +00:00
parent 9d1f4699de
commit 5bfe346880
15 changed files with 1472 additions and 1629 deletions

840
ede-desktop/Desktop.cpp Normal file
View File

@ -0,0 +1,840 @@
/*
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <edelib/Debug.h>
#include <edelib/Netwm.h>
#include <edelib/WindowUtils.h>
#include <edelib/ForeignCallback.h>
#include <edelib/MenuItem.h>
#include <edelib/Nls.h>
#include <edelib/StrUtil.h>
#include <edelib/Directory.h>
#include <edelib/Util.h>
#include <edelib/Run.h>
#include <edelib/MessageBox.h>
#include <edelib/IconLoader.h>
#include <edelib/FileTest.h>
#include <edelib/FontCache.h>
#include <edelib/File.h>
#include "Desktop.h"
#include "DesktopIcon.h"
#include "Wallpaper.h"
#include "Utils.h"
#include "IconDialog.h"
EDELIB_NS_USING(MenuButton)
EDELIB_NS_USING(MenuItem)
EDELIB_NS_USING(String)
EDELIB_NS_USING(DesktopFile)
EDELIB_NS_USING(IconLoader)
EDELIB_NS_USING(window_xid_create)
EDELIB_NS_USING(netwm_window_set_type)
EDELIB_NS_USING(netwm_workarea_get_size)
EDELIB_NS_USING(netwm_callback_add)
EDELIB_NS_USING(foreign_callback_add)
EDELIB_NS_USING(str_ends)
EDELIB_NS_USING(dir_home)
EDELIB_NS_USING(dir_empty)
EDELIB_NS_USING(dir_remove)
EDELIB_NS_USING(build_filename)
EDELIB_NS_USING(run_async)
EDELIB_NS_USING(input)
EDELIB_NS_USING(alert)
EDELIB_NS_USING(dir_create)
EDELIB_NS_USING(file_test)
EDELIB_NS_USING(file_remove)
EDELIB_NS_USING(font_cache_find)
EDELIB_NS_USING(FILE_TEST_IS_DIR)
EDELIB_NS_USING(NETWM_WINDOW_TYPE_DESKTOP)
EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKAREA)
EDELIB_NS_USING(DESK_FILE_TYPE_UNKNOWN)
EDELIB_NS_USING(ICON_SIZE_TINY)
#define DOT_OR_DOTDOT(base) (base[0] == '.' && (base[1] == '\0' || (base[1] == '.' && base[2] == '\0')))
#define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper) || (widget == dmenu))
#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)))
#undef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#undef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define ICONS_POS_FILE "ede-desktop-icons"
static void background_conf_cb(Fl_Widget*, void*);
static void icons_conf_cb(Fl_Widget*, void*);
static void folder_create_cb(Fl_Widget*, void*);
static void launcher_create_cb(Fl_Widget*, void*);
static void arrange_icons_cb(Fl_Widget*, void*);
struct SelectionOverlay {
int x, y, w, h;
bool show;
SelectionOverlay() : x(0), y(0), w(0), h(0), show(false) { }
};
static MenuItem desktop_menu[] = {
{_("Create &launcher..."), 0, launcher_create_cb},
{_("Create &folder..."), 0, folder_create_cb, 0, FL_MENU_DIVIDER},
{_("A&rrange icons"), 0, arrange_icons_cb, 0, FL_MENU_DIVIDER},
{_("&Icons settings..."), 0, icons_conf_cb, 0},
{_("&Background..."), 0, background_conf_cb, 0},
{0}
};
inline bool intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
return (MAX(x1, x2) <= MIN(w1, w2) &&
MAX(y1, y2) <= MIN(h1, h2));
}
static void make_me_desktop(Fl_Window *win) {
netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DESKTOP);
}
static void settings_changed_cb(Fl_Window *win, void *data) {
Desktop *d = (Desktop*)win;
d->read_config();
}
static void desktop_message_handler(int action, Window xid, void *data) {
Desktop *d = (Desktop*)data;
switch(action) {
case NETWM_CHANGED_CURRENT_WORKAREA:
d->update_workarea();
break;
}
}
static void background_conf_cb(Fl_Widget*, void*) {
run_async("ede-launch ede-desktop-conf");
}
static void icons_conf_cb(Fl_Widget*, void*) {
run_async("ede-launch ede-desktop-conf --icons");
}
static void launcher_create_cb(Fl_Widget*, void* d) {
Desktop *self = (Desktop*)d;
icon_dialog_icon_create(self);
}
static void arrange_icons_cb(Fl_Widget*, void *d) {
E_RETURN_IF_FAIL(d != NULL);
Desktop *self = (Desktop*)d;
self->arrange_icons();
self->redraw();
}
static void folder_create_cb(Fl_Widget*, void *d) {
E_RETURN_IF_FAIL(d != NULL);
const char *n = input(_("Create a new folder with the name"));
if(!n) return;
Desktop *self = (Desktop*)d;
self->create_folder(n);
}
Desktop::Desktop() : EDE_DESKTOP_WINDOW(0, 0, 100, 100, EDE_DESKTOP_APP) {
end();
conf = NULL;
selbox = new SelectionOverlay;
icon_opts = NULL;
wallpaper = NULL;
dmenu = NULL;
selection_x = selection_y = 0;
last_px = last_py = -1;
moving = false;
/*
* first update workarea _then_ read configuration, as it will have correct size for
* wallpaper which will prevent wallpaper load and scalle image twice
*/
update_workarea();
read_config();
read_desktop_folder(desktop_path());
foreign_callback_add(this, EDE_DESKTOP_APP, settings_changed_cb);
dmenu = new MenuButton(0, 0, 500, 0);
dmenu->menu(desktop_menu);
desktop_menu[1].image((Fl_Image*)IconLoader::get("folder", ICON_SIZE_TINY));
desktop_menu[0].user_data(this);
desktop_menu[1].user_data(this);
desktop_menu[2].user_data(this);
add(dmenu);
}
Desktop::~Desktop() {
E_DEBUG("Desktop::~Desktop()\n");
delete conf;
delete icon_opts;
delete selbox;
}
const char *Desktop::desktop_path(void) {
if(dpath.empty())
dpath = build_filename(dir_home().c_str(), "Desktop");
return dpath.c_str();
}
void Desktop::show(void) {
if(shown()) {
EDE_DESKTOP_WINDOW::show();
return;
}
window_xid_create(this, make_me_desktop);
netwm_callback_add(desktop_message_handler, this);
}
void Desktop::update_workarea(void) {
int X, Y, W, H;
if(!netwm_workarea_get_size(X, Y, W, H))
Fl::screen_xywh(X, Y, W, H);
E_DEBUG(E_STRLOC ": resizing to %i %i %i %i\n", X, Y, W, H);
resize(X, Y, W, H);
/* also resize wallpaper if given */
if(wallpaper && wallpaper->visible())
wallpaper->resize(0, 0, w(), h());
}
void Desktop::read_config(void) {
E_DEBUG(E_STRLOC ": Reading desktop config...\n");
if(!conf) conf = new DesktopConfig();
E_RETURN_IF_FAIL(conf->load(EDE_DESKTOP_APP));
char buf[PATH_MAX];
bool wp_use = true;
int bcolor;
/* use nice darker blue color as default for background */
conf->get("Desktop", "color", bcolor, fl_rgb_color(73, 64, 102));
color(bcolor);
conf->get("Desktop", "wallpaper_use", wp_use, wp_use);
/* get wallpaper */
if(wp_use) {
if(conf->get("Desktop", "wallpaper", buf, sizeof(buf))) {
if(!wallpaper)
wallpaper = new Wallpaper(0, 0, w(), h());
int s;
bool rootpmap_use;
conf->get("Desktop", "wallpaper_mode", s, WALLPAPER_CENTER);
conf->get("Desktop", "wallpaper_rootpmap", rootpmap_use, true);
wallpaper->load(buf, s, rootpmap_use);
/*
* wallpaper is another widget, but we add it to the bottom of the list
* to preserve stacking order
*/
if(find(*wallpaper) == children())
insert(*wallpaper, 0);
/* show it in case it got hidden before */
wallpaper->show();
}
} else {
if(wallpaper) wallpaper->hide();
}
/* get options for icons */
if(!icon_opts) icon_opts = new IconOptions;
#define ICON_CONF_GET(var, fallback) conf->get("Icons", #var, icon_opts->var, fallback)
ICON_CONF_GET(label_background, FL_BLACK);
ICON_CONF_GET(label_foreground, FL_WHITE);
ICON_CONF_GET(label_maxwidth, 75);
ICON_CONF_GET(label_transparent, 1);
ICON_CONF_GET(label_visible, 1);
ICON_CONF_GET(one_click_exec, false);
if(ICON_CONF_GET(label_font, FL_HELVETICA) && ICON_CONF_GET(label_fontsize, 12))
E_WARNING(E_STRLOC ": 'label_font' && 'label_fontsize' are deprecated. Use 'label_fontname' with full font name and size instead (e.g 'sans 12')\n");
/* if found new 'label_fontname' variable, overwrite 'label_font' && 'label_fontsize' */
if(conf->get("Icons", "label_fontname", buf, sizeof(buf))) {
if(!font_cache_find(buf, (Fl_Font&)icon_opts->label_font, icon_opts->label_fontsize))
E_WARNING(E_STRLOC ": Unable to find '%s' font. Using default values...\n", buf);
}
/* sanitize */
if(icon_opts->label_font < 0) icon_opts->label_font = FL_HELVETICA;
if(icon_opts->label_fontsize < 8) icon_opts->label_fontsize = 12;
if(icon_opts->label_maxwidth < 30) icon_opts->label_maxwidth = 75;
/* doing this will redraw _all_ children, and they will in turn read modified 'icon_opts' */
if(visible()) redraw();
}
void Desktop::read_desktop_folder(const char *dpath) {
E_RETURN_IF_FAIL(dpath != NULL);
String path;
DIR *dir = opendir(dpath);
E_RETURN_IF_FAIL(dir != NULL);
DesktopConfig pos;
pos.load(ICONS_POS_FILE);
dirent *d;
while((d = readdir(dir)) != NULL) {
if(DOT_OR_DOTDOT(d->d_name))
continue;
if(d->d_type != DT_REG && d->d_type != DT_LNK && d->d_type != DT_DIR)
continue;
path = dpath;
path += E_DIR_SEPARATOR;
path += d->d_name;
DesktopIcon *o = read_desktop_file(path.c_str(), (const char*)d->d_name, &pos);
if(o) add(o);
}
closedir(dir);
}
DesktopIcon *Desktop::read_desktop_file(const char *path, const char *base, DesktopConfig *pos) {
DesktopIcon *ret = NULL;
if(file_test(path, FILE_TEST_IS_DIR)) {
ret = new DesktopIcon(_("No Name"));
ret->set_icon_type(DESKTOP_ICON_TYPE_FOLDER);
/* hardcoded */
ret->set_image("folder");
/* copy label explicitly, as DesktopIcon() will only store a pointer */
ret->copy_label(base);
} else {
/*
* try to load it as plain .desktop file by looking only at extension
* TODO: MimeType can be used here too
*/
if(!str_ends(path, ".desktop"))
return ret;
DesktopFile df;
char buf[PATH_MAX];
E_RETURN_VAL_IF_FAIL(df.load(path), ret);
E_RETURN_VAL_IF_FAIL(df.type() != DESK_FILE_TYPE_UNKNOWN, ret);
ret = new DesktopIcon(_("No Name"));
ret->set_icon_type(DESKTOP_ICON_TYPE_NORMAL);
if(df.name(buf, sizeof(buf)))
ret->copy_label(buf);
if(df.icon(buf, sizeof(buf)))
ret->set_image(buf);
else
ret->set_image(NULL);
if(df.exec(buf, sizeof(buf))) ret->set_cmd(buf);
}
/* try to put random icon position in the middle of the desktop, so it is easier to notice */
int X = (rand() % (w() / 4)) + (w() / 4);
int Y = (rand() % (h() / 4)) + (h() / 4);
/* lookup icons locations if possible */
if(base && pos && *pos) {
pos->get(base, "X", X, X);
pos->get(base, "Y", Y, Y);
}
E_DEBUG("Setting icon '%s' (%i,%i)\n", base, X, Y);
ret->position(X, Y);
/* use loaded icon options */
ret->set_options(icon_opts);
ret->set_path(path);
return ret;
}
void Desktop::arrange_icons(void) {
int lw = icon_opts ? icon_opts->label_maxwidth : 75;
int X = (lw / 5) + 10;
int Y = 10;
int H = h();
DesktopIcon *o;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
o->position(X, Y);
Y += o->h() + (o->h() / 2);
if(Y + (o->h() / 2) > H) {
Y = 10;
X += lw + (o->w() / 2);
}
}
}
bool Desktop::remove_icon(DesktopIcon *di, bool real_delete) {
bool ret = true;
if(real_delete) {
if(di->get_icon_type() == DESKTOP_ICON_TYPE_FOLDER) {
if(!dir_empty(di->get_path())) {
alert(_("This folder is not empty. Recursive removal of not empty folders is not yet implemented :S"));
return false;
}
ret = dir_remove(di->get_path());
} else {
ret = file_remove(di->get_path());
}
}
remove(di);
redraw();
return ret;
}
bool Desktop::rename_icon(DesktopIcon *di, const char *name) {
di->copy_label(name);
di->update_label_font_and_size();
di->fast_redraw();
/* open file and try to change the name */
DesktopFile df;
E_RETURN_VAL_IF_FAIL(df.load(di->get_path()) == true, false);
df.set_name(name);
return df.save(di->get_path());
}
bool Desktop::save_icons_positions(void) {
DesktopConfig pos;
DesktopIcon *o;
char *base;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
base = get_basename(o->get_path());
pos.set(base, "X", o->x());
pos.set(base, "Y", o->y());
}
return pos.save(ICONS_POS_FILE);
}
bool Desktop::create_folder(const char *name) {
String path = desktop_path();
path += E_DIR_SEPARATOR;
path += name;
if(!dir_create(path.c_str())) {
alert(_("Unable to create directory '%s'! Please check if directory already exists or you have enough permissions to create it"), path.c_str());
return false;
}
DesktopIcon *ic = read_desktop_file(path.c_str(), name);
if(ic) {
/* use mouse position so folder icon gets created where was clicked */
ic->position(last_px, last_py);
add(ic);
redraw();
}
return true;
}
void Desktop::unfocus_all(void) {
DesktopIcon *o;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
o->do_unfocus();
o->fast_redraw();
}
}
void Desktop::select(DesktopIcon *ic, bool do_redraw) {
E_ASSERT(ic != NULL);
if(in_selection(ic)) return;
selectionbuf.push_back(ic);
if(!ic->is_focused()) {
ic->do_focus();
if(do_redraw) ic->fast_redraw();
}
}
void Desktop::select_only(DesktopIcon *ic) {
E_ASSERT(ic != NULL);
unfocus_all();
selectionbuf.clear();
selectionbuf.push_back(ic);
ic->do_focus();
ic->fast_redraw();
}
bool Desktop::in_selection(const DesktopIcon* ic) {
E_ASSERT(ic != NULL);
if(selectionbuf.empty())
return false;
for(DesktopIconListIt it = selectionbuf.begin(), ite = selectionbuf.end(); it != ite; ++it) {
if((*it) == ic)
return true;
}
return false;
}
void Desktop::move_selection(int x, int y, bool apply) {
if(selectionbuf.empty()) return;
int prev_x, prev_y, tmp_x, tmp_y;
DesktopIcon *ic;
for(DesktopIconListIt it = selectionbuf.begin(), ite = selectionbuf.end(); it != ite; ++it) {
ic = (*it);
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);
}
selection_x = x;
selection_y = y;
/*
* move the last moved icon on the top of the stack, so it be drawn the top most; also
* when called arrange_icons(), last moved icon will be placed last in the list
*/
ic = selectionbuf.back();
insert(*ic, children());
if(apply) {
redraw();
save_icons_positions();
}
}
/*
* 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) {
DesktopIcon *o;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
if(o->x() < px && o->y() < py && px < (o->x() + o->h()) && py < (o->y() + o->h()))
return o;
}
return NULL;
}
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.
*/
DesktopIcon* o;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
if(intersects(ax, ay, ax+aw, ay+ah, o->x(), o->y(), o->w()+o->x(), o->h()+o->y())) {
if(!o->is_focused()) {
o->do_focus();
/* updated from Desktop::draw() */
o->damage(EDE_DESKTOP_DAMAGE_CHILD_LABEL);
}
} else {
if(o->is_focused()) {
o->do_unfocus();
o->fast_redraw();
}
}
}
}
void Desktop::draw(void) {
if(!damage()) return;
if(damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) {
/*
* If any overlay was previously visible during full redraw, it will not be cleared because of fast flip.
* This will assure that does not happened.
*/
fl_overlay_clear();
EDE_DESKTOP_WINDOW::draw();
//E_DEBUG(E_STRLOC ": REDRAW ALL\n");
}
if(damage() & EDE_DESKTOP_DAMAGE_OVERLAY) {
if(selbox->show)
fl_overlay_rect(selbox->x, selbox->y, selbox->w, selbox->h);
else
fl_overlay_clear();
/*
* 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() == EDE_DESKTOP_DAMAGE_CHILD_LABEL) {
update_child(*child(i));
child(i)->clear_damage();
//E_DEBUG(E_STRLOC ": ICON REDRAW \n");
}
}
}
clear_damage();
}
int Desktop::handle(int event) {
switch(event) {
case FL_FOCUS:
case FL_UNFOCUS:
case FL_SHORTCUT:
return 1;
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.
*/
Fl_Widget* clicked = Fl::belowmouse();
if(NOT_SELECTABLE(clicked)) {
//E_DEBUG(E_STRLOC ": DESKTOP CLICK !!!\n");
if(!selectionbuf.empty()) {
/*
* Only focused are in selectionbuf, so this is fine to do; also will prevent
* full redraw when is clicked on desktop
*/
unfocus_all();
selectionbuf.clear();
}
/* track position so moving can be deduced */
if(Fl::event_button() == 1) {
selbox->x = Fl::event_x();
selbox->y = Fl::event_y();
} else if(Fl::event_button() == 3) {
last_px = Fl::event_x();
last_py = Fl::event_y();
damage(EDE_DESKTOP_DAMAGE_OVERLAY);
const edelib::MenuItem* item = dmenu->menu()->popup(Fl::event_x(), Fl::event_y());
dmenu->picked(item);
}
return 1;
}
/* from here, all events are managed for icons */
DesktopIcon* tmp_icon = (DesktopIcon*)clicked;
/* do no use assertion on this, since fltk::belowmouse() can miss our icon */
if(!tmp_icon) return 1;
if(SELECTION_MULTI) {
Fl::event_is_click(0);
select(tmp_icon);
return 1;
} else if(SELECTION_SINGLE) {
if(!in_selection(tmp_icon)) {
select_only(tmp_icon);
}
} else if(Fl::event_button() == 3) {
select_only(tmp_icon);
}
/*
* Let child handle the rest.
* Also prevent click on other mouse buttons during move.
*/
if(!moving)
tmp_icon->handle(FL_PUSH);
//E_DEBUG(E_STRLOC ": FL_PUSH from desktop\n");
selection_x = Fl::event_x_root();
selection_y = Fl::event_y_root();
return 1;
}
case FL_DRAG:
moving = true;
if(!selectionbuf.empty()) {
//E_DEBUG(E_STRLOC ": DRAG icon from desktop\n");
move_selection(Fl::event_x_root(), Fl::event_y_root(), false);
} else {
//E_DEBUG(E_STRLOC ": 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 = Fl::event_x() - selbox->x;
selbox->h = Fl::event_y() - selbox->y;
selbox->show = true;
/* see if there some icons inside selection area */
select_in_area();
/* redraw selection box */
damage(EDE_DESKTOP_DAMAGE_OVERLAY);
}
}
return 1;
case FL_RELEASE:
//E_DEBUG(E_STRLOC ": RELEASE from desktop\n");
//E_DEBUG(E_STRLOC ": clicks: %i\n", Fl::event_is_click());
if(selbox->show) {
selbox->x = selbox->y = selbox->w = selbox->h = 0;
selbox->show = false;
damage(EDE_DESKTOP_DAMAGE_OVERLAY);
/*
* Now pickup those who are in is_focused() state.
*
* Possible flickers due overlay will be later removed when is called move_selection(), which
* will in turn redraw icons again after position them.
*/
if(!selectionbuf.empty())
selectionbuf.clear();
DesktopIcon *o;
for(int i = 0; i < children(); i++) {
if(NOT_SELECTABLE(child(i))) continue;
o = (DesktopIcon*)child(i);
if(o->is_focused())
select(o, false);
}
return 1;
}
if(!selectionbuf.empty() && moving)
move_selection(Fl::event_x_root(), Fl::event_y_root(), true);
/*
* Do not send FL_RELEASE during move
* TODO: should be alowed FL_RELEASE to multiple icons? (aka. run command for all selected icons)?
*/
if(selectionbuf.size() == 1 && !moving)
selectionbuf.front()->handle(FL_RELEASE);
moving = false;
return 1;
case FL_DND_ENTER:
case FL_DND_DRAG:
case FL_DND_LEAVE:
return 1;
case FL_DND_RELEASE: {
DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y());
if(di) return di->handle(event);
return 1;
}
case FL_PASTE: {
DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y());
if(di) return di->handle(event);
return 1;
}
case FL_ENTER:
case FL_LEAVE:
case FL_MOVE:
return EDE_DESKTOP_WINDOW::handle(event);
default:
break;
}
return 0;
}

99
ede-desktop/Desktop.h Normal file
View File

@ -0,0 +1,99 @@
/*
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* Copyright (C) 2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __EDE_DESKTOP_H__
#define __EDE_DESKTOP_H__
#include <edelib/MenuButton.h>
#include <edelib/DesktopFile.h>
#include <edelib/Config.h>
#include <edelib/List.h>
#include <edelib/String.h>
#ifdef USE_EDELIB_WINDOW
# include <edelib/Window.h>
# define EDE_DESKTOP_WINDOW EDELIB_NS_PREPEND(Window)
#else
# include <FL/Fl_Window.H>
# define EDE_DESKTOP_WINDOW Fl_Window
#endif
#include "Globals.h"
#define EDE_DESKTOP_APP "ede-desktop"
struct SelectionOverlay;
struct IconOptions;
class DesktopIcon;
class Wallpaper;
typedef EDELIB_NS_PREPEND(list)<DesktopIcon*> DesktopIconList;
typedef EDELIB_NS_PREPEND(list)<DesktopIcon*>::iterator DesktopIconListIt;
class Desktop : public EDE_DESKTOP_WINDOW {
private:
SelectionOverlay *selbox;
DesktopConfig *conf;
IconOptions *icon_opts;
EDELIB_NS_PREPEND(String) dpath;
EDELIB_NS_PREPEND(MenuButton) *dmenu;
Wallpaper *wallpaper;
int selection_x, selection_y;
/* last recorded pointer position, so icon can be created at position where menu is clicked */
int last_px, last_py;
bool moving;
/* so we can track selected icons; one or multiselection */
DesktopIconList selectionbuf;
public:
Desktop();
~Desktop();
const char *desktop_path(void);
void show(void);
void update_workarea(void);
void read_config(void);
void read_desktop_folder(const char *dpath = NULL);
DesktopIcon *read_desktop_file(const char *path, const char *base = 0, DesktopConfig *positions = 0);
void arrange_icons(void);
bool remove_icon(DesktopIcon *di, bool real_delete);
bool rename_icon(DesktopIcon *di, const char *name);
bool save_icons_positions(void);
bool create_folder(const char *name);
void unfocus_all(void);
void select(DesktopIcon *ic, bool do_redraw = true);
void select_only(DesktopIcon *ic);
bool in_selection(const DesktopIcon *ic);
void move_selection(int x, int y, bool apply);
DesktopIcon *below_mouse(int px, int py);
void select_in_area(void);
void draw(void);
int handle(int event);
};
#endif

View File

@ -1,13 +1,21 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2008 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
@ -18,20 +26,19 @@
#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/IconLoader.h>
#include <edelib/MenuItem.h>
#include <edelib/MessageBox.h>
#include <edelib/Nls.h>
#include <edelib/Run.h>
#include "ede-desktop.h"
#include "DesktopIcon.h"
#include "IconDialog.h"
#include "MovableIcon.h"
#include "Utils.h"
#include "Desktop.h"
/* label offset from icon y() + h(), so selection box can be drawn nicely */
#define LABEL_OFFSET 2
/* minimal icon sizes */
#define ICON_SIZE_MIN_W 48
@ -41,18 +48,16 @@
#define OFFSET_W 16
#define OFFSET_H 16
/* label offset from icon y()+h(), so selection box can be drawn nicely */
#define LABEL_OFFSET 2
EDELIB_NS_USING(String)
EDELIB_NS_USING(IconLoader)
EDELIB_NS_USING(MenuItem)
EDELIB_NS_USING(String)
EDELIB_NS_USING(MenuButton)
EDELIB_NS_USING(ICON_SIZE_HUGE)
EDELIB_NS_USING(ICON_SIZE_TINY)
EDELIB_NS_USING(input)
EDELIB_NS_USING(ask)
EDELIB_NS_USING(MenuItem)
EDELIB_NS_USING(run_async)
EDELIB_NS_USING(ask)
EDELIB_NS_USING(alert)
EDELIB_NS_USING(input)
EDELIB_NS_USING(ICON_SIZE_TINY)
EDELIB_NS_USING(ICON_SIZE_HUGE)
static void open_cb(Fl_Widget*, void* d);
static void rename_cb(Fl_Widget*, void* d);
@ -62,22 +67,21 @@ static MenuItem icon_menu[] = {
{_("&Open"), 0, open_cb, 0},
{_("&Rename"), 0, rename_cb, 0},
{_("&Delete"), 0, delete_cb, 0},
/* {_("&Properties"), 0, props_cb, 0}, */
{0}
};
#if 0
static MenuItem icon_trash_menu[] = {
{_("&Open"), 0, 0},
{_("&Properties"), 0, 0, 0, FL_MENU_DIVIDER},
{_("&Empty"), 0, 0},
{0}
};
#endif
static void open_cb(Fl_Widget*, void* d) {
DesktopIcon* di = (DesktopIcon*)d;
IconSettings* s = di->get_settings();
run_async("ede-launch %s", s->cmd.c_str());
DesktopIcon* o = (DesktopIcon*)d;
run_async("ede-launch %s", o->get_cmd());
}
static void rename_cb(Fl_Widget*, void* d) {
@ -85,137 +89,94 @@ static void rename_cb(Fl_Widget*, void* d) {
const char* new_name = input(_("Change desktop icon name to:"), di->label());
if(new_name) {
di->rename(new_name);
Desktop::instance()->rename_icon(di, new_name);
bool saved = ((Desktop*)di->parent())->rename_icon(di, new_name);
if(!saved)
alert(_("Unable to rename this icon. Please check if you have enough permissions to do so"));
}
}
static void delete_cb(Fl_Widget*, void* d) {
DesktopIcon* di = (DesktopIcon*)d;
if(ask(_("This icon will be permanently deleted. Proceed?")))
Desktop::instance()->remove_icon(di, true);
if(ask(_("This icon will be permanently deleted. Are you sure?")))
((Desktop*)di->parent())->remove_icon(di, true);
}
/*
static void props_cb(Fl_Widget*, void* d) {
DesktopIcon* di = (DesktopIcon*)d;
icon_dialog_icon_property(di);
}
*/
DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
Fl_Widget(is->x, is->y, ICON_SIZE_MIN_W, ICON_SIZE_MIN_H) {
E_ASSERT(gs != NULL);
lwidth = lheight = 0;
focus = false;
micon = NULL;
darker_img = NULL;
gsettings = gs;
settings = is;
label(settings->name.c_str());
imenu = new MenuButton(0, 0, 0, 0);
if(settings->type == ICON_TRASH)
imenu->menu(icon_trash_menu);
else {
icon_menu[2].image(IconLoader::get("edit-delete", ICON_SIZE_TINY));
imenu->menu(icon_menu);
}
load_icon(ICON_FACE_ONE);
fix_position(x(), y());
/* use desktop color as color for icon background */
color(bg);
DesktopIcon::DesktopIcon(const char *l, int W, int H) : Fl_Widget(1, 1, W, H, l) {
box(FL_FLAT_BOX);
color(FL_RED);
label(l);
align(FL_ALIGN_WRAP);
update_label_font_and_size();
/* default values unless given explicitly */
labelfont(FL_HELVETICA);
labelsize(12);
darker_img = 0;
micon = 0;
lwidth = lheight = 0;
focused = false;
imenu = 0;
icon_menu[2].image((Fl_Image*)IconLoader::get("edit-delete", ICON_SIZE_TINY));
}
DesktopIcon::~DesktopIcon() {
E_DEBUG("DesktopIcon::~DesktopIcon()\n");
delete settings;
delete micon;
DesktopIcon::~DesktopIcon() {
delete darker_img;
delete micon;
delete imenu;
}
void DesktopIcon::load_icon(int face) {
const char* ic = NULL;
void DesktopIcon::set_image(const char *name) {
E_RETURN_IF_FAIL(IconLoader::inited());
if(face != ICON_FACE_TWO) {
if(!settings->icon.empty())
ic = settings->icon.c_str();
} else {
if(!settings->icon2.empty())
ic = settings->icon2.c_str();
}
if(!ic)
return;
if(!IconLoader::set(this, ic, ICON_SIZE_HUGE)) {
E_DEBUG(E_STRLOC ": Unable to load %s icon\n", ic);
return;
}
/* if not name give, use false name to trick IconLoader to use fallback icons */
if(!name) name = "THIS-ICON-DOES-NOT-EXISTS";
E_RETURN_IF_FAIL(IconLoader::set(this, name, ICON_SIZE_HUGE));
/* fetch image object for sizes */
Fl_Image* img = image();
int img_w = img->w();
int img_h = img->h();
int img_w = img->w(),
img_h = img->h();
/* resize box if icon is larger */
if(img_w > ICON_SIZE_MIN_W || img_h > ICON_SIZE_MIN_H)
size(img_w + OFFSET_W, img_h + OFFSET_H);
/* darker icon version for selection */
delete darker_img;
darker_img = img->copy(img->w(), img->h());
darker_img->color_average(FL_BLUE, 0.6);
}
void DesktopIcon::update_label_font_and_size(void) {
labelfont(gsettings->label_font);
labelsize(gsettings->label_fontsize);
lwidth = gsettings->label_maxwidth;
lheight= 0;
E_RETURN_IF_FAIL(opts != 0);
labelfont(opts->label_font);
labelsize(opts->label_fontsize);
lwidth = opts->label_maxwidth;
lheight = 0;
/*
* make sure current font size/type is set (internaly to fltk)
* so fl_measure() can correctly calculate label width and height
*/
int old = fl_font();
int old_sz = fl_size();
int old = fl_font(), old_sz = fl_size();
fl_font(labelfont(), labelsize());
fl_measure(label(), lwidth, lheight, align());
fl_font(old, old_sz);
lwidth += 12;
lwidth += 12;
lheight += 5;
}
void DesktopIcon::fix_position(int X, int Y) {
int dx, dy, dw, dh;
Desktop::instance()->area(dx, dy, dw, dh);
int dx = parent()->x(),
dy = parent()->y(),
dw = parent()->w(),
dh = parent()->h();
if(X < dx)
X = dx;
if(Y < dy)
Y = dy;
if(X + w() > dw)
X = (dx + dw) - w();
if(Y + h() > dh)
Y = (dy + dh) - h();
if(X < dx) X = dx;
if(Y < dy) Y = dy;
if(X + w() > dw) X = (dx + dw) - w();
if(Y + h() > dh) Y = (dy + dh) - h();
position(X, Y);
}
@ -227,14 +188,17 @@ void DesktopIcon::drag(int x, int y, bool apply) {
/*
* This is used to calculate correct window startup/ending
* position since icon is placed in the middle of the box.
*
* Opposite, window (shaped) will have small but noticeable 'jump off' and
* dropped icon position will not be at the exact place where was dropped.
*/
int ix = 0, iy = 0;
if(image()) {
ix = (w()/2) - (image()->w()/2);
iy = (h()/2) - (image()->h()/2);
/* include parent offset since x/y are absolute locations */
if(parent()) {
ix += parent()->x();
iy += parent()->y();
}
}
micon->position(micon->x() + ix, micon->y() + iy);
@ -251,7 +215,14 @@ void DesktopIcon::drag(int x, int y, bool apply) {
if(image()) {
ix = (w()/2) - (image()->w()/2);
iy = (h()/2) - (image()->h()/2);
/* also take into account offsets, as below we subtract it */
if(parent()) {
ix += parent()->x();
iy += parent()->y();
}
}
fix_position(micon->x() - ix, micon->y() - iy);
#else
fix_position(micon->x(), micon->y());
@ -276,38 +247,7 @@ int DesktopIcon::drag_icon_y(void) {
else
return micon->y();
}
void DesktopIcon::rename(const char* str) {
if(!str ||(str[0] == '\0'))
return;
if(settings->name == str)
return;
settings->name = str;
label(settings->name.c_str());
update_label_font_and_size();
redraw();
}
const String& DesktopIcon::path(void) {
return settings->full_path;
}
int DesktopIcon::icon_type(void) {
return settings->type;
}
void DesktopIcon::use_icon1(void) {
load_icon(ICON_FACE_ONE);
fast_redraw();
}
void DesktopIcon::use_icon2(void) {
load_icon(ICON_FACE_TWO);
fast_redraw();
}
void DesktopIcon::fast_redraw(void) {
int wsz = w();
int xpos = x();
@ -321,11 +261,9 @@ void DesktopIcon::fast_redraw(void) {
parent()->damage(FL_DAMAGE_ALL, xpos, y(), wsz, h() + lheight + LABEL_OFFSET + 2);
}
void DesktopIcon::draw(void) {
// draw_box(FL_UP_BOX, FL_BLACK);
void DesktopIcon::draw(void) {
if(image() && (damage() & FL_DAMAGE_ALL)) {
Fl_Image* im = image();
Fl_Image *im = image();
/* center image in the box */
int ix = (w()/2) - (im->w()/2);
@ -333,23 +271,27 @@ void DesktopIcon::draw(void) {
ix += x();
iy += y();
/* darker_img is always present if image() is present */
if(is_focused())
if(is_focused()) {
/* create darker image only when needed */
if(!darker_img) {
darker_img = im->copy(im->w(), im->h());
darker_img->color_average(FL_BLUE, 0.6);
}
darker_img->draw(ix, iy);
else
} else {
im->draw(ix, iy);
E_DEBUG(E_STRLOC ": DesktopIcon icon redraw\n");
}
}
if(gsettings->label_draw && (damage() & (FL_DAMAGE_ALL | EDAMAGE_CHILD_LABEL))) {
if(opts && opts->label_visible && (damage() & (FL_DAMAGE_ALL | EDE_DESKTOP_DAMAGE_CHILD_LABEL))) {
int X = x() + w()-(w()/2)-(lwidth/2);
int Y = y() + h() + LABEL_OFFSET;
Fl_Color old = fl_color();
if(!gsettings->label_transparent) {
fl_color(gsettings->label_background);
if(!opts->label_transparent) {
fl_color(opts->label_background);
fl_rectf(X, Y, lwidth, lheight);
}
@ -358,12 +300,12 @@ void DesktopIcon::draw(void) {
/* draw with icon's font */
fl_font(labelfont(), labelsize());
/* pseudo-shadow */
fl_color(FL_BLACK);
fl_draw(label(), X+1, Y+1, lwidth, lheight, align(), 0, 0);
fl_color(gsettings->label_foreground);
fl_color(opts->label_foreground);
fl_draw(label(), X, Y, lwidth, lheight, align(), 0, 0);
/* restore old font */
@ -371,7 +313,7 @@ void DesktopIcon::draw(void) {
if(is_focused()) {
/* draw focused box on our way so later this can be used to draw customised boxes */
fl_color(gsettings->label_foreground);
fl_color(opts->label_foreground);
fl_line_style(FL_DOT);
fl_push_matrix();
@ -390,7 +332,6 @@ void DesktopIcon::draw(void) {
/* revert to old color whatever that be */
fl_color(old);
E_DEBUG(E_STRLOC ": DesktopIcon label redraw\n");
}
}
@ -400,22 +341,33 @@ int DesktopIcon::handle(int event) {
case FL_UNFOCUS:
case FL_ENTER:
case FL_LEAVE:
return 1;
/* We have to handle FL_MOVE too, if want to get only once FL_ENTER when entered or FL_LEAVE when leaved */
case FL_MOVE:
return 1;
case FL_PUSH:
if(Fl::event_button() == 3) {
/*
* init icon specific menu only when needed
* TODO: since menu for all icons is mostly the same, it can be shared; Desktop can
* have menu instance seeded to all icons
*/
if(!imenu) {
imenu = new MenuButton(0, 0, 0, 0);
imenu->menu(icon_menu);
}
/* MenuItem::popup() by default does not call callbacks */
const MenuItem* m = imenu->menu()->popup(Fl::event_x(), Fl::event_y());
const MenuItem *m = imenu->menu()->popup(Fl::event_x(), Fl::event_y());
if(m && m->callback())
m->do_callback(0, this);
}
return 1;
case FL_RELEASE:
if(Fl::event_clicks() > 0)
run_async("ede-launch %s", settings->cmd.c_str());
if(Fl::event_clicks() > 0 && !cmd.empty())
run_async("ede-launch %s", cmd.c_str());
return 1;
case FL_DND_ENTER:

View File

@ -1,95 +1,119 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2008 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __DESKTOPICON_H__
#define __DESKTOPICON_H__
#ifndef __DESKTOP_ICON_H__
#define __DESKTOP_ICON_H__
#include <FL/Fl_Widget.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Image.H>
#include <edelib/String.h>
#include <edelib/MenuButton.h>
#include <edelib/String.h>
#include "Globals.h"
enum {
DESKTOP_ICON_TYPE_NORMAL,
DESKTOP_ICON_TYPE_TRASH,
DESKTOP_ICON_TYPE_LINK,
DESKTOP_ICON_TYPE_FILE,
DESKTOP_ICON_TYPE_FOLDER
};
/* default icon sizes */
#define DESKTOP_ICON_SIZE_W 48
#define DESKTOP_ICON_SIZE_H 48
/*
* Each DesktopIcon shares IconOptions, which is content of [Icons] section
* from configuration file. With this, 'Desktop' needs only to update content so all
* icons see it.
*/
struct IconOptions {
int label_background;
int label_foreground;
int label_font;
int label_fontsize;
int label_maxwidth;
int label_transparent;
int label_visible;
bool one_click_exec;
};
struct GlobalIconSettings;
struct IconSettings;
class MovableIcon;
class DesktopIcon : public Fl_Widget {
private:
IconSettings* settings;
const GlobalIconSettings* gsettings;
int icon_type;
int lwidth, lheight;
bool focused;
int lwidth;
int lheight;
bool focus;
Fl_Image *darker_img;
IconOptions *opts;
MovableIcon *micon;
MovableIcon* micon;
Fl_Image* darker_img;
edelib::MenuButton* imenu;
void load_icon(int face);
void update_label_font_and_size(void);
void fix_position(int X, int Y);
/* location of .desktop file and command to be executed */
EDELIB_NS_PREPEND(String) path, cmd;
EDELIB_NS_PREPEND(MenuButton) *imenu;
public:
DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett, int bg);
DesktopIcon(const char *l, int W = DESKTOP_ICON_SIZE_W, int H = DESKTOP_ICON_SIZE_H);
~DesktopIcon();
virtual void draw(void);
virtual int handle(int event);
void set_icon_type(int c) { icon_type = c; }
int get_icon_type(void) { return icon_type;}
void set_image(const char *name);
void update_label_font_and_size(void);
void set_options(IconOptions *o) {
opts = o;
update_label_font_and_size();
}
/* Here is implemented localy focus schema avoiding messy fltk one. Focus/unfocus is handled from Desktop. */
void do_focus(void) { focused = true; }
void do_unfocus(void) { focused = false; }
bool is_focused(void) { return focused; }
void set_path(const char *p) { path = p; }
const char *get_path(void) { return path.c_str(); }
void set_cmd(const char *c) { cmd = c; }
const char *get_cmd(void) { return cmd.c_str(); }
void fix_position(int X, int Y);
void drag(int x, int y, bool apply);
int drag_icon_x(void);
int drag_icon_y(void);
IconSettings* get_settings(void) { return settings; }
/*
* 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)
* 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.
* Alternative way would be to redraw the 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.
*/
void do_focus(void) { focus = true; }
void do_unfocus(void) { focus = false; }
bool is_focused(void) { return focus; }
Fl_Image* icon_image(void) { return image(); }
void rename(const char* str);
/*
* make sure this returns String since operator== is
* further used, especially in Desktop
*/
const edelib::String& path(void);
int icon_type(void);
void use_icon1(void);
void use_icon2(void);
void draw(void);
int handle(int event);
};
#endif

33
ede-desktop/Globals.h Normal file
View File

@ -0,0 +1,33 @@
/*
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* Copyright (C) 2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __EDE_DESKTOP_GLOBAL_H__
#define __EDE_DESKTOP_GLOBAL_H__
#include <edelib/Resource.h>
/* alias it so we don't have to use EDELIB_NS_PREPEND */
EDELIB_NS_USING_AS(Resource, DesktopConfig)
#define EDE_DESKTOP_DAMAGE_CHILD_LABEL 0x10
#define EDE_DESKTOP_DAMAGE_OVERLAY 0x20
#define EDE_DESKTOP_DAMAGE_CLEAR_OVERLAY 0x30
#endif

View File

@ -1,13 +1,21 @@
/*
* $Id: IconProperties.h 2366 2008-10-02 09:42:19Z karijes $
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2012 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <ctype.h>
@ -35,7 +43,7 @@
#include "IconDialog.h"
#include "DesktopIcon.h"
#include "ede-desktop.h"
#include "Desktop.h"
EDELIB_NS_USING_LIST(10, (str_tolower, icon_chooser, dir_home, build_filename, alert,
ICON_SIZE_HUGE, String, IconLoader, DesktopFile, DESK_FILE_TYPE_APPLICATION))
@ -73,13 +81,15 @@ static void cancel_cb(Fl_Widget*, void*) {
win->hide();
}
static void ok_cb(Fl_Widget*, void*) {
static void ok_cb(Fl_Widget*, void *d) {
if(is_empty_input(name) || is_empty_input(execute) || !img->image()) {
/* do nothing */
win->hide();
return;
}
Desktop *self = (Desktop*)d;
DesktopFile df;
df.create_new(DESK_FILE_TYPE_APPLICATION);
df.set_name(name->value());
@ -98,32 +108,19 @@ static void ok_cb(Fl_Widget*, void*) {
file += ".desktop";
/* go through the file and replace spaces with '_' */
for(char *p = (char*)file.c_str(); p && *p; p++)
if(isspace(*p)) *p = '_';
for(String::size_type i = 0; i < file.length(); i++)
if(isspace(file[i])) file[i] = '_';
/* TODO: let 'Desktop' (class) returns full desktop path */
String path = build_filename(Desktop::instance()->desktop_path(), file.c_str());
/*
* disable watching on folder and explicitly add file (probably as notification will be fired up faster than
* file will be available on that location)
*/
Desktop::instance()->dir_watch_off();
String path = build_filename(self->desktop_path(), file.c_str());
if(df.save(path.c_str())) {
/* explictly add file path */
Desktop::instance()->add_icon_by_path(path.c_str(), NULL);
/*
* wait a second; this would remove event from the queue so watched does not complain how filed
* does not exists
*/
Fl::wait(1);
Desktop::instance()->redraw();
DesktopIcon *ic = self->read_desktop_file(path.c_str(), file.c_str());
if(ic) self->add(ic);
self->redraw();
} else {
alert(_("Unable to create '%s' file. Received error is: %s\n"), path.c_str(), df.strerror());
}
Desktop::instance()->dir_watch_on();
win->hide();
}
@ -140,7 +137,7 @@ static void file_browse_cb(Fl_Widget*, void*) {
execute->value(p);
}
void icon_dialog_icon_create(void) {
void icon_dialog_icon_create(Desktop *self) {
win = new Fl_Window(430, 170, _("Create desktop icon"));
img = new Fl_Button(10, 10, 75, 75);
img->callback(img_browse_cb);
@ -156,7 +153,7 @@ void icon_dialog_icon_create(void) {
icon_type->menu(menu_items);
ok = new Fl_Button(235, 135, 90, 25, _("&OK"));
ok->callback(ok_cb);
ok->callback(ok_cb, self);
cancel = new Fl_Button(330, 135, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
win->end();

View File

@ -1,21 +1,30 @@
/*
* $Id: IconProperties.h 2366 2008-10-02 09:42:19Z karijes $
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2012 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __ICONDIALOG_H__
#define __ICONDIALOG_H__
class DesktopIcon;
class Desktop;
void icon_dialog_icon_create(void);
void icon_dialog_icon_create(Desktop *d);
void icon_dialog_icon_property(DesktopIcon *d);
#endif

View File

@ -1,26 +1,34 @@
#
# $Id$
#
# 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.
# Copyright (C) 2006-2013 Sanel Zukan
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
SubDir TOP ede-desktop ;
ObjectC++Flags ede-desktop.cpp : -DUSE_EDELIB_WINDOW ;
SOURCE = ede-desktop.cpp
Utils.cpp
Wallpaper.cpp
DesktopIcon.cpp
Wallpaper.cpp
DesktopIcon.cpp
MovableIcon.cpp
IconDialog.cpp ;
Utils.cpp
IconDialog.cpp
Desktop.cpp ;
ObjectC++Flags $(SOURCE) : $(EDELIB_DBUS_INCLUDE) ;
EdeProgram ede-desktop : $(SOURCE) ;
LinkAgainst ede-desktop : $(EDELIB_DBUS_LIB) ;
TranslationStrings locale : $(SOURCE) ;
LinkAgainst ede-desktop : $(EDELIB_DBUS_LIB) $(XSHAPE_LIBS) ;

View File

@ -1,13 +1,21 @@
/*
* $Id: DesktopIcon.cpp 3032 2011-08-03 12:20:37Z karijes $
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2011 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
@ -15,8 +23,9 @@
#endif
#define FL_LIBRARY 1
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Image.H>
#include <edelib/Debug.h>
#ifdef HAVE_SHAPE
@ -27,7 +36,9 @@
#include "DesktopIcon.h"
#include "Utils.h"
MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic), mask(0), opacity_atom(0) {
MovableIcon::MovableIcon(DesktopIcon* ic) :
Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic), mask(0), opacity_atom(0)
{
E_ASSERT(icon != NULL);
set_override();
@ -36,7 +47,7 @@ MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(),
begin();
/* force box be same width/height as icon so it can fit inside masked window */
#ifdef HAVE_SHAPE
Fl_Image* img = ic->icon_image();
Fl_Image* img = ic->image();
if(img)
icon_box = new Fl_Box(0, 0, img->w(), img->h());
else
@ -44,7 +55,7 @@ MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(),
#else
icon_box = new Fl_Box(0, 0, w(), h());
#endif
icon_box->image(ic->icon_image());
icon_box->image(ic->image());
end();
opacity_atom = XInternAtom(fl_display, "_NET_WM_WINDOW_OPACITY", False);
@ -60,8 +71,8 @@ void MovableIcon::show(void) {
Fl_X::make_xid(this);
#ifdef HAVE_SHAPE
if(icon->icon_image()) {
mask = create_mask(icon->icon_image());
if(icon->image()) {
mask = create_mask(icon->image());
if(mask) {
XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet);

View File

@ -1,21 +1,29 @@
/*
* $Id: DesktopIcon.h 2742 2009-07-09 13:59:51Z karijes $
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2011 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MOVABLEICON_H__
#define __MOVABLEICON_H__
#include <X11/Xlib.h> // Pixmap
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <Fl/x.h>
class DesktopIcon;
@ -25,6 +33,7 @@ private:
Fl_Box* icon_box;
Pixmap mask;
Atom opacity_atom;
public:
MovableIcon(DesktopIcon* i);
~MovableIcon();

View File

@ -1,17 +1,24 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2008 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <string.h>
#include <FL/x.H>
#include <edelib/Debug.h>
#include "Utils.h"
@ -26,8 +33,7 @@ static Fl_Window* overlay_drawable = NULL;
static char dash_list[] = {1};
void draw_overlay_rect(void) {
if(overlay_w <= 0 || overlay_h <= 0)
return;
E_RETURN_IF_FAIL(overlay_w > 0 && overlay_h > 0);
XSetDashes(fl_display, fl_gc, 0, dash_list, 1);
XSetLineAttributes(fl_display, fl_gc, 2, LineOnOffDash, CapButt, JoinMiter);
@ -35,11 +41,7 @@ void draw_overlay_rect(void) {
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;
Window ow = overlay_drawable ? fl_xid(overlay_drawable) : fl_window;
XDrawRectangle(fl_display, ow, fl_gc, overlay_x, overlay_y, overlay_w-1, overlay_h-1);
XSetFunction(fl_display, fl_gc, GXcopy);

View File

@ -1,25 +1,31 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2008 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UTILS_H__
#define __UTILS_H__
#include <X11/Xlib.h>
#include <FL/Fl_Window.H>
#include <FL/Fl_Image.H>
#include <Fl/x.h>
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_Image* img);

View File

@ -1,52 +1,53 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <string.h> // memcpy
#include <stdlib.h> // malloc
#include <string.h>
#include <stdlib.h>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_RGB_Image.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <edelib/Debug.h>
#include "Wallpaper.h"
#include "Utils.h"
#define CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask) \
tmp = 0; \
if(rshift >= 0) \
tmp |= (((int)r << rshift) & rmask); \
else \
tmp |= (((int)r >> (-rshift)) & rmask); \
\
if(gshift >= 0) \
tmp |= (((int)g << gshift) & gmask); \
else \
tmp |= (((int)g >> (-gshift)) & gmask); \
\
if(bshift >= 0) \
tmp |= (((int)b << bshift) & bmask); \
else \
#define CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask) \
tmp = 0; \
if(rshift >= 0) \
tmp |= (((int)r << rshift) & rmask); \
else \
tmp |= (((int)r >> (-rshift)) & rmask); \
\
if(gshift >= 0) \
tmp |= (((int)g << gshift) & gmask); \
else \
tmp |= (((int)g >> (-gshift)) & gmask); \
\
if(bshift >= 0) \
tmp |= (((int)b << bshift) & bmask); \
else \
tmp |= (((int)b >> (-bshift)) & bmask)
static Pixmap create_xpixmap(Fl_Image* img, XImage** xim, Pixmap pix, int wp_w, int wp_h) {
if(!img)
return 0;
if(pix)
XFreePixmap(fl_display, pix);
if(!img) return 0;
if(pix) XFreePixmap(fl_display, pix);
unsigned long rmask = fl_visual->visual->red_mask;
unsigned long gmask = fl_visual->visual->green_mask;
@ -108,15 +109,9 @@ static Pixmap create_xpixmap(Fl_Image* img, XImage** xim, Pixmap pix, int wp_w,
int iw = img->w();
int ih = img->h();
int id = img->d();
bool msb = false;
if(ImageByteOrder(fl_display) == MSBFirst)
msb = true;
else
msb = false;
bool msb = (ImageByteOrder(fl_display) == MSBFirst) ? true : false;
unsigned int r, g, b, tmp;
//unsigned char* dest = (unsigned char*)malloc(sizeof(unsigned char) * iw * ih * id);
unsigned char* dest = (unsigned char*)malloc(ih * (*xim)->bytes_per_line);
unsigned char* destptr = dest;
unsigned char* src = (unsigned char*)img->data()[0];
@ -257,8 +252,8 @@ static Pixmap create_xpixmap(Fl_Image* img, XImage** xim, Pixmap pix, int wp_w,
*
* FIXME: drawable background should be the same color as wallpaper background
*/
Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, wp_w,
wp_h, 0, 0, BlackPixel(fl_display, fl_screen));
Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, wp_w, wp_h,
0, 0, BlackPixel(fl_display, fl_screen));
pix = XCreatePixmap(fl_display, drawable, wp_w, wp_h, fl_visual->depth);
@ -349,23 +344,18 @@ static void create_tile(Fl_Image* orig, Fl_RGB_Image** copied, int X, int Y, int
}
Wallpaper::~Wallpaper() {
if(rootpmap_pixmap)
XFreePixmap(fl_display, rootpmap_pixmap);
if(rootpmap_pixmap) XFreePixmap(fl_display, rootpmap_pixmap);
delete stretched_alloc;
}
void Wallpaper::set_rootpmap(void) {
if(!image())
return;
E_RETURN_IF_FAIL(image() != NULL);
XImage* rootpmap_image = 0;
XImage *rootpmap_image = 0;
Atom _XA_XROOTPMAP_ID;
rootpmap_pixmap = create_xpixmap(image(), &rootpmap_image, rootpmap_pixmap, w(), h());
if(!rootpmap_pixmap)
return;
E_RETURN_IF_FAIL(rootpmap_pixmap != 0);
/* XDestroyImage function calls frees both the image structure and the data pointed to by the image structure */
if(rootpmap_image)
@ -374,51 +364,59 @@ void Wallpaper::set_rootpmap(void) {
_XA_XROOTPMAP_ID = XInternAtom(fl_display, "_XROOTPMAP_ID", False);
XChangeProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&rootpmap_pixmap, 1);
_XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&rootpmap_pixmap, 1);
}
bool Wallpaper::load(const char* path, WallpaperState s) {
bool Wallpaper::load(const char *path, int s, bool rootpmap) {
E_ASSERT(path != NULL);
/* in case this function gets multiple calls */
if(wpath == path && state == s && rootpmap == use_rootpmap)
return true;
Fl_Shared_Image* i = Fl_Shared_Image::get(path);
if(!i)
return false;
Fl_Shared_Image *img = Fl_Shared_Image::get(path);
E_RETURN_VAL_IF_FAIL(img != NULL, false);
if(s != WALLPAPER_CENTER && s != WALLPAPER_TILE && s != WALLPAPER_STRETCH)
s = WALLPAPER_CENTER;
if(s == WALLPAPER_TILE) {
Fl_RGB_Image* tiled;
Fl_RGB_Image *tiled;
create_tile((Fl_Image*)i, &tiled, x(), y(), w(), h());
create_tile((Fl_Image*)img, &tiled, x(), y(), w(), h());
image(tiled);
} else if(s == WALLPAPER_STRETCH) {
Fl_Image* stretched = NULL;
Fl_Image *stretched = NULL;
if(i->w() == w() && i->h() == h())
stretched = i;
if(img->w() == w() && img->h() == h())
stretched = img;
else {
/* valgrind reports it as possible lost, but FLTK should free it */
delete stretched_alloc;
stretched = i->copy(w(), h());
i->release();
stretched = img->copy(w(), h());
img->release();
stretched_alloc = stretched;
}
image(stretched);
} else {
image(i);
image(img);
}
state = s;
/* set root pixmap for pseudo transparency */
set_rootpmap();
if(rootpmap) set_rootpmap();
state = s;
use_rootpmap = rootpmap;
/* prevent self assignment or bad things will happen */
if(wpath != path) wpath = path;
return true;
}
void Wallpaper::draw(void) {
if(!image())
return;
E_RETURN_IF_FAIL(image() != NULL);
int ix, iy, iw, ih;
Fl_Image* im = image();
@ -426,8 +424,7 @@ void Wallpaper::draw(void) {
iw = im->w();
ih = im->h();
if(iw == 0 || ih == 0)
return;
E_RETURN_IF_FAIL(iw > 0 && ih > 0);
if(state == WALLPAPER_CENTER) {
ix = (w()/2) - (iw/2);
@ -475,3 +472,20 @@ int Wallpaper::handle(int event) {
return 0;
}
void Wallpaper::resize(int X, int Y, int W, int H) {
if(X == x() && Y == y() && W == w() && H == h())
return;
Fl_Box::resize(X, Y, W, H);
if(image()) {
/*
* It is safe to call 'load()' again, as Fl_Shared_Image::get() will cache successfully loaded image.
* Also benefit is that image transormations (scaling, tiling) will be done again on original image, so
* there will be no lost data.
*
* TODO: Fl_Shared_Image will eat a memory; this needs some investigation.
*/
load(wpath.c_str(), state, use_rootpmap);
}
}

View File

@ -1,22 +1,31 @@
/*
* $Id$
*
* ede-desktop, desktop and icon manager
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2006-2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
* Copyright (C) 2006-2013 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __WALLPAPER_H__
#define __WALLPAPER_H__
#include <X11/Xlib.h> // XImage, Pixmap
#include <FL/Fl_Box.H>
#include <FL/x.H>
#include <edelib/String.h>
enum WallpaperState {
enum {
WALLPAPER_CENTER,
WALLPAPER_STRETCH,
WALLPAPER_TILE
@ -26,21 +35,23 @@ class Fl_Image;
class Wallpaper : public Fl_Box {
private:
Pixmap rootpmap_pixmap;
WallpaperState state;
Fl_Image* stretched_alloc; /* FLTK issue */
Pixmap rootpmap_pixmap;
int state;
Fl_Image* stretched_alloc; /* FLTK issue */
bool use_rootpmap;
EDELIB_NS_PREPEND(String) wpath;
void set_rootpmap(void);
public:
Wallpaper(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H),
rootpmap_pixmap(0), state(WALLPAPER_CENTER), stretched_alloc(NULL) { }
Wallpaper(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H),
rootpmap_pixmap(0), state(WALLPAPER_CENTER), stretched_alloc(NULL), use_rootpmap(false) { }
~Wallpaper();
bool load(const char* path, WallpaperState s);
bool load(const char *path, int s, bool do_rootpmap = true);
virtual void draw(void);
virtual int handle(int event);
void draw(void);
int handle(int event);
void resize(int X, int Y, int W, int H);
};
#endif

File diff suppressed because it is too large Load Diff