Selection overlay will now be correctly redrawed.

Tiled background code. Needs some cleanup.
This commit is contained in:
Sanel Zukan 2007-06-26 16:33:25 +00:00
parent 43268a4e8b
commit 0e53194249
4 changed files with 129 additions and 45 deletions

View File

@ -73,17 +73,17 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
edelib::String ipath = edelib::IconTheme::get(nn, edelib::ICON_SIZE_HUGE);
if(!ipath.empty()) {
Fl_Image* img = Fl_Shared_Image::get(ipath.c_str());
if(img) {
int img_w = img->w();
int img_h = img->h();
if(img) {
int img_w = img->w();
int img_h = img->h();
// resize box if icon is larger
if(img_w > ICONSIZE || img_h > ICONSIZE)
size(img_w + OFFSET_W, img_h + OFFSET_H);
// resize box if icon is larger
if(img_w > ICONSIZE || img_h > ICONSIZE)
size(img_w + OFFSET_W, img_h + OFFSET_H);
image(img);
} else
EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str());
image(img);
} else
EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str());
} else
EDEBUG(ESTRLOC ": Got empty icon name ?!?\n");
}
@ -189,7 +189,6 @@ void DesktopIcon::fast_redraw(void) {
// LABEL_OFFSET + 2 include selection box line height too
parent()->damage(FL_DAMAGE_ALL, x(), y(), w(), h() + lheight + LABEL_OFFSET + 2);
//parent()->damage(FL_DAMAGE_CHILD, x(), y(), w(), h() + lheight + LABEL_OFFSET + 2);
}
void DesktopIcon::draw(void) {
@ -207,7 +206,7 @@ void DesktopIcon::draw(void) {
im->draw(ix, iy);
}
if(globals->label_draw && (damage() & (FL_DAMAGE_ALL))) {
if(globals->label_draw && (damage() & (FL_DAMAGE_ALL | EDAMAGE_CHILD_LABEL))) {
int X = x() + w()-(w()/2)-(lwidth/2);
int Y = y() + h() + LABEL_OFFSET;

View File

@ -15,9 +15,12 @@
#include <edelib/Debug.h>
#include <FL/Fl_Shared_Image.h>
#include <FL/Fl_RGB_Image.h>
#include <FL/fl_draw.h>
#include <FL/x.h>
#include <string.h> // memcpy
#define CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask) \
tmp = 0; \
if(rshift >= 0) \
@ -288,6 +291,73 @@ Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
return pix;
}
int pixel_pos(int x, int y, int w, int d) {
return ((y * w) + x) * d;
}
bool create_tile(Fl_Image* orig, Fl_RGB_Image*& copied, int X, int Y, int W, int H) {
if(orig->w() >= W && orig->h() >= H)
return false;
int iw = orig->w();
int ih = orig->h();
int tx = X - (X % iw);
int ty = Y - (Y % ih);
int tw = W + tx;
int th = H + ty;
unsigned char* dest = new unsigned char[tw * th * orig->d()];
memset(dest, 0, tw * th * orig->d());
unsigned char* destptr = dest;
unsigned char* src = (unsigned char*)orig->data()[0];
int ppos = 0;
#if 0
// funny effect :)
for(int j = 0, cj = 0; j < th; j++, cj++) {
for(int i = 0, ci = 0; i < tw * orig->d(); i++, ci++) {
if(ci >= iw) ci = 0;
if(cj >= ih) cj = 0;
ppos = pixel_pos(ci, cj, iw, orig->d());
*destptr = src[ppos];
destptr++;
}
}
#endif
for(int j = 0, cj = 0; j < th; j++, cj++) {
for(int i = 0, ci = 0; i < tw; i++, ci++) {
if(ci > iw) ci = 0;
if(cj > ih) cj = 0;
ppos = pixel_pos(ci, cj, iw, orig->d());
if(orig->d() == 3 || orig->d() == 4) {
*destptr++ = src[ppos];
*destptr++ = src[ppos+1];
*destptr++ = src[ppos+2];
if(orig->d() == 4)
*destptr++ = src[ppos+3];
} else if(orig->d() == 2) {
*destptr++ = src[ppos];
*destptr++ = src[ppos+1];
} else
*destptr++ = src[ppos];
}
}
Fl_RGB_Image* c = new Fl_RGB_Image(dest, tw, th, orig->d(), orig->ld());
//Fl_RGB_Image* c = new Fl_RGB_Image(dest, iw, ih, orig->d(), orig->ld());
c->alloc_array = 1;
copied = c;
EDEBUG("==> %i %i\n", copied->w(), copied->h());
return true;
}
Wallpaper::Wallpaper(int X, int Y, int W, int H) :
Fl_Box(X, Y, W, H, 0), rootpmap_image(NULL), rootpmap_pixmap(0), img(NULL), tiled(false) {
}
@ -320,10 +390,27 @@ bool Wallpaper::set(const char* path) {
}
bool Wallpaper::set_tiled(const char* path) {
EASSERT(path != NULL);
Fl_Image* i = Fl_Shared_Image::get(path);
if(!i)
return false;
EDEBUG("==> %i \n", i->w());
EDEBUG("==> %i \n", i->h());
Fl_RGB_Image* res = 0;
create_tile(i, res, x(), y(), w(), h());
EDEBUG("---> %p\n", res);
EDEBUG("==> %i \n", res->w());
EDEBUG("==> %i \n", res->h());
//EDEBUG("==> %i \n", res->d());
image(res);
#if 0
bool ret = set(path);
if(ret)
tiled = true;
return ret;
#endif
}
void Wallpaper::set_rootpmap(void) {
@ -378,7 +465,7 @@ void Wallpaper::draw(void) {
if(iw == 0 || ih == 0)
return;
#if 0
if(ih < h() || iw < w()) {
if(tiled) {
// tile image across the box
@ -405,6 +492,9 @@ void Wallpaper::draw(void) {
ix = x();
iy = y();
}
#endif
ix = x();
iy = y();
im->draw(ix, iy);

View File

@ -36,7 +36,6 @@
#define CONFIG_NAME "eiconman.conf"
#define EDAMAGE_OVERLAY 0x20
#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)))
@ -91,7 +90,6 @@ int desktop_xmessage_handler(int event) {
return 1;
}
//if(fl_xevent->xclient.message_type == _XA_EDE_DESKTOP_NOTIFY_COLOR) {
if(fl_xevent->xproperty.atom == _XA_EDE_DESKTOP_NOTIFY_COLOR) {
Desktop::instance()->notify_box_color(ede_get_desktop_notify_color());
return 1;
@ -128,10 +126,13 @@ Desktop::Desktop() : DESKTOP_WINDOW(0, 0, 100, 100, "") {
*/
begin();
wallpaper = new Wallpaper(0, 0, w(), h());
wallpaper->set("/home/sanel/wallpapers/katebig.jpg");
//wallpaper->hide();
//wallpaper->set("/home/sanel/wallpapers/katebig.jpg");
//wallpaper->set_tiled("/home/sanel/wallpapers/katesmall.jpg");
//wallpaper->set_tiled("/home/sanelz/walls/katesmall.jpg");
//wallpaper->set_tiled("/home/sanelz/walls/kate.jpg");
//wallpaper->set("/home/sanelz/walls/katebig.jpg");
//wallpaper->set("/home/sanelz/walls/nin/1024x768-04.jpg");
//wallpaper->hide();
wallpaper->set("/home/sanelz/walls/nin/1024x768-04.jpg");
//wallpaper->set("/home/sanelz/walls/nin/1024x768-02.jpg");
notify = new NotifyBox(w(), h());
notify->hide();
@ -559,14 +560,19 @@ void Desktop::select_in_area(void) {
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->fast_redraw();
ic->redraw();
// updated from Desktop::draw()
ic->damage(EDAMAGE_CHILD_LABEL);
}
} else {
if(ic->is_focused()) {
ic->do_unfocus();
//ic->fast_redraw();
ic->redraw();
// updated from Desktop::draw()
ic->damage(EDAMAGE_CHILD_LABEL);
/*
* need to redraw whole screen since icon label is
* outside icon's drawable rectangle
*/
redraw();
}
}
}
@ -651,44 +657,32 @@ void Desktop::drop_source(const char* src, int src_len, int x, int y) {
}
void Desktop::draw(void) {
/*
if(damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) {
Fl_Group::draw();
EDEBUG("REDRAW ALL\n");
} */
if(damage() & (~FL_DAMAGE_CHILD & ~EDAMAGE_OVERLAY)) {
draw_box();
draw_label();
/*
* 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.
*/
clear_xoverlay();
Fl_Widget* const* a = array();
for(int i = children(); i--; ) {
Fl_Widget& o = **a++;
draw_child(o);
draw_outside_label(o);
}
} else if(damage() & FL_DAMAGE_CHILD) {
Fl_Widget* const* a = array();
for(int i = children(); i--; )
update_child(**a++);
DESKTOP_WINDOW::draw();
EDEBUG("REDRAW ALL\n");
}
if(damage() & (FL_DAMAGE_ALL | EDAMAGE_OVERLAY)) {
clear_xoverlay();
if(selbox->show) {
draw_xoverlay(selbox->x, selbox->y, selbox->w, selbox->h);
EDEBUG("DRAW OVERLAY\n");
}
} else
clear_xoverlay();
/*
* 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() == FL_DAMAGE_ALL) {
if(child(i)->damage() == EDAMAGE_CHILD_LABEL)
update_child(*child(i));
}
}
}
}

View File

@ -21,7 +21,8 @@
#include <edelib/Config.h>
#include <edelib/Vector.h>
#define EDAMAGE_LABEL 0x20
#define EDAMAGE_CHILD_LABEL 0x10
#define EDAMAGE_OVERLAY 0x20
struct DesktopSettings {
int color; // background color