mirror of https://github.com/edeproject/ede.git
Manualy merging ede-desktop2 branch. SF merging facility (ignores valid login) sux badly.
This commit is contained in:
parent
9d1f4699de
commit
5bfe346880
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) ;
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue