mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
eiconman based on fltk1. Most of the stuff is
revised from scratch.
This commit is contained in:
parent
95a3034827
commit
202b4ffb29
@ -1,194 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Eiconman, desktop and icon manager
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2007 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "DesktopConfig.h"
|
||||
#include "Utils.h"
|
||||
#include "eiconman.h"
|
||||
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/Debug.h>
|
||||
#include <fltk/Item.h>
|
||||
#include <fltk/ColorChooser.h>
|
||||
#include <fltk/file_chooser.h>
|
||||
#include <fltk/SharedImage.h>
|
||||
#include <fltk/run.h>
|
||||
#include <fltk/draw.h>
|
||||
#include <fltk/x11.h>
|
||||
|
||||
void close_cb(fltk::Widget*, void* w) {
|
||||
DesktopConfig* dc = (DesktopConfig*)w;
|
||||
dc->hide();
|
||||
}
|
||||
|
||||
void ok_cb(fltk::Widget*, void* w) { }
|
||||
|
||||
void apply_cb(fltk::Widget*, void* w) {
|
||||
DesktopConfig* dc = (DesktopConfig*)w;
|
||||
|
||||
//Desktop::instance()->set_bg_color(dc->bg_color());
|
||||
}
|
||||
|
||||
void wp_use_cb(fltk::Widget*, void* w) {
|
||||
DesktopConfig* dc = (DesktopConfig*)w;
|
||||
dc->wp_disable();
|
||||
}
|
||||
|
||||
void color_box_cb(fltk::Widget*, void* w) {
|
||||
DesktopConfig* dc = (DesktopConfig*)w;
|
||||
|
||||
fltk::Color col = dc->bg_color();
|
||||
if(fltk::color_chooser(_("Background color"), col))
|
||||
dc->set_color(col);
|
||||
}
|
||||
|
||||
void img_browse_cb(fltk::Widget*, void* w) {
|
||||
DesktopConfig* dc = (DesktopConfig*)w;
|
||||
|
||||
const char* f = fltk::file_chooser(_("Choose image"), "Image files (*.{jpg,png,xpm})", 0);
|
||||
if(f)
|
||||
dc->set_preview_image(f);
|
||||
};
|
||||
|
||||
PreviewBox::PreviewBox(int x, int y, int w, int h, const char* l) : fltk::InvisibleBox(x,y,w,h)
|
||||
{
|
||||
}
|
||||
|
||||
PreviewBox::~PreviewBox()
|
||||
{
|
||||
}
|
||||
|
||||
void PreviewBox::draw(void) {
|
||||
draw_box();
|
||||
|
||||
if(image()) {
|
||||
fltk::Rectangle ir(0,0,w(),h());
|
||||
box()->inset(ir);
|
||||
fltk::Image* im = (fltk::Image*)image();
|
||||
im->draw(ir);
|
||||
}
|
||||
}
|
||||
|
||||
DesktopConfig::DesktopConfig() : fltk::Window(540, 265, _("Background settings")), img_enable(false), wp_img(NULL) {
|
||||
begin();
|
||||
// monitor
|
||||
fltk::InvisibleBox* m1 = new fltk::InvisibleBox(75, 175, 100, 15);
|
||||
m1->box(fltk::BORDER_BOX);
|
||||
fltk::InvisibleBox* m2 = new fltk::InvisibleBox(20, 20, 210, 160);
|
||||
m2->box(fltk::THIN_UP_BOX);
|
||||
|
||||
preview = new PreviewBox(30, 30, 190, 140);
|
||||
preview->box(fltk::DOWN_BOX);
|
||||
preview->color(56);
|
||||
|
||||
fltk::InvisibleBox* m4 = new fltk::InvisibleBox(50, 185, 145, 15);
|
||||
m4->box(fltk::THIN_UP_BOX);
|
||||
|
||||
// fetch workspace names
|
||||
fltk::Choice* ws_names = new fltk::Choice(310, 20, 220, 25, _("Desktop:"));
|
||||
ws_names->begin();
|
||||
|
||||
new fltk::Item(_("All desktops"));
|
||||
|
||||
ws_names->end();
|
||||
|
||||
// rest
|
||||
use_wp = new fltk::CheckButton(310, 60, 20, 20, _("Use wallpaper"));
|
||||
use_wp->align(fltk::ALIGN_RIGHT);
|
||||
use_wp->callback(wp_use_cb, this);
|
||||
use_wp->value(1);
|
||||
|
||||
img_path = new fltk::Input(310, 95, 190, 25, _("Image:"));
|
||||
img_browse = new fltk::Button(505, 95, 25, 25, "...");
|
||||
img_browse->callback(img_browse_cb, this);
|
||||
|
||||
img_choice = new fltk::Choice(310, 130, 220, 25, _("Mode:"));
|
||||
img_choice->begin();
|
||||
new fltk::Item(_("Normal"));
|
||||
new fltk::Item(_("Center"));
|
||||
new fltk::Item(_("Stretch"));
|
||||
new fltk::Item(_("Aspect stretch"));
|
||||
new fltk::Item(_("Tile"));
|
||||
img_choice->end();
|
||||
|
||||
color_box = new fltk::Button(310, 175, 25, 25, _("Background color"));
|
||||
color_box->color((fltk::Color)0x3ca700);
|
||||
color_box->align(fltk::ALIGN_RIGHT);
|
||||
color_box->callback(color_box_cb, this);
|
||||
|
||||
fltk::Button* ok = new fltk::Button(250, 230, 90, 25, _("&OK"));
|
||||
ok->callback(ok_cb, this);
|
||||
|
||||
fltk::Button* apply = new fltk::Button(345, 230, 90, 25, _("&Apply"));
|
||||
apply->callback(apply_cb, this);
|
||||
|
||||
fltk::Button* close = new fltk::Button(440, 230, 90, 25, _("&Cancel"));
|
||||
close->callback(close_cb, this);
|
||||
end();
|
||||
}
|
||||
|
||||
DesktopConfig::~DesktopConfig()
|
||||
{
|
||||
}
|
||||
|
||||
void DesktopConfig::run(void) {
|
||||
if(!shown())
|
||||
show();
|
||||
|
||||
while(visible())
|
||||
fltk::wait();
|
||||
}
|
||||
|
||||
void DesktopConfig::wp_disable(void) {
|
||||
if(!use_wp->value()) {
|
||||
img_path->deactivate();
|
||||
img_browse->deactivate();
|
||||
img_choice->deactivate();
|
||||
} else {
|
||||
img_path->activate();
|
||||
img_browse->activate();
|
||||
img_choice->activate();
|
||||
}
|
||||
|
||||
img_enable = false;
|
||||
preview->image(NULL);
|
||||
set_color(color_box->color());
|
||||
}
|
||||
|
||||
void DesktopConfig::set_preview_color(unsigned int c) {
|
||||
if(c == preview->color())
|
||||
return;
|
||||
|
||||
preview->color(c);
|
||||
preview->redraw();
|
||||
}
|
||||
|
||||
void DesktopConfig::set_color(unsigned int c) {
|
||||
if(c != color_box->color()) {
|
||||
color_box->color(c);
|
||||
color_box->redraw();
|
||||
}
|
||||
|
||||
set_preview_color(c);
|
||||
}
|
||||
|
||||
void DesktopConfig::set_preview_image(const char* path) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
if(wp_path == path)
|
||||
return;
|
||||
wp_path = path;
|
||||
wp_img = fltk::SharedImage::get(wp_path.c_str());
|
||||
|
||||
preview->image(wp_img);
|
||||
preview->redraw();
|
||||
img_path->value(wp_path.c_str());
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Eiconman, desktop and icon manager
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2007 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef __DESKTOPCONFIG_H__
|
||||
#define __DESKTOPCONFIG_H__
|
||||
|
||||
#include <fltk/Window.h>
|
||||
#include <fltk/Button.h>
|
||||
#include <fltk/Input.h>
|
||||
#include <fltk/InvisibleBox.h>
|
||||
#include <fltk/Choice.h>
|
||||
#include <fltk/CheckButton.h>
|
||||
#include <fltk/Image.h>
|
||||
#include <edelib/String.h>
|
||||
|
||||
class PreviewBox : public fltk::InvisibleBox {
|
||||
public:
|
||||
PreviewBox(int x, int y, int w, int h, const char* l = 0);
|
||||
~PreviewBox();
|
||||
virtual void draw(void);
|
||||
};
|
||||
|
||||
class DesktopConfig : public fltk::Window {
|
||||
private:
|
||||
bool img_enable;
|
||||
fltk::Image* wp_img;
|
||||
|
||||
fltk::Input* img_path;
|
||||
fltk::Button* img_browse;
|
||||
fltk::Choice* img_choice;
|
||||
fltk::CheckButton* use_wp;
|
||||
PreviewBox* preview;
|
||||
fltk::Button* color_box;
|
||||
|
||||
edelib::String wp_path;
|
||||
|
||||
public:
|
||||
DesktopConfig();
|
||||
~DesktopConfig();
|
||||
|
||||
void run(void);
|
||||
void wp_disable(void);
|
||||
bool wp_enabled(void) { return img_enable; }
|
||||
|
||||
void set_preview_color(unsigned int c);
|
||||
void set_preview_image(const char* path);
|
||||
void set_color(unsigned int c);
|
||||
unsigned int bg_color(void) { return color_box->color(); }
|
||||
};
|
||||
|
||||
#endif
|
@ -12,63 +12,50 @@
|
||||
|
||||
#include "DesktopIcon.h"
|
||||
#include "eiconman.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <FL/Fl.h>
|
||||
#include <FL/fl_draw.h>
|
||||
#include <FL/Fl_Shared_Image.h>
|
||||
#include <FL/x.h>
|
||||
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/IconTheme.h>
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/Item.h>
|
||||
#include <edelib/Ask.h>
|
||||
|
||||
#include <fltk/SharedImage.h>
|
||||
#include <fltk/Color.h>
|
||||
#include <fltk/Divider.h>
|
||||
#include <fltk/draw.h>
|
||||
#include <fltk/events.h>
|
||||
#include <fltk/damage.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
#include <fltk/x11.h> // Pixmap
|
||||
|
||||
// fuck !
|
||||
#define Window XWindow
|
||||
#include <X11/extensions/shape.h>
|
||||
#undef Window
|
||||
|
||||
// default icon size
|
||||
// minimal icon size
|
||||
#define ICONSIZE 48
|
||||
|
||||
// spaces around box in case of large/small icons
|
||||
#define OFFSET_W 16
|
||||
#define OFFSET_H 16
|
||||
|
||||
void icon_delete_cb(fltk::Widget*, void* di) {
|
||||
DesktopIcon* dicon = (DesktopIcon*)di;
|
||||
edelib::ask(_("Delete '%s' ?"), dicon->label());
|
||||
}
|
||||
// label offset from icon y()+h(), so selection box can be drawn nicely
|
||||
#define LABEL_OFFSET 2
|
||||
|
||||
DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) :
|
||||
fltk::Widget(isett->x, isett->y, ICONSIZE, ICONSIZE), settings(NULL)
|
||||
{
|
||||
EASSERT(gisett != NULL); EASSERT(isett != NULL);
|
||||
DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
|
||||
Fl_Button(is->x, is->y, ICONSIZE, ICONSIZE) {
|
||||
|
||||
EASSERT(gs != NULL);
|
||||
|
||||
lwidth = lheight = 0;
|
||||
focus = false;
|
||||
micon = false;
|
||||
|
||||
image_w = image_h = ICONSIZE;
|
||||
micon = NULL;
|
||||
|
||||
/*
|
||||
* GlobalIconSettings is shared from desktop so we only
|
||||
* reference it. On other hand IconSettings is not shared
|
||||
* and we must construct a copy from given parameter
|
||||
*/
|
||||
globals = gisett;
|
||||
globals = gs;
|
||||
|
||||
settings = new IconSettings;
|
||||
settings->name = isett->name;
|
||||
settings->cmd = isett->cmd;
|
||||
settings->icon = isett->icon;
|
||||
settings->type = isett->type;
|
||||
settings->key_name= isett->key_name;
|
||||
settings->name = is->name;
|
||||
settings->cmd = is->cmd;
|
||||
settings->icon = is->icon;
|
||||
settings->type = is->type;
|
||||
settings->key_name= is->key_name;
|
||||
|
||||
// x,y are not needed since x(), y() are filled with it
|
||||
|
||||
@ -77,83 +64,52 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett) :
|
||||
if(!settings->icon.empty()) {
|
||||
const char* nn = settings->icon.c_str();
|
||||
|
||||
edelib::IconSizes isize = edelib::ICON_SIZE_MEDIUM;
|
||||
edelib::String ipath = edelib::IconTheme::get(nn, isize);
|
||||
edelib::String ipath = edelib::IconTheme::get(nn, edelib::ICON_SIZE_MEDIUM);
|
||||
Fl_Image* img = Fl_Shared_Image::get(ipath.c_str());
|
||||
if(img) {
|
||||
int img_w = img->w();
|
||||
int img_h = img->h();
|
||||
|
||||
/*
|
||||
* Resize box according to size from IconSizes.
|
||||
*
|
||||
* Here is avoided image()->measure() since looks like
|
||||
* that function messes up icon's alpha blending if is widget
|
||||
* resizes (but not icon). This is a bug in fltk.
|
||||
*/
|
||||
if(isize >= ICONSIZE) {
|
||||
image_w = isize;
|
||||
image_h = isize;
|
||||
// resize box if icon is larger
|
||||
if(img_w > ICONSIZE || img_h > ICONSIZE)
|
||||
size(img_w + OFFSET_W, img_h + OFFSET_H);
|
||||
|
||||
resize(image_w + OFFSET_W, image_h + OFFSET_H);
|
||||
}
|
||||
|
||||
nn = ipath.c_str();
|
||||
image(fltk::SharedImage::get(nn));
|
||||
image(img);
|
||||
} else
|
||||
EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
EDEBUG(ESTRLOC ": Got label: %s\n", label());
|
||||
EDEBUG(ESTRLOC ": Got image: %s\n", settings->icon.c_str());
|
||||
EDEBUG(ESTRLOC ": Got x/y : %i %i\n", x(), y());
|
||||
*/
|
||||
//Use desktop color as color for icon background
|
||||
color(bg);
|
||||
|
||||
align(fltk::ALIGN_WRAP);
|
||||
align(FL_ALIGN_WRAP);
|
||||
update_label_size();
|
||||
|
||||
pmenu = new fltk::PopupMenu(0, 0, 100, 100);
|
||||
pmenu->begin();
|
||||
if(settings->type == ICON_TRASH) {
|
||||
edelib::Item* it = new edelib::Item(_("&Open"));
|
||||
it->offset_x(12, 12);
|
||||
it = new edelib::Item(_("&Properties"));
|
||||
it->offset_x(12, 12);
|
||||
new fltk::Divider();
|
||||
it = new edelib::Item(_("&Empty"));
|
||||
it->offset_x(12, 12);
|
||||
} else {
|
||||
edelib::Item* it = new edelib::Item(_("&Open"));
|
||||
it->offset_x(12, 12);
|
||||
it = new edelib::Item(_("&Rename"));
|
||||
it->offset_x(12, 12);
|
||||
it = new edelib::Item(_("&Delete"));
|
||||
it->offset_x(12, 12);
|
||||
it->callback(icon_delete_cb, this);
|
||||
new fltk::Divider();
|
||||
it = new edelib::Item(_("&Properties"));
|
||||
it->offset_x(12, 12);
|
||||
}
|
||||
pmenu->end();
|
||||
pmenu->type(fltk::PopupMenu::POPUP3);
|
||||
}
|
||||
|
||||
DesktopIcon::~DesktopIcon()
|
||||
{
|
||||
if(settings) {
|
||||
EDEBUG(ESTRLOC ": IconSettings clearing from ~DesktopIcon()\n");
|
||||
delete settings;
|
||||
}
|
||||
DesktopIcon::~DesktopIcon() {
|
||||
EDEBUG("DesktopIcon::~DesktopIcon()\n");
|
||||
|
||||
if(settings)
|
||||
delete settings;
|
||||
if(micon)
|
||||
delete micon;
|
||||
|
||||
if(pmenu)
|
||||
delete pmenu;
|
||||
}
|
||||
|
||||
void DesktopIcon::update_label_size(void) {
|
||||
lwidth = globals->label_maxwidth;
|
||||
lheight= 0;
|
||||
|
||||
// FIXME: really needed ???
|
||||
fltk::setfont(labelfont(), labelsize());
|
||||
/*
|
||||
* make sure current font size/type is set (internaly to fltk)
|
||||
* so fl_measure() can correctly calculate label width and height
|
||||
*/
|
||||
fl_font(labelfont(), labelsize());
|
||||
|
||||
//fltk::measure(label(), lwidth, lheight, fltk::ALIGN_WRAP);
|
||||
fltk::measure(label(), lwidth, lheight, flags());
|
||||
fl_measure(label(), lwidth, lheight, align());
|
||||
|
||||
lwidth += 8;
|
||||
lheight += 4;
|
||||
@ -172,7 +128,7 @@ void DesktopIcon::drag(int x, int y, bool apply) {
|
||||
if(apply) {
|
||||
position(micon->x(), micon->y());
|
||||
delete micon;
|
||||
micon = 0;
|
||||
micon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +136,7 @@ void DesktopIcon::drag(int x, int y, bool apply) {
|
||||
int DesktopIcon::drag_icon_x(void) {
|
||||
if(!micon)
|
||||
return x();
|
||||
else
|
||||
else
|
||||
return micon->x();
|
||||
}
|
||||
|
||||
@ -192,130 +148,94 @@ int DesktopIcon::drag_icon_y(void) {
|
||||
return micon->y();
|
||||
}
|
||||
|
||||
void DesktopIcon::draw(void) {
|
||||
if(image() && (damage() & fltk::DAMAGE_ALL)) {
|
||||
fltk::Image* ii = (fltk::Image*)image();
|
||||
int ix = (w()/2) - (ii->w()/2);
|
||||
/*
|
||||
* Make sure to pickup image's w() and h() since if fltk is compiled
|
||||
* with Xrender it will be scaled to rectangle's w()/h().
|
||||
*
|
||||
* On other hand, if fltk is _not_ compiled with Xrender,
|
||||
* scaling will not be done.
|
||||
* Yuck !
|
||||
*/
|
||||
fltk::Rectangle ir(ix, 5, ii->w(), ii->h());
|
||||
ii->draw(ir);
|
||||
void DesktopIcon::fast_redraw(void) {
|
||||
EASSERT(parent() != NULL && "Impossible !");
|
||||
|
||||
// LABEL_OFFSET + 2 include selection box line height too
|
||||
parent()->damage(FL_DAMAGE_ALL, x(), y(), w(), h() + lheight + LABEL_OFFSET + 2);
|
||||
}
|
||||
|
||||
void DesktopIcon::draw(void) {
|
||||
//draw_box(FL_UP_BOX, FL_BLACK);
|
||||
|
||||
if(image() && (damage() & FL_DAMAGE_ALL)) {
|
||||
Fl_Image* im = image();
|
||||
|
||||
// center image in the box
|
||||
int ix = (w()/2) - (im->w()/2);
|
||||
int iy = (h()/2) - (im->h()/2);
|
||||
ix += x();
|
||||
iy += y();
|
||||
|
||||
im->draw(ix, iy);
|
||||
}
|
||||
|
||||
if(globals->label_draw && (damage() & (fltk::DAMAGE_ALL | fltk::DAMAGE_CHILD_LABEL))) {
|
||||
int X = w()-(w()/2)-(lwidth/2);
|
||||
int Y = h()+2;
|
||||
if(globals->label_draw && (damage() & (FL_DAMAGE_ALL))) {
|
||||
int X = x() + w()-(w()/2)-(lwidth/2);
|
||||
int Y = y() + h() + LABEL_OFFSET;
|
||||
|
||||
Fl_Color old = fl_color();
|
||||
|
||||
if(!globals->label_transparent) {
|
||||
fltk::setcolor(globals->label_background);
|
||||
fltk::fillrect(X, Y, lwidth, lheight);
|
||||
fl_color(globals->label_background);
|
||||
fl_rectf(X, Y, lwidth, lheight);
|
||||
}
|
||||
|
||||
Rectangle r(X, Y, lwidth, lheight);
|
||||
|
||||
fltk::setcolor(globals->label_foreground);
|
||||
drawtext(label(), r, flags());
|
||||
fl_color(globals->label_foreground);
|
||||
fl_draw(label(), X, Y, lwidth, lheight, align(), 0, 0);
|
||||
|
||||
if(is_focused()) {
|
||||
/*
|
||||
* draw focused box on our way so later
|
||||
* this can be used to draw customised boxes
|
||||
*/
|
||||
fltk::line_style(fltk::DOT);
|
||||
fl_line_style(FL_DOT);
|
||||
|
||||
fltk::push_matrix();
|
||||
fl_color(globals->label_foreground);
|
||||
|
||||
//fltk::setcolor(fltk::WHITE);
|
||||
fltk::setcolor(globals->label_foreground);
|
||||
fltk::addvertex(X,Y);
|
||||
fltk::addvertex(X+lwidth,Y);
|
||||
fltk::addvertex(X+lwidth,Y+lheight);
|
||||
fltk::addvertex(X,Y+lheight);
|
||||
fltk::addvertex(X,Y);
|
||||
fltk::strokepath();
|
||||
|
||||
fltk::pop_matrix();
|
||||
fl_push_matrix();
|
||||
fl_begin_loop();
|
||||
fl_vertex(X,Y);
|
||||
fl_vertex(X+lwidth,Y);
|
||||
fl_vertex(X+lwidth,Y+lheight);
|
||||
fl_vertex(X,Y+lheight);
|
||||
fl_vertex(X,Y);
|
||||
fl_end_loop();
|
||||
fl_pop_matrix();
|
||||
|
||||
// revert to default line style
|
||||
fltk::line_style(0);
|
||||
fl_line_style(0);
|
||||
}
|
||||
|
||||
set_damage(damage() & ~fltk::DAMAGE_CHILD_LABEL);
|
||||
// revert to old color whatever that be
|
||||
fl_color(old);
|
||||
}
|
||||
}
|
||||
|
||||
int DesktopIcon::handle(int event) {
|
||||
switch(event) {
|
||||
case fltk::FOCUS:
|
||||
case fltk::UNFOCUS:
|
||||
return 1;
|
||||
|
||||
case fltk::ENTER:
|
||||
case fltk::LEAVE:
|
||||
return 1;
|
||||
/*
|
||||
* We have to handle fltk::MOVE too, if
|
||||
* want to get only once fltk::ENTER when
|
||||
* entered or fltk::LEAVE when leaved.
|
||||
*/
|
||||
case fltk::MOVE:
|
||||
return 1;
|
||||
case fltk::PUSH:
|
||||
if(fltk::event_button() == 3)
|
||||
pmenu->popup();
|
||||
return 1;
|
||||
case fltk::RELEASE:
|
||||
if(fltk::event_clicks() > 0)
|
||||
EDEBUG(ESTRLOC ": EXECUTE: %s\n", settings->cmd.c_str());
|
||||
return 1;
|
||||
|
||||
case fltk::DND_ENTER:
|
||||
EDEBUG("Icon DND_ENTER\n");
|
||||
return 1;
|
||||
case fltk::DND_DRAG:
|
||||
EDEBUG("Icon DND_DRAG\n");
|
||||
return 1;
|
||||
case fltk::DND_LEAVE:
|
||||
EDEBUG("Icon DND_LEAVE\n");
|
||||
return 1;
|
||||
case fltk::DND_RELEASE:
|
||||
EDEBUG("Icon DND_RELEASE\n");
|
||||
return 1;
|
||||
case fltk::PASTE:
|
||||
EDEBUG("Icon PASTE\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return fltk::Widget::handle(event);
|
||||
return Fl_Button::handle(event);
|
||||
}
|
||||
|
||||
MovableIcon::MovableIcon(DesktopIcon* ic) : fltk::Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) {
|
||||
MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) {
|
||||
EASSERT(icon != NULL);
|
||||
|
||||
set_override();
|
||||
create();
|
||||
color(ic->color());
|
||||
|
||||
fltk::Image* img = icon->icon_image();
|
||||
if(img)
|
||||
image(img);
|
||||
begin();
|
||||
icon_box = new Fl_Box(0, 0, w(), h());
|
||||
icon_box->image(ic->icon_image());
|
||||
end();
|
||||
}
|
||||
|
||||
MovableIcon::~MovableIcon() {
|
||||
}
|
||||
|
||||
void MovableIcon::show(void) {
|
||||
if(!shown())
|
||||
Fl_X::make_xid(this);
|
||||
#if 0
|
||||
if(img) {
|
||||
#ifdef SHAPE
|
||||
Pixmap mask = create_pixmap_mask(img->width(), img->height());
|
||||
XShapeCombineMask(fltk::xdisplay, fltk::xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
|
||||
#else
|
||||
image(img);
|
||||
#endif
|
||||
}
|
||||
Pixmap mask = create_mask((Fl_RGB_Image*)icon->icon_image());
|
||||
XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
|
||||
#endif
|
||||
}
|
||||
|
||||
MovableIcon::~MovableIcon()
|
||||
{
|
||||
}
|
||||
|
@ -13,16 +13,17 @@
|
||||
#ifndef __DESKTOPICON_H__
|
||||
#define __DESKTOPICON_H__
|
||||
|
||||
#include <fltk/Widget.h>
|
||||
#include <fltk/Window.h>
|
||||
#include <fltk/Image.h>
|
||||
#include <fltk/PopupMenu.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>
|
||||
|
||||
class GlobalIconSettings;
|
||||
class IconSettings;
|
||||
class MovableIcon;
|
||||
|
||||
class DesktopIcon : public fltk::Widget {
|
||||
class DesktopIcon : public Fl_Button {
|
||||
private:
|
||||
IconSettings* settings;
|
||||
const GlobalIconSettings* globals;
|
||||
@ -31,24 +32,33 @@ class DesktopIcon : public fltk::Widget {
|
||||
int lheight;
|
||||
bool focus;
|
||||
|
||||
// pseudosizes (nor real icon sizes)
|
||||
int image_w;
|
||||
int image_h;
|
||||
|
||||
fltk::PopupMenu* pmenu;
|
||||
MovableIcon* micon;
|
||||
|
||||
void update_label_size(void);
|
||||
|
||||
public:
|
||||
DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett);
|
||||
DesktopIcon(GlobalIconSettings* gisett, IconSettings* isett, int bg);
|
||||
~DesktopIcon();
|
||||
|
||||
virtual void draw(void);
|
||||
virtual int handle(int event);
|
||||
|
||||
void drag(int x, int y, bool apply);
|
||||
int drag_icon_x(void);
|
||||
int drag_icon_y(void);
|
||||
|
||||
/*
|
||||
* This is 'enhanced' (in some sense) redraw(). Redrawing
|
||||
* icon will not fully redraw label nor focus box, which laid outside
|
||||
* icon box. It will use damage() on given region, but called from
|
||||
* parent, so parent can redraw that region on itself (since label does
|
||||
* not laid on any box)
|
||||
*
|
||||
* Alternative way would be to redraw whole parent, but it is pretty unneeded
|
||||
* and slow.
|
||||
*/
|
||||
void fast_redraw(void);
|
||||
|
||||
/*
|
||||
* Here is implemented localy focus schema avoiding
|
||||
* messy fltk one. Focus/unfocus is handled from Desktop.
|
||||
@ -57,19 +67,20 @@ class DesktopIcon : public fltk::Widget {
|
||||
void do_unfocus(void) { focus = false; }
|
||||
bool is_focused(void) { return focus; }
|
||||
|
||||
fltk::Image* icon_image(void) { return (fltk::Image*)image(); }
|
||||
Fl_Image* icon_image(void) { return image(); }
|
||||
|
||||
const IconSettings* get_settings(void) const { return settings; }
|
||||
};
|
||||
|
||||
|
||||
class MovableIcon : public fltk::Window {
|
||||
class MovableIcon : public Fl_Window {
|
||||
private:
|
||||
DesktopIcon* icon;
|
||||
Fl_Box* icon_box;
|
||||
|
||||
public:
|
||||
MovableIcon(DesktopIcon* i);
|
||||
~MovableIcon();
|
||||
virtual void show(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -lfltk2_images -lpng -lfltk2_images -ljpeg -lz -lfltk2 -L/usr/X11R6/lib -lX11 -lXi -lXinerama -lpthread -lm -lXext -lstdc++ ;
|
||||
|
||||
LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -lfltk2_images -lpng -lfltk2_images -ljpeg -lz -lfltk2 -L/usr/X11R6/lib -lX11 -lXi -lXinerama -lpthread -lm -lXft -lXext -lstdc++ ;
|
||||
LINKLIBS += -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -L/usr/X11R6/lib -lfltk_images -lpng -lz -ljpeg -lfltk -ldl -lm -lXext -lX11 -lstdc++ ;
|
||||
|
||||
C++FLAGS += -g3 -I/opt/ede/include ;
|
||||
C++FLAGS += -Wall -g3 -I/opt/ede/include ;
|
||||
|
||||
Main eiconman : eiconman.cpp Utils.cpp DesktopIcon.cpp DesktopConfig.cpp ;
|
||||
Main eiconman : eiconman.cpp Utils.cpp Wallpaper.cpp DesktopIcon.cpp ;
|
||||
|
@ -12,9 +12,11 @@
|
||||
|
||||
#include "Utils.h"
|
||||
#include <X11/Xproto.h> // CARD32
|
||||
#include <fltk/x11.h>
|
||||
#include <FL/x.h>
|
||||
#include <edelib/Debug.h>
|
||||
|
||||
#include <string.h> // strrchr
|
||||
|
||||
Atom NET_WORKAREA = 0;
|
||||
Atom NET_WM_WINDOW_TYPE = 0;
|
||||
Atom NET_WM_WINDOW_TYPE_DESKTOP = 0;
|
||||
@ -27,20 +29,22 @@ int overlay_y = 0;
|
||||
int overlay_w = 0;
|
||||
int overlay_h = 0;
|
||||
|
||||
Fl_Window* overlay_drawable = NULL;
|
||||
|
||||
char dash_list[] = {1};
|
||||
|
||||
bool net_get_workarea(int& x, int& y, int& w, int &h) {
|
||||
Atom real;
|
||||
|
||||
if(!NET_WORKAREA)
|
||||
NET_WORKAREA= XInternAtom(fltk::xdisplay, "_NET_WORKAREA", 1);
|
||||
NET_WORKAREA= XInternAtom(fl_display, "_NET_WORKAREA", 1);
|
||||
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
unsigned char* prop;
|
||||
x = y = w = h = 0;
|
||||
|
||||
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen),
|
||||
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
NET_WORKAREA, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop);
|
||||
|
||||
if(status != Success)
|
||||
@ -60,18 +64,18 @@ bool net_get_workarea(int& x, int& y, int& w, int &h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void net_make_me_desktop(fltk::Window* w) {
|
||||
void net_make_me_desktop(Fl_Window* w) {
|
||||
if(!NET_WM_WINDOW_TYPE)
|
||||
NET_WM_WINDOW_TYPE = XInternAtom(fltk::xdisplay, "_NET_WM_WINDOW_TYPE", False);
|
||||
NET_WM_WINDOW_TYPE = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False);
|
||||
|
||||
if(!NET_WM_WINDOW_TYPE_DESKTOP)
|
||||
NET_WM_WINDOW_TYPE_DESKTOP= XInternAtom(fltk::xdisplay, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
|
||||
NET_WM_WINDOW_TYPE_DESKTOP= XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
|
||||
|
||||
/*
|
||||
* xid() will return zero if window is not shown;
|
||||
* make sure it is shown
|
||||
*/
|
||||
EASSERT(fltk::xid(w));
|
||||
EASSERT(fl_xid(w));
|
||||
|
||||
/*
|
||||
* Reminder for me (others possible):
|
||||
@ -80,20 +84,20 @@ void net_make_me_desktop(fltk::Window* w) {
|
||||
*
|
||||
* I lost two hours messing with this ! (gdb is unusefull in X world)
|
||||
*/
|
||||
XChangeProperty(fltk::xdisplay, fltk::xid(w), NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace,
|
||||
XChangeProperty(fl_display, fl_xid(w), NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace,
|
||||
(unsigned char*)&NET_WM_WINDOW_TYPE_DESKTOP, sizeof(Atom));
|
||||
}
|
||||
|
||||
int net_get_workspace_count(void) {
|
||||
if(!NET_NUMBER_OF_DESKTOPS)
|
||||
NET_NUMBER_OF_DESKTOPS = XInternAtom(fltk::xdisplay, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
NET_NUMBER_OF_DESKTOPS = XInternAtom(fl_display, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
|
||||
Atom real;
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
unsigned char* prop;
|
||||
|
||||
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen),
|
||||
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
NET_NUMBER_OF_DESKTOPS, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra,
|
||||
(unsigned char**)&prop);
|
||||
|
||||
@ -108,13 +112,13 @@ int net_get_workspace_count(void) {
|
||||
// desktops are starting from 0
|
||||
int net_get_current_desktop(void) {
|
||||
if(!NET_CURRENT_DESKTOP)
|
||||
NET_CURRENT_DESKTOP = XInternAtom(fltk::xdisplay, "_NET_CURRENT_DESKTOP", False);
|
||||
NET_CURRENT_DESKTOP = XInternAtom(fl_display, "_NET_CURRENT_DESKTOP", False);
|
||||
Atom real;
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
unsigned char* prop;
|
||||
|
||||
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen),
|
||||
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
NET_CURRENT_DESKTOP, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop);
|
||||
|
||||
if(status != Success && !prop)
|
||||
@ -128,11 +132,11 @@ int net_get_current_desktop(void) {
|
||||
// call on this XFreeStringList(names)
|
||||
int net_get_workspace_names(char**& names) {
|
||||
if(!NET_DESKTOP_NAMES)
|
||||
NET_DESKTOP_NAMES = XInternAtom(fltk::xdisplay, "_NET_DESKTOP_NAMES", False);
|
||||
NET_DESKTOP_NAMES = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
|
||||
|
||||
// FIXME: add _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED ???
|
||||
XTextProperty wnames;
|
||||
XGetTextProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), &wnames, NET_DESKTOP_NAMES);
|
||||
XGetTextProperty(fl_display, RootWindow(fl_display, fl_screen), &wnames, NET_DESKTOP_NAMES);
|
||||
|
||||
// if wm does not understainds _NET_DESKTOP_NAMES this is not set
|
||||
if(!wnames.nitems || !wnames.value)
|
||||
@ -152,14 +156,14 @@ int net_get_workspace_names(char**& names) {
|
||||
|
||||
#if 0
|
||||
int net_get_workspace_names(char** names) {
|
||||
Atom nd = XInternAtom(fltk::xdisplay, "_NET_DESKTOP_NAMES", False);
|
||||
Atom utf8_str = XInternAtom(fltk::xdisplay, "UTF8_STRING", False);
|
||||
Atom nd = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
|
||||
Atom utf8_str = XInternAtom(fl_display, "UTF8_STRING", False);
|
||||
Atom real;
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
unsigned char* prop;
|
||||
|
||||
int status = XGetWindowProperty(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen),
|
||||
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
nd, 0L, 0x7fffffff, False, utf8_str, &real, &format, &n, &extra, (unsigned char**)&prop);
|
||||
|
||||
if(status != Success && !prop)
|
||||
@ -185,16 +189,23 @@ void draw_overlay_rect(void) {
|
||||
if(overlay_w <= 0 || overlay_h <= 0)
|
||||
return;
|
||||
|
||||
XSetDashes(fltk::xdisplay, fltk::gc, 0, dash_list, 1);
|
||||
XSetLineAttributes(fltk::xdisplay, fltk::gc, 1, LineOnOffDash, CapButt, JoinMiter);
|
||||
XSetDashes(fl_display, fl_gc, 0, dash_list, 1);
|
||||
XSetLineAttributes(fl_display, fl_gc, 1, LineOnOffDash, CapButt, JoinMiter);
|
||||
|
||||
XSetFunction(fltk::xdisplay, fltk::gc, GXxor);
|
||||
XSetForeground(fltk::xdisplay, fltk::gc, 0xffffffff);
|
||||
XDrawRectangle(fltk::xdisplay, fltk::xwindow, fltk::gc, overlay_x, overlay_y, overlay_w-1, overlay_h-1);
|
||||
XSetFunction(fltk::xdisplay, fltk::gc, GXcopy);
|
||||
XSetFunction(fl_display, fl_gc, GXxor);
|
||||
XSetForeground(fl_display, fl_gc, 0xffffffff);
|
||||
|
||||
Window ow;
|
||||
if(overlay_drawable)
|
||||
ow = fl_xid(overlay_drawable);
|
||||
else
|
||||
ow = fl_window;
|
||||
XDrawRectangle(fl_display, ow, fl_gc, overlay_x, overlay_y, overlay_w-1, overlay_h-1);
|
||||
|
||||
XSetFunction(fl_display, fl_gc, GXcopy);
|
||||
|
||||
// set line to 0 again
|
||||
XSetLineAttributes(fltk::xdisplay, fltk::gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
||||
XSetLineAttributes(fl_display, fl_gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
void draw_xoverlay(int x, int y, int w, int h) {
|
||||
@ -230,3 +241,15 @@ void clear_xoverlay(void) {
|
||||
overlay_w = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_xoverlay_drawable(Fl_Window* win) {
|
||||
overlay_drawable = win;
|
||||
}
|
||||
|
||||
char* get_basename(const char* path) {
|
||||
char* p = strrchr(path, '/');
|
||||
if(p)
|
||||
return (p + 1);
|
||||
|
||||
return (char*) path;
|
||||
}
|
||||
|
@ -13,15 +13,23 @@
|
||||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
#include <fltk/Window.h>
|
||||
#include <FL/Fl_Window.h>
|
||||
#include <FL/Fl_Image.h>
|
||||
|
||||
#include <X11/Xlib.h> // Pixmap
|
||||
|
||||
int net_get_workspace_count(void);
|
||||
int net_get_current_desktop(void);
|
||||
bool net_get_workarea(int& x, int& y, int& w, int &h);
|
||||
void net_make_me_desktop(fltk::Window* w);
|
||||
void net_make_me_desktop(Fl_Window* w);
|
||||
int net_get_workspace_names(char**& names);
|
||||
|
||||
void draw_xoverlay(int x, int y, int w, int h);
|
||||
void clear_xoverlay(void);
|
||||
void set_xoverlay_drawable(Fl_Window* win);
|
||||
|
||||
Pixmap create_mask(Fl_RGB_Image* img);
|
||||
|
||||
char* get_basename(const char* path);
|
||||
|
||||
#endif
|
||||
|
87
eiconman/Wallpaper.cpp
Normal file
87
eiconman/Wallpaper.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Eiconman, desktop and icon manager
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2007 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Wallpaper.h"
|
||||
|
||||
#include <edelib/Debug.h>
|
||||
#include <FL/Fl_Shared_Image.h>
|
||||
#include <FL/fl_draw.h>
|
||||
|
||||
Wallpaper::Wallpaper(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H, 0), img(NULL), tiled(false) {
|
||||
}
|
||||
|
||||
Wallpaper::~Wallpaper() {
|
||||
}
|
||||
|
||||
bool Wallpaper::set(const char* path) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
tiled = false;
|
||||
|
||||
Fl_Image* i = Fl_Shared_Image::get(path);
|
||||
if(!i)
|
||||
return false;
|
||||
img = i;
|
||||
image(img);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wallpaper::set_tiled(const char* path) {
|
||||
bool ret = set(path);
|
||||
if(ret)
|
||||
tiled = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Wallpaper::draw(void) {
|
||||
if(!image())
|
||||
return;
|
||||
|
||||
int ix, iy, iw, ih;
|
||||
Fl_Image* im = image();
|
||||
|
||||
iw = im->w();
|
||||
ih = im->h();
|
||||
|
||||
if(iw == 0 || ih == 0)
|
||||
return;
|
||||
|
||||
if(ih < h() || iw < w()) {
|
||||
if(tiled) {
|
||||
// tile image across the box
|
||||
fl_push_clip(x(), y(), w(), h());
|
||||
int tx = x() - (x() % iw);
|
||||
int ty = y() - (y() % ih);
|
||||
int tw = w() + tx;
|
||||
int th = h() + ty;
|
||||
|
||||
for(int j = 0; j < th; j += ih)
|
||||
for(int i = 0; i < tw; i += iw)
|
||||
im->draw(i, j);
|
||||
|
||||
fl_pop_clip();
|
||||
return;
|
||||
} else {
|
||||
// center image in the box
|
||||
ix = (w()/2) - (iw/2);
|
||||
iy = (h()/2) - (ih/2);
|
||||
ix += x();
|
||||
iy += y();
|
||||
}
|
||||
} else {
|
||||
ix = x();
|
||||
iy = y();
|
||||
}
|
||||
|
||||
im->draw(ix, iy);
|
||||
}
|
37
eiconman/Wallpaper.h
Normal file
37
eiconman/Wallpaper.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Eiconman, desktop and icon manager
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2007 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef __WALLPAPER_H__
|
||||
#define __WALLPAPER_H__
|
||||
|
||||
#include <FL/Fl_Box.h>
|
||||
#include <FL/Fl_Image.h>
|
||||
|
||||
/*
|
||||
* Class responsible for displaying images at background
|
||||
* their scaling (TODO), caching(TODO) and making coffee at spear time.
|
||||
*/
|
||||
class Wallpaper : public Fl_Box {
|
||||
private:
|
||||
Fl_Image* img;
|
||||
bool tiled;
|
||||
|
||||
public:
|
||||
Wallpaper(int X, int Y, int W, int H);
|
||||
~Wallpaper();
|
||||
|
||||
bool set(const char* path);
|
||||
bool set_tiled(const char* path);
|
||||
virtual void draw(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
[Desktop]
|
||||
Color = 35
|
||||
Color = 45
|
||||
WallpaperUse = 0
|
||||
Wallpaper = /home/foo/xxx/baz/tax
|
||||
|
||||
|
@ -12,60 +12,38 @@
|
||||
|
||||
#include "eiconman.h"
|
||||
#include "DesktopIcon.h"
|
||||
#include "DesktopConfig.h"
|
||||
#include "Utils.h"
|
||||
#include "Wallpaper.h"
|
||||
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/Config.h>
|
||||
#include <edelib/Directory.h>
|
||||
#include <edelib/StrUtil.h>
|
||||
#include <edelib/File.h>
|
||||
#include <edelib/IconTheme.h>
|
||||
#include <edelib/Item.h>
|
||||
#include <edelib/Directory.h>
|
||||
#include <edelib/MimeType.h>
|
||||
#include <edelib/StrUtil.h>
|
||||
#include <edelib/IconTheme.h>
|
||||
|
||||
#include <fltk/Divider.h>
|
||||
#include <fltk/damage.h>
|
||||
#include <fltk/Color.h>
|
||||
#include <fltk/events.h>
|
||||
#include <fltk/run.h>
|
||||
#include <fltk/x11.h>
|
||||
#include <fltk/SharedImage.h>
|
||||
#include <FL/Fl.h>
|
||||
#include <FL/Fl_Shared_Image.h>
|
||||
#include <FL/x.h>
|
||||
#include <FL/Fl_Box.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <X11/Xproto.h> // CARD32
|
||||
|
||||
#include <stdlib.h> // rand, srand
|
||||
#include <time.h> // time
|
||||
#include <stdio.h> // snprintf
|
||||
|
||||
/*
|
||||
* NOTE: DO NOT set 'using namespace fltk' here
|
||||
* since fltk::Window will collide with Window from X11
|
||||
* resulting compilation errors.
|
||||
*
|
||||
* This is why I hate this namespace shit !
|
||||
*/
|
||||
#define CONFIG_NAME "eiconman.conf"
|
||||
|
||||
#define CONFIG_NAME "eiconman.conf"
|
||||
|
||||
#define SELECTION_SINGLE (fltk::event_button() == 1)
|
||||
#define SELECTION_MULTI (fltk::event_button() == 1 && \
|
||||
(fltk::get_key_state(fltk::LeftShiftKey) ||\
|
||||
fltk::get_key_state(fltk::RightShiftKey)))
|
||||
#define SELECTION_SINGLE (Fl::event_button() == 1)
|
||||
#define SELECTION_MULTI (Fl::event_button() == 1 && (Fl::event_key(FL_Shift_L) || Fl::event_key(FL_Shift_R)))
|
||||
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
/*
|
||||
* Added since fltk DAMAGE_OVERLAY value is used in few different contexts
|
||||
* and re-using it will do nothing. Yuck!
|
||||
*/
|
||||
#define EDAMAGE_OVERLAY 2
|
||||
// which widgets Fl::belowmouse() to skip
|
||||
#define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper))
|
||||
|
||||
Desktop* Desktop::pinstance = NULL;
|
||||
bool running = true;
|
||||
bool running = false;
|
||||
|
||||
inline unsigned int random_pos(int max) {
|
||||
return (rand() % max);
|
||||
@ -76,10 +54,10 @@ inline bool intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, i
|
||||
MAX(y1, y2) <= MIN(h1, h2));
|
||||
}
|
||||
|
||||
// assume fl_open_display() is called before
|
||||
inline void dpy_sizes(int& width, int& height) {
|
||||
fltk::open_display();
|
||||
width = DisplayWidth(fltk::xdisplay, fltk::xscreen);
|
||||
height = DisplayHeight(fltk::xdisplay, fltk::xscreen);
|
||||
width = DisplayWidth(fl_display, fl_screen);
|
||||
height = DisplayHeight(fl_display, fl_screen);
|
||||
}
|
||||
|
||||
void exit_signal(int signum) {
|
||||
@ -87,103 +65,43 @@ void exit_signal(int signum) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is used to notify desktop when _NET_CURRENT_DESKTOP is triggered.
|
||||
* FIXME: _NET_WORKAREA is nice thing that could set here too :)
|
||||
*
|
||||
* FIXME: XInternAtom should be placed somewhere else
|
||||
*/
|
||||
int desktop_xmessage_handler(int e, fltk::Window*) {
|
||||
Atom nd = XInternAtom(fltk::xdisplay, "_NET_CURRENT_DESKTOP", False);
|
||||
|
||||
if(fltk::xevent.type == PropertyNotify) {
|
||||
if(fltk::xevent.xproperty.atom == nd) {
|
||||
EDEBUG(ESTRLOC ": Desktop changed !!!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
void restart_signal(int signum) {
|
||||
EDEBUG(ESTRLOC ": Restarting (got signal %d)\n", signum);
|
||||
}
|
||||
|
||||
void background_cb(fltk::Widget*, void*) {
|
||||
DesktopConfig dc;
|
||||
dc.run();
|
||||
}
|
||||
int desktop_xmessage_handler(int event) { return 0; }
|
||||
|
||||
Desktop::Desktop() : fltk::Window(0, 0, 100, 100, "")
|
||||
{
|
||||
Desktop::Desktop() : Fl_Window(0, 0, 100, 100, "") {
|
||||
|
||||
selection_x = selection_y = 0;
|
||||
moving = false;
|
||||
|
||||
desktops_num = 0;
|
||||
curr_desktop = 0;
|
||||
|
||||
selbox = new SelectionOverlay;
|
||||
selbox->x = selbox->y = selbox->w = selbox->h = 0;
|
||||
selbox->show = false;
|
||||
|
||||
dsett = new DesktopSettings;
|
||||
dsett->color = 0;
|
||||
dsett->color = FL_GRAY;
|
||||
dsett->wp_use = false;
|
||||
dsett->wp_image = NULL;
|
||||
|
||||
// fallback if update_workarea() fails
|
||||
int dw, dh;
|
||||
dpy_sizes(dw, dh);
|
||||
resize(dw, dh);
|
||||
|
||||
update_workarea();
|
||||
|
||||
read_config();
|
||||
|
||||
/*
|
||||
* NOTE: order how childs are added is important. First
|
||||
* non iconable ones should be added (wallpaper, menu, ...)
|
||||
* then icons, so they can be drawn at top of them.
|
||||
*/
|
||||
begin();
|
||||
|
||||
pmenu = new fltk::PopupMenu(0, 0, 450, 50);
|
||||
pmenu->begin();
|
||||
edelib::Item* it = new edelib::Item(_("&New desktop item"));
|
||||
it->offset_x(12, 12);
|
||||
new fltk::Divider();
|
||||
it = new edelib::Item(_("&Line up vertical"));
|
||||
it->offset_x(12, 12);
|
||||
it = new edelib::Item(_("&Line up horizontal"));
|
||||
it->offset_x(12, 12);
|
||||
it = new edelib::Item(_("&Arrange by name"));
|
||||
it->offset_x(12, 12);
|
||||
new fltk::Divider();
|
||||
it = new edelib::Item(_("&Icon settings"));
|
||||
it->offset_x(12, 12);
|
||||
|
||||
edelib::Item* itbg = new edelib::Item(_("&Background settings"));
|
||||
itbg->offset_x(12, 12);
|
||||
itbg->callback(background_cb);
|
||||
pmenu->end();
|
||||
pmenu->type(fltk::PopupMenu::POPUP3);
|
||||
|
||||
wallpaper = new Wallpaper(0, 0, w(), h());
|
||||
//wallpaper->set_tiled("/home/sanel/wallpapers/katesmall.jpg");
|
||||
end();
|
||||
|
||||
if(dsett->wp_use)
|
||||
set_wallpaper(dsett->wp_path.c_str(), false);
|
||||
else
|
||||
set_bg_color(dsett->color, false);
|
||||
read_config();
|
||||
|
||||
set_bg_color(dsett->color, false);
|
||||
running = true;
|
||||
}
|
||||
|
||||
Desktop::~Desktop() {
|
||||
EDEBUG(ESTRLOC ": Desktop::~Desktop()\n");
|
||||
Desktop::~Desktop() {
|
||||
EDEBUG("Desktop::~Desktop()\n");
|
||||
|
||||
save_config();
|
||||
|
||||
if(selbox)
|
||||
delete selbox;
|
||||
|
||||
/*
|
||||
* icons member deleting is not needed, since add_icon will
|
||||
* append to icons and to fltk::Group array. Desktop at the end
|
||||
* will cleanup fltk::Group array.
|
||||
*/
|
||||
icons.clear();
|
||||
|
||||
if(dsett)
|
||||
delete dsett;
|
||||
delete dsett;
|
||||
}
|
||||
|
||||
void Desktop::init(void) {
|
||||
@ -205,49 +123,43 @@ Desktop* Desktop::instance(void) {
|
||||
return Desktop::pinstance;
|
||||
}
|
||||
|
||||
void Desktop::update_workarea(void) {
|
||||
int X,Y,W,H;
|
||||
if(net_get_workarea(X, Y, W, H))
|
||||
resize(X,Y,W,H);
|
||||
/*
|
||||
* This function must be overriden so window can inform
|
||||
* wm to see it as desktop. It will send data when window
|
||||
* is created, but before is shown.
|
||||
*/
|
||||
void Desktop::show(void) {
|
||||
if(!shown()) {
|
||||
Fl_X::make_xid(this);
|
||||
net_make_me_desktop(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Desktop::set_bg_color(unsigned int c, bool do_redraw) {
|
||||
EASSERT(dsett != NULL);
|
||||
/*
|
||||
* If someone intentionaly hide desktop
|
||||
* then quit from it.
|
||||
*/
|
||||
void Desktop::hide(void) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
void Desktop::update_workarea(void) {
|
||||
int X, Y, W, H;
|
||||
if(!net_get_workarea(X, Y, W, H)) {
|
||||
EWARNING(ESTRLOC ": wm does not support _NET_WM_WORKAREA; using screen sizes...\n");
|
||||
X = Y = 0;
|
||||
dpy_sizes(W, H);
|
||||
}
|
||||
|
||||
resize(X, Y, W, H);
|
||||
}
|
||||
|
||||
void Desktop::set_bg_color(int c, bool do_redraw) {
|
||||
if(color() == c)
|
||||
return;
|
||||
|
||||
dsett->color = c;
|
||||
color(c);
|
||||
|
||||
if(do_redraw)
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Desktop::set_wallpaper(const char* path, bool do_redraw) {
|
||||
EASSERT(path != NULL);
|
||||
EASSERT(dsett != NULL);
|
||||
/*
|
||||
* Prevent cases 'set_wallpaper(dsett->wp_path.c_str())' since assignement
|
||||
* will nullify pointers. Very hard to find bug! (believe me, after few hours)
|
||||
*/
|
||||
if(dsett->wp_path.c_str() != path)
|
||||
dsett->wp_path = path;
|
||||
|
||||
dsett->wp_image = fltk::SharedImage::get(path);
|
||||
/*
|
||||
* SharedImage::get() will return NULL if is unable to read the image
|
||||
* and that is exactly what is wanted here since draw() function will
|
||||
* skip drawing image in nulled case. Blame user for this :)
|
||||
*/
|
||||
image(dsett->wp_image);
|
||||
|
||||
if(do_redraw)
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Desktop::set_wallpaper(fltk::Image* im, bool do_redraw) {
|
||||
if(dsett->wp_image == im)
|
||||
return;
|
||||
|
||||
image(dsett->wp_image);
|
||||
if(do_redraw)
|
||||
redraw();
|
||||
}
|
||||
@ -255,7 +167,7 @@ void Desktop::set_wallpaper(fltk::Image* im, bool do_redraw) {
|
||||
void Desktop::read_config(void) {
|
||||
edelib::Config conf;
|
||||
if(!conf.load(CONFIG_NAME)) {
|
||||
EDEBUG(ESTRLOC ": Can't load %s, using default...\n", CONFIG_NAME);
|
||||
EWARNING(ESTRLOC ": Can't load %s, using default...\n", CONFIG_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -264,20 +176,17 @@ void Desktop::read_config(void) {
|
||||
* Add IconArea[X,Y,W,H] so icons can live
|
||||
* inside that area only (aka margins).
|
||||
*/
|
||||
|
||||
// read Desktop section
|
||||
int default_bg_color = fltk::BLUE;
|
||||
int default_bg_color = FL_BLUE;
|
||||
int default_wp_use = false;
|
||||
char wpath[256];
|
||||
|
||||
// read Desktop section
|
||||
conf.get("Desktop", "Color", dsett->color, default_bg_color);
|
||||
|
||||
if(conf.error() != edelib::CONF_ERR_SECTION) {
|
||||
conf.get("Desktop", "WallpaperUse", dsett->wp_use, default_wp_use);
|
||||
conf.get("Desktop", "Wallpaper", wpath, sizeof(wpath));
|
||||
|
||||
dsett->wp_path = wpath;
|
||||
|
||||
// keep path but disable wallpaper if file does not exists
|
||||
if(!edelib::file_exists(wpath)) {
|
||||
EDEBUG(ESTRLOC ": %s as wallpaper does not exists\n", wpath);
|
||||
@ -289,15 +198,14 @@ void Desktop::read_config(void) {
|
||||
}
|
||||
|
||||
// read Icons section
|
||||
conf.get("Icons", "Label Background", gisett.label_background, 46848);
|
||||
conf.get("Icons", "Label Foreground", gisett.label_foreground, fltk::WHITE);
|
||||
conf.get("Icons", "Label Background", gisett.label_background, FL_BLUE);
|
||||
conf.get("Icons", "Label Foreground", gisett.label_foreground, FL_WHITE);
|
||||
conf.get("Icons", "Label Fontsize", gisett.label_fontsize, 12);
|
||||
conf.get("Icons", "Label Maxwidth", gisett.label_maxwidth, 75);
|
||||
conf.get("Icons", "Label Transparent",gisett.label_transparent, false);
|
||||
conf.get("Icons", "Label Visible", gisett.label_draw, true);
|
||||
conf.get("Icons", "Gridspacing", gisett.gridspacing, 16);
|
||||
conf.get("Icons", "OneClickExec", gisett.one_click_exec, false);
|
||||
conf.get("Icons", "AutoArrange", gisett.auto_arr, true);
|
||||
conf.get("Icons", "AutoArrange", gisett.auto_arrange, true);
|
||||
|
||||
/*
|
||||
* Now try to load icons, first looking inside ~/Desktop directory
|
||||
@ -306,25 +214,17 @@ void Desktop::read_config(void) {
|
||||
*
|
||||
* FIXME: dir_exists() can't handle '~/Desktop' ???
|
||||
*/
|
||||
//load_icons("/home/sanel/Desktop", conf);
|
||||
edelib::String dd = edelib::dir_home();
|
||||
if(dd.empty()) {
|
||||
EWARNING(ESTRLOC ": Can't read home directory; icons will not be loaded\n");
|
||||
return;
|
||||
}
|
||||
dd += "/Desktop";
|
||||
load_icons(dd.c_str(), conf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
EDEBUG("----------------------------------------------------------\n");
|
||||
EDEBUG("d Color : %i\n", bg_color);
|
||||
EDEBUG("d WallpaperUse: %i\n", wp_use);
|
||||
EDEBUG("i label bkg : %i\n", gisett.label_background);
|
||||
EDEBUG("i label fg : %i\n", gisett.label_foreground);
|
||||
EDEBUG("i label fsize : %i\n", gisett.label_fontsize);
|
||||
EDEBUG("i label maxw : %i\n", gisett.label_maxwidth);
|
||||
EDEBUG("i label trans : %i\n", gisett.label_transparent);
|
||||
EDEBUG("i label vis : %i\n", gisett.label_draw);
|
||||
EDEBUG("i gridspace : %i\n", gisett.gridspacing);
|
||||
EDEBUG("i oneclick : %i\n", gisett.one_click_exec);
|
||||
EDEBUG("i auto_arr : %i\n", gisett.auto_arr);
|
||||
#endif
|
||||
void Desktop::save_config(void) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Desktop::load_icons(const char* path, edelib::Config& conf) {
|
||||
@ -372,15 +272,7 @@ void Desktop::load_icons(const char* path, edelib::Config& conf) {
|
||||
} else {
|
||||
// then try to figure out it's mime; if fails, ignore it
|
||||
if(mt.set(full_path.c_str())) {
|
||||
/*
|
||||
* FIXME: MimeType fails for directories
|
||||
* Temp solution untill that is fixed in edelib
|
||||
*/
|
||||
if(edelib::dir_exists(full_path.c_str()))
|
||||
is.icon = "folder";
|
||||
else
|
||||
is.icon = mt.icon_name();
|
||||
|
||||
is.icon = mt.icon_name();
|
||||
// icon label is name of file
|
||||
is.name = name;
|
||||
is.type = ICON_FILE;
|
||||
@ -402,13 +294,13 @@ void Desktop::load_icons(const char* path, edelib::Config& conf) {
|
||||
is.x = icon_x;
|
||||
is.y = icon_y;
|
||||
|
||||
DesktopIcon* dic = new DesktopIcon(&gisett, &is);
|
||||
DesktopIcon* dic = new DesktopIcon(&gisett, &is, dsett->color);
|
||||
add_icon(dic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reads .desktop file content
|
||||
// read .desktop files
|
||||
bool Desktop::read_desktop_file(const char* path, IconSettings& is) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
@ -499,82 +391,53 @@ bool Desktop::read_desktop_file(const char* path, IconSettings& is) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Desktop::save_config(void) {
|
||||
edelib::Config conf;
|
||||
|
||||
conf.set("Desktop", "Color", dsett->color);
|
||||
conf.set("Desktop", "WallpaperUse", dsett->wp_use);
|
||||
conf.set("Desktop", "Wallpaper", dsett->wp_path.c_str());
|
||||
|
||||
conf.set("Icons", "Label Background", gisett.label_background);
|
||||
conf.set("Icons", "Label Foreground", gisett.label_foreground);
|
||||
conf.set("Icons", "Label Fontsize", gisett.label_fontsize);
|
||||
conf.set("Icons", "Label Maxwidth", gisett.label_maxwidth);
|
||||
conf.set("Icons", "Label Transparent",gisett.label_transparent);
|
||||
conf.set("Icons", "Label Visible", gisett.label_draw);
|
||||
conf.set("Icons", "Gridspacing", gisett.gridspacing);
|
||||
conf.set("Icons", "OneClickExec", gisett.one_click_exec);
|
||||
conf.set("Icons", "AutoArrange", gisett.auto_arr);
|
||||
|
||||
unsigned int sz = icons.size();
|
||||
const IconSettings* is = NULL;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
is = icons[i]->get_settings();
|
||||
conf.set(is->key_name.c_str(), "X", icons[i]->x());
|
||||
conf.set(is->key_name.c_str(), "Y", icons[i]->y());
|
||||
}
|
||||
|
||||
if(!conf.save(CONFIG_NAME))
|
||||
EDEBUG(ESTRLOC ": Unable to save to %s\n", CONFIG_NAME);
|
||||
}
|
||||
|
||||
void Desktop::add_icon(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
icons.push_back(ic);
|
||||
add(ic);
|
||||
// FIXME: validate this
|
||||
add((Fl_Widget*)ic);
|
||||
}
|
||||
|
||||
void Desktop::move_selection(int x, int y, bool apply) {
|
||||
unsigned int sz = selectionbuff.size();
|
||||
if(sz == 0)
|
||||
return;
|
||||
|
||||
int prev_x, prev_y, tmp_x, tmp_y;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
prev_x = selectionbuff[i]->drag_icon_x();
|
||||
prev_y = selectionbuff[i]->drag_icon_y();
|
||||
|
||||
tmp_x = x - selection_x;
|
||||
tmp_y = y - selection_y;
|
||||
|
||||
selectionbuff[i]->drag(prev_x+tmp_x, prev_y+tmp_y, apply);
|
||||
|
||||
// very slow if is not checked
|
||||
if(apply == true)
|
||||
selectionbuff[i]->redraw();
|
||||
}
|
||||
|
||||
selection_x = x;
|
||||
selection_y = y;
|
||||
}
|
||||
|
||||
void Desktop::unfocus_all(void) {
|
||||
void Desktop::unfocus_all(void) {
|
||||
unsigned int sz = icons.size();
|
||||
DesktopIcon* ic;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
if(icons[i]->is_focused()) {
|
||||
icons[i]->do_unfocus();
|
||||
icons[i]->redraw();
|
||||
ic = icons[i];
|
||||
if(ic->is_focused()) {
|
||||
ic->do_unfocus();
|
||||
ic->fast_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
bool Desktop::in_selection(const DesktopIcon* ic) {
|
||||
void Desktop::select(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
if(in_selection(ic))
|
||||
return;
|
||||
|
||||
selectionbuff.push_back(ic);
|
||||
|
||||
if(!ic->is_focused()) {
|
||||
ic->do_focus();
|
||||
ic->fast_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void Desktop::select_only(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
unfocus_all();
|
||||
selectionbuff.clear();
|
||||
selectionbuff.push_back(ic);
|
||||
|
||||
ic->do_focus();
|
||||
ic->fast_redraw();
|
||||
}
|
||||
|
||||
bool Desktop::in_selection(const DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
unsigned int sz = selectionbuff.size();
|
||||
@ -586,94 +449,47 @@ bool Desktop::in_selection(const DesktopIcon* ic) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Desktop::select(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
if(in_selection(ic))
|
||||
void Desktop::move_selection(int x, int y, bool apply) {
|
||||
unsigned int sz = selectionbuff.size();
|
||||
if(sz == 0)
|
||||
return;
|
||||
|
||||
selectionbuff.push_back(ic);
|
||||
|
||||
if(!ic->is_focused()) {
|
||||
ic->do_focus();
|
||||
ic->redraw();
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Desktop::select_noredraw(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
if(in_selection(ic))
|
||||
return;
|
||||
selectionbuff.push_back(ic);
|
||||
}
|
||||
|
||||
void Desktop::select_only(DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
unfocus_all();
|
||||
|
||||
selectionbuff.clear();
|
||||
selectionbuff.push_back(ic);
|
||||
|
||||
ic->do_focus();
|
||||
ic->redraw();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Desktop::select_in_area(void) {
|
||||
if(!selbox->show)
|
||||
return;
|
||||
|
||||
int ax = selbox->x;
|
||||
int ay = selbox->y;
|
||||
int aw = selbox->w;
|
||||
int ah = selbox->h;
|
||||
|
||||
if(aw < 0) {
|
||||
ax += aw;
|
||||
aw = -aw;
|
||||
} else if(!aw)
|
||||
aw = 1;
|
||||
|
||||
if(ah < 0) {
|
||||
ay += ah;
|
||||
ah = -ah;
|
||||
} else if(!ah)
|
||||
ah = 1;
|
||||
|
||||
/*
|
||||
* XXX: This function can fail since icon coordinates are absolute (event_x_root)
|
||||
* but selbox use relative (event_root). It will work as expected if desktop is at x=0 y=0.
|
||||
* This should be checked further.
|
||||
*/
|
||||
unsigned int sz = icons.size();
|
||||
DesktopIcon* ic = NULL;
|
||||
int prev_x, prev_y, tmp_x, tmp_y;
|
||||
DesktopIcon* ic;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = icons[i];
|
||||
EASSERT(ic != NULL && "Impossible to happen");
|
||||
ic = selectionbuff[i];
|
||||
|
||||
if(intersects(ax, ay, ax+aw, ay+ah, ic->x(), ic->y(), ic->w()+ic->x(), ic->h()+ic->y())) {
|
||||
if(!ic->is_focused()) {
|
||||
ic->do_focus();
|
||||
ic->redraw();
|
||||
}
|
||||
} else {
|
||||
if(ic->is_focused()) {
|
||||
ic->do_unfocus();
|
||||
ic->redraw();
|
||||
}
|
||||
}
|
||||
prev_x = ic->drag_icon_x();
|
||||
prev_y = ic->drag_icon_y();
|
||||
|
||||
tmp_x = x - selection_x;
|
||||
tmp_y = y - selection_y;
|
||||
|
||||
ic->drag(prev_x + tmp_x, prev_y + tmp_y, apply);
|
||||
|
||||
// very slow if not checked
|
||||
if(apply == true)
|
||||
ic->fast_redraw();
|
||||
}
|
||||
|
||||
selection_x = x;
|
||||
selection_y = y;
|
||||
|
||||
/*
|
||||
* Redraw whole screen so it reflects
|
||||
* new icon position
|
||||
*/
|
||||
if(apply)
|
||||
redraw();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Tries to figure out icon below mouse (used for DND)
|
||||
* If fails, return NULL
|
||||
* Tries to figure out icon below mouse. It is alternative to
|
||||
* Fl::belowmouse() since with this we hunt only icons, not other
|
||||
* childs (wallpaper, menu), which can be returned by Fl::belowmouse()
|
||||
* and bad things be hapened.
|
||||
*/
|
||||
DesktopIcon* Desktop::below_mouse(int px, int py) {
|
||||
unsigned int sz = icons.size();
|
||||
@ -681,129 +497,39 @@ DesktopIcon* Desktop::below_mouse(int px, int py) {
|
||||
DesktopIcon* ic = NULL;
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = icons[i];
|
||||
EASSERT(ic != NULL && "Impossible to happen");
|
||||
|
||||
if(ic->x() < px && ic->y() < py && px < (ic->x() + ic->h()) && py < (ic->y() + ic->h()))
|
||||
return ic;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// used to drop dnd context on desktop figuring out what it can be
|
||||
void Desktop::drop_source(const char* src, int x, int y) {
|
||||
if(!src)
|
||||
return;
|
||||
IconSettings is;
|
||||
is.x = x;
|
||||
is.y = y;
|
||||
|
||||
// absolute path we (for now) see as non-url
|
||||
if(src[0] == '/')
|
||||
is.cmd_is_url = false;
|
||||
else
|
||||
is.cmd_is_url = true;
|
||||
|
||||
is.name = "XXX";
|
||||
is.cmd = "(none)";
|
||||
is.type = ICON_NORMAL;
|
||||
|
||||
edelib::MimeType mt;
|
||||
if(!mt.set(src)) {
|
||||
EDEBUG("MimeType for %s failed, not dropping icon\n", src);
|
||||
return;
|
||||
}
|
||||
|
||||
is.icon = mt.icon_name();
|
||||
|
||||
EDEBUG("---------> %s\n", is.icon.c_str());
|
||||
|
||||
DesktopIcon* dic = new DesktopIcon(&gisett, &is);
|
||||
add_icon(dic);
|
||||
}
|
||||
|
||||
void Desktop::draw(void) {
|
||||
#if 0
|
||||
if(damage() & fltk::DAMAGE_ALL) {
|
||||
fltk::Window::draw();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(damage() & fltk::DAMAGE_ALL) {
|
||||
clear_flag(fltk::HIGHLIGHT);
|
||||
|
||||
int nchild = children();
|
||||
if(damage() & ~fltk::DAMAGE_CHILD) {
|
||||
draw_box();
|
||||
draw_label();
|
||||
|
||||
for(int i = 0; i < nchild; i++) {
|
||||
fltk::Widget& ch = *child(i);
|
||||
draw_child(ch);
|
||||
draw_outside_label(ch);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < nchild; i++) {
|
||||
fltk::Widget& ch = *child(i);
|
||||
if(ch.damage() & fltk::DAMAGE_CHILD_LABEL) {
|
||||
draw_outside_label(ch);
|
||||
ch.set_damage(ch.damage() & ~fltk::DAMAGE_CHILD_LABEL);
|
||||
}
|
||||
update_child(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(damage() & (fltk::DAMAGE_ALL|EDAMAGE_OVERLAY)) {
|
||||
clear_xoverlay();
|
||||
|
||||
if(selbox->show)
|
||||
draw_xoverlay(selbox->x, selbox->y, selbox->w, selbox->h);
|
||||
/*
|
||||
* now scan all icons and see if they needs redraw, and if do
|
||||
* just update their label since it is indicator of selection
|
||||
*/
|
||||
for(int i = 0; i < children(); i++) {
|
||||
if(child(i)->damage() == fltk::DAMAGE_ALL) {
|
||||
child(i)->set_damage(fltk::DAMAGE_CHILD_LABEL);
|
||||
update_child(*child(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Desktop::handle(int event) {
|
||||
switch(event) {
|
||||
case fltk::FOCUS:
|
||||
case fltk::UNFOCUS:
|
||||
case FL_FOCUS:
|
||||
case FL_UNFOCUS:
|
||||
return 1;
|
||||
|
||||
case fltk::PUSH: {
|
||||
case FL_PUSH: {
|
||||
/*
|
||||
* First check where we clicked. If we do it on desktop
|
||||
* unfocus any possible focused childs, and handle
|
||||
* specific clicks. Otherwise, do rest for childs.
|
||||
*/
|
||||
fltk::Widget* clicked = fltk::belowmouse();
|
||||
EDEBUG(ESTRLOC ": %i\n", fltk::event_button());
|
||||
|
||||
if(clicked == this) {
|
||||
unfocus_all();
|
||||
Fl_Widget* clicked = Fl::belowmouse();
|
||||
|
||||
if(NOT_SELECTABLE(clicked)) {
|
||||
EDEBUG(ESTRLOC ": DESKTOP CLICK !!!\n");
|
||||
|
||||
if(!selectionbuff.empty())
|
||||
if(!selectionbuff.empty()) {
|
||||
/*
|
||||
* only focused are in selectionbuff, so this is
|
||||
* fine to do; also will prevent full redraw when
|
||||
* is clicked on desktop
|
||||
*/
|
||||
unfocus_all();
|
||||
selectionbuff.clear();
|
||||
|
||||
if(fltk::event_button() == 3)
|
||||
pmenu->popup();
|
||||
|
||||
// track position so moving can be deduced
|
||||
if(fltk::event_button() == 1) {
|
||||
selbox->x = fltk::event_x();
|
||||
selbox->y = fltk::event_y();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -818,15 +544,13 @@ int Desktop::handle(int event) {
|
||||
return 1;
|
||||
|
||||
if(SELECTION_MULTI) {
|
||||
fltk::event_is_click(0);
|
||||
Fl::event_is_click(0);
|
||||
select(tmp_icon);
|
||||
return 1;
|
||||
} else if (SELECTION_SINGLE) {
|
||||
|
||||
} else if(SELECTION_SINGLE) {
|
||||
if(!in_selection(tmp_icon))
|
||||
select_only(tmp_icon);
|
||||
|
||||
} else if (fltk::event_button() == 3)
|
||||
} else if(Fl::event_button() == 3)
|
||||
select_only(tmp_icon);
|
||||
|
||||
/*
|
||||
@ -834,157 +558,79 @@ int Desktop::handle(int event) {
|
||||
* Also prevent click on other mouse buttons during move.
|
||||
*/
|
||||
if(!moving)
|
||||
tmp_icon->handle(fltk::PUSH);
|
||||
tmp_icon->handle(FL_PUSH);
|
||||
|
||||
selection_x = fltk::event_x_root();
|
||||
selection_y = fltk::event_y_root();
|
||||
EDEBUG(ESTRLOC ": fltk::PUSH from desktop\n");
|
||||
EDEBUG(ESTRLOC ": FL_PUSH from desktop\n");
|
||||
selection_x = Fl::event_x_root();
|
||||
selection_y = Fl::event_y_root();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case fltk::DRAG:
|
||||
case FL_DRAG:
|
||||
moving = true;
|
||||
|
||||
if(!selectionbuff.empty()) {
|
||||
EDEBUG(ESTRLOC ": DRAG icon from desktop\n");
|
||||
move_selection(fltk::event_x_root(), fltk::event_y_root(), false);
|
||||
move_selection(Fl::event_x_root(), Fl::event_y_root(), false);
|
||||
} else {
|
||||
EDEBUG(ESTRLOC ": DRAG from desktop\n");
|
||||
|
||||
/*
|
||||
* Moving is started with pushed button.
|
||||
* From this point selection box is created and is rolled until release
|
||||
*/
|
||||
if(selbox->x != 0 || selbox->y != 0) {
|
||||
selbox->w = fltk::event_x() - selbox->x;
|
||||
selbox->h = fltk::event_y() - selbox->y;
|
||||
|
||||
selbox->show = true;
|
||||
|
||||
// see if there some icons inside selection area
|
||||
select_in_area();
|
||||
|
||||
// redraw selection box
|
||||
redraw(EDAMAGE_OVERLAY);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case fltk::RELEASE:
|
||||
case FL_RELEASE:
|
||||
EDEBUG(ESTRLOC ": RELEASE from desktop\n");
|
||||
EDEBUG(ESTRLOC ": clicks: %i\n", fltk::event_is_click());
|
||||
|
||||
if(selbox->show) {
|
||||
selbox->x = selbox->y = selbox->w = selbox->h = 0;
|
||||
selbox->show = false;
|
||||
redraw(EDAMAGE_OVERLAY);
|
||||
/*
|
||||
* Now pickup those who are in is_focused() state.
|
||||
* Here is not used select() since it will fill selectionbuff with
|
||||
* redrawing whole window each time. This is not what we want.
|
||||
*
|
||||
* Possible flickers due overlay will be later removed when is
|
||||
* called move_selection(), which will in turn redraw icons again
|
||||
* after position them.
|
||||
*/
|
||||
if(!selectionbuff.empty())
|
||||
selectionbuff.clear();
|
||||
|
||||
for(unsigned int i = 0; i < icons.size(); i++) {
|
||||
if(icons[i]->is_focused())
|
||||
select_noredraw(icons[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
EDEBUG(ESTRLOC ": clicks: %i\n", Fl::event_is_click());
|
||||
|
||||
if(!selectionbuff.empty() && moving)
|
||||
move_selection(fltk::event_x_root(), fltk::event_y_root(), true);
|
||||
move_selection(Fl::event_x_root(), Fl::event_y_root(), true);
|
||||
|
||||
/*
|
||||
* Do not send fltk::RELEASE during move
|
||||
* Do not send FL_RELEASE during move
|
||||
*
|
||||
* TODO: should be alowed fltk::RELEASE to multiple icons? (aka. run
|
||||
* TODO: should be alowed FL_RELEASE to multiple icons? (aka. run
|
||||
* command for all selected icons ?
|
||||
*/
|
||||
if(selectionbuff.size() == 1 && !moving)
|
||||
selectionbuff[0]->handle(fltk::RELEASE);
|
||||
selectionbuff[0]->handle(FL_RELEASE);
|
||||
|
||||
moving = false;
|
||||
return 1;
|
||||
|
||||
case fltk::DND_ENTER:
|
||||
case fltk::DND_DRAG:
|
||||
case fltk::DND_LEAVE:
|
||||
return 1;
|
||||
|
||||
case fltk::DND_RELEASE: {
|
||||
// fltk::belowmouse() can't be used within DND context :)
|
||||
DesktopIcon* di = below_mouse(fltk::event_x_root(), fltk::event_y_root());
|
||||
if(di) {
|
||||
di->handle(event);
|
||||
} else {
|
||||
EDEBUG("DND on DESKTOP\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case fltk::PASTE: {
|
||||
DesktopIcon* di = below_mouse(fltk::event_x_root(), fltk::event_y_root());
|
||||
if(di) {
|
||||
di->handle(event);
|
||||
} else {
|
||||
EDEBUG("PASTE on desktop with %s\n", fltk::event_text());
|
||||
drop_source(fltk::event_text(), fltk::event_x_root(), fltk::event_y_root());
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return fltk::Window::handle(event);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is executed before desktop is actually showed
|
||||
* but after is internally created so net_make_me_desktop() specific code can
|
||||
* be executed correctly.
|
||||
*
|
||||
* Calling net_make_me_desktop() after show() will confuse many wm's which will
|
||||
* in turn partialy register us as desktop type.
|
||||
*/
|
||||
void Desktop::create(void) {
|
||||
fltk::Window::create();
|
||||
net_make_me_desktop(this);
|
||||
return Fl_Window::handle(event);
|
||||
}
|
||||
|
||||
int main() {
|
||||
signal(SIGTERM, exit_signal);
|
||||
signal(SIGKILL, exit_signal);
|
||||
signal(SIGINT, exit_signal);
|
||||
signal(SIGINT, exit_signal);
|
||||
signal(SIGHUP, restart_signal);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
// TODO: init_locale_support()
|
||||
// a lot of preparing code depends on this
|
||||
fl_open_display();
|
||||
|
||||
fl_register_images();
|
||||
|
||||
//edelib::IconTheme::init("crystalsvg");
|
||||
edelib::IconTheme::init("edeneu");
|
||||
|
||||
fltk::register_images();
|
||||
|
||||
Desktop::init();
|
||||
Desktop::instance()->show();
|
||||
|
||||
/*
|
||||
* XSelectInput will redirect PropertyNotify messages, which
|
||||
* we are listen for
|
||||
* are listened for
|
||||
*/
|
||||
XSelectInput(fltk::xdisplay, RootWindow(fltk::xdisplay, fltk::xscreen), PropertyChangeMask | StructureNotifyMask );
|
||||
fltk::add_event_handler(desktop_xmessage_handler);
|
||||
XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask );
|
||||
Fl::add_handler(desktop_xmessage_handler);
|
||||
|
||||
while(running)
|
||||
fltk::wait();
|
||||
Fl::wait();
|
||||
|
||||
Desktop::shutdown();
|
||||
edelib::IconTheme::shutdown();
|
||||
|
@ -13,18 +13,19 @@
|
||||
#ifndef __EICONMAN_H__
|
||||
#define __EICONMAN_H__
|
||||
|
||||
#include <fltk/Window.h>
|
||||
#include <fltk/PopupMenu.h>
|
||||
#include <fltk/Image.h>
|
||||
#include <FL/Fl_Window.h>
|
||||
#include <FL/Fl_Double_Window.h>
|
||||
#include <FL/Fl_Image.h>
|
||||
|
||||
#include <edelib/String.h>
|
||||
#include <edelib/Config.h>
|
||||
#include <edelib/Vector.h>
|
||||
|
||||
#define EDAMAGE_LABEL 0x20
|
||||
|
||||
struct DesktopSettings {
|
||||
int color; // background color
|
||||
bool wp_use; // use wallpaper or not
|
||||
fltk::Image* wp_image; // wallpaper image (can be NULL)
|
||||
edelib::String wp_path; // wallpaper path
|
||||
};
|
||||
|
||||
struct GlobalIconSettings {
|
||||
@ -32,11 +33,10 @@ struct GlobalIconSettings {
|
||||
int label_foreground;
|
||||
int label_fontsize;
|
||||
int label_maxwidth;
|
||||
int gridspacing;
|
||||
bool label_transparent;
|
||||
bool label_draw;
|
||||
bool one_click_exec;
|
||||
bool auto_arr;
|
||||
bool auto_arrange;
|
||||
bool same_size;
|
||||
};
|
||||
|
||||
@ -53,8 +53,8 @@ struct GlobalIconSettings {
|
||||
* - symlink in ~/Desktop directory pointing to the real file
|
||||
*/
|
||||
struct IconSettings {
|
||||
int x, y;
|
||||
int type;
|
||||
int x, y;
|
||||
int type; // ICON_NORMAL, ICON_TRASH,...
|
||||
bool cmd_is_url; // interpret cmd as url, like system:/,trash:/,$HOME
|
||||
|
||||
edelib::String name;
|
||||
@ -64,79 +64,59 @@ struct IconSettings {
|
||||
edelib::String key_name; // name used as key when storing positions
|
||||
};
|
||||
|
||||
// selection overlay
|
||||
struct SelectionOverlay {
|
||||
int x, y, w, h;
|
||||
bool show;
|
||||
};
|
||||
|
||||
class Wallpaper;
|
||||
class DesktopIcon;
|
||||
|
||||
typedef edelib::vector<DesktopIcon*> DesktopIconList;
|
||||
|
||||
class Desktop : public fltk::Window {
|
||||
class Desktop : public Fl_Window {
|
||||
private:
|
||||
static Desktop* pinstance;
|
||||
|
||||
int desktops_num;
|
||||
int curr_desktop;
|
||||
int bg_color;
|
||||
bool wp_use;
|
||||
|
||||
int selection_x, selection_y;
|
||||
bool moving;
|
||||
int selection_x;
|
||||
int selection_y;
|
||||
|
||||
SelectionOverlay* selbox;
|
||||
|
||||
GlobalIconSettings gisett;
|
||||
IconSettings isett;
|
||||
|
||||
DesktopSettings* dsett;
|
||||
|
||||
Wallpaper* wallpaper;
|
||||
|
||||
DesktopIconList icons;
|
||||
DesktopIconList selectionbuff;
|
||||
|
||||
fltk::PopupMenu* pmenu;
|
||||
|
||||
void init_desktops(void);
|
||||
|
||||
void load_icons(const char* path, edelib::Config& conf);
|
||||
bool read_desktop_file(const char* path, IconSettings& is);
|
||||
|
||||
void add_icon(DesktopIcon* ic);
|
||||
|
||||
void unfocus_all(void);
|
||||
|
||||
void select(DesktopIcon* ic);
|
||||
void select_only(DesktopIcon* ic);
|
||||
bool in_selection(const DesktopIcon* ic);
|
||||
|
||||
void select_in_area(void);
|
||||
void select_noredraw(DesktopIcon* ic);
|
||||
|
||||
void move_selection(int x, int y, bool apply);
|
||||
|
||||
DesktopIcon* below_mouse(int x, int y);
|
||||
void drop_source(const char* src, int x, int y);
|
||||
//DesktopIcon* below_mouse(int px, int py);
|
||||
|
||||
public:
|
||||
Desktop();
|
||||
~Desktop();
|
||||
|
||||
virtual void show(void);
|
||||
virtual void hide(void);
|
||||
virtual int handle(int event);
|
||||
|
||||
static void init(void);
|
||||
static void shutdown(void);
|
||||
static Desktop* instance(void);
|
||||
|
||||
Desktop();
|
||||
~Desktop();
|
||||
void update_workarea(void);
|
||||
void read_config(void);
|
||||
void save_config(void);
|
||||
|
||||
void set_wallpaper(const char* path, bool do_redraw = true);
|
||||
void set_wallpaper(fltk::Image* im, bool do_redraw = true);
|
||||
void set_bg_color(unsigned int c, bool do_redraw = true);
|
||||
void update_workarea(void);
|
||||
void set_bg_color(int c, bool do_redraw = true);
|
||||
|
||||
void create(void);
|
||||
virtual void draw(void);
|
||||
virtual int handle(int event);
|
||||
Fl_Window* desktop_window(void) { return this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,87 +1,56 @@
|
||||
# data file for the FLTK User Interface Designer (FLUID)
|
||||
version 2.1000
|
||||
images_dir fltk::Choice
|
||||
# data file for the Fltk User Interface Designer (fluid)
|
||||
version 1.0108
|
||||
header_name {.h}
|
||||
code_name {.cxx}
|
||||
gridx 5
|
||||
gridy 5
|
||||
snap 1
|
||||
Function {} {open selected
|
||||
code_name {.cxx}
|
||||
Function {} {open
|
||||
} {
|
||||
{fltk::Window} {} {open
|
||||
xywh {363 251 540 260} resizable visible
|
||||
Fl_Window {} {open selected
|
||||
xywh {416 256 540 260} type Double resizable visible
|
||||
} {
|
||||
{fltk::InvisibleBox} {} {
|
||||
Fl_Box {} {
|
||||
xywh {75 173 100 15} box BORDER_BOX
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
Fl_Box {} {
|
||||
xywh {20 20 210 158} box THIN_UP_BOX
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
xywh {30 30 190 138} box DOWN_BOX color 56
|
||||
Fl_Box {} {
|
||||
xywh {33 30 184 138} box DOWN_BOX color 56
|
||||
code0 {/* box size is intentionaly odd so preserve aspect ratio */}
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
Fl_Box {} {
|
||||
xywh {50 183 145 14} box THIN_UP_BOX
|
||||
}
|
||||
{fltk::Choice} {} {
|
||||
label {Desktop:} open
|
||||
xywh {310 20 220 25}
|
||||
} {}
|
||||
{fltk::CheckButton} {} {
|
||||
label {Use wallpaper}
|
||||
xywh {310 60 20 19} align 8
|
||||
}
|
||||
{fltk::Input} {} {
|
||||
Fl_Input {} {
|
||||
label {Image:}
|
||||
xywh {310 94 190 25}
|
||||
xywh {310 55 190 25}
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
Fl_Button {} {
|
||||
label {...}
|
||||
xywh {505 94 25 25}
|
||||
xywh {505 55 25 25}
|
||||
}
|
||||
{fltk::Choice} {} {
|
||||
Fl_Choice {} {
|
||||
label {Mode:} open
|
||||
xywh {310 129 220 24}
|
||||
xywh {310 91 220 24} down_box BORDER_BOX
|
||||
} {}
|
||||
{fltk::Button} {} {
|
||||
Fl_Button {} {
|
||||
label {Background color}
|
||||
xywh {310 173 25 24} align 8 color 0x3ca700
|
||||
xywh {310 136 25 24} color 73 align 8
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
Fl_Button {} {
|
||||
label {&OK}
|
||||
xywh {250 227 90 25}
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
Fl_Button {} {
|
||||
label {&Apply}
|
||||
xywh {345 227 90 25}
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
Fl_Button {} {
|
||||
label {&Cancel}
|
||||
xywh {440 227 90 25}
|
||||
}
|
||||
{fltk::Group} {} {open
|
||||
xywh {20 210 210 40}
|
||||
} {
|
||||
{fltk::InvisibleBox} {} {
|
||||
xywh {15 5 35 30} box THIN_DOWN_BOX color 0xffff0000
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
label {@<}
|
||||
xywh {0 5 10 30} box FLAT_BOX
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
label {@>}
|
||||
xywh {200 5 10 30} box FLAT_BOX
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
xywh {55 5 35 30} box THIN_DOWN_BOX color 0x49a47d00
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
xywh {95 5 35 30} box THIN_DOWN_BOX color 0x3a488800
|
||||
}
|
||||
{fltk::InvisibleBox} {} {
|
||||
xywh {135 5 35 30} box THIN_DOWN_BOX color 0x808b3f00
|
||||
}
|
||||
Fl_Check_Button {} {
|
||||
label { Use wallpaper}
|
||||
xywh {310 20 220 25} down_box DOWN_BOX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user