mirror of https://github.com/fltk/fltk
Add ability to set custom icons for windows. STR #2816.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10197 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
332dc1b7ac
commit
f58b1a91b3
|
@ -22,6 +22,10 @@
|
|||
#ifndef Fl_Window_H
|
||||
#define Fl_Window_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "Fl_Group.H"
|
||||
|
||||
#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this
|
||||
|
@ -89,9 +93,19 @@ class FL_EXPORT Fl_Window : public Fl_Group {
|
|||
friend class Fl_X;
|
||||
Fl_X *i; // points at the system-specific stuff
|
||||
|
||||
struct icon_data {
|
||||
const void *legacy_icon;
|
||||
Fl_RGB_Image **icons;
|
||||
int count;
|
||||
#ifdef WIN32
|
||||
HICON big_icon;
|
||||
HICON small_icon;
|
||||
#endif
|
||||
};
|
||||
|
||||
const char* iconlabel_;
|
||||
char* xclass_;
|
||||
const void* icon_;
|
||||
struct icon_data *icon_;
|
||||
// size_range stuff:
|
||||
int minw, minh, maxw, maxh;
|
||||
int dw, dh, aspect;
|
||||
|
@ -141,6 +155,8 @@ protected:
|
|||
*/
|
||||
int force_position() const { return ((flags() & FORCE_POSITION)?1:0); }
|
||||
|
||||
void free_icons();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -370,6 +386,18 @@ public:
|
|||
static const char *default_xclass();
|
||||
const char* xclass() const;
|
||||
void xclass(const char* c);
|
||||
|
||||
static void default_icon(const Fl_RGB_Image*);
|
||||
static void default_icons(const Fl_RGB_Image*[], int);
|
||||
void icon(const Fl_RGB_Image*);
|
||||
void icons(const Fl_RGB_Image*[], int);
|
||||
|
||||
#ifdef WIN32
|
||||
static void default_icons(HICON big_icon, HICON small_icon);
|
||||
void icons(HICON big_icon, HICON small_icon);
|
||||
#endif
|
||||
|
||||
/* for legacy compatibility */
|
||||
const void* icon() const;
|
||||
void icon(const void * ic);
|
||||
|
||||
|
|
3
FL/mac.H
3
FL/mac.H
|
@ -142,6 +142,9 @@ public:
|
|||
void collapse(void);
|
||||
WindowRef window_ref(void);
|
||||
void set_key_window(void);
|
||||
// OS X doesn't have per window icons
|
||||
static void set_default_icons(const Fl_RGB_Image*[], int) {};
|
||||
void set_icons() {};
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
|
||||
|
|
|
@ -85,6 +85,9 @@ public:
|
|||
void flush() {w->flush();}
|
||||
void set_minmax(LPMINMAXINFO minmax);
|
||||
void mapraise();
|
||||
static void set_default_icons(const Fl_RGB_Image*[], int);
|
||||
static void set_default_icons(HICON, HICON);
|
||||
void set_icons();
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static Fl_X* make(Fl_Window*);
|
||||
|
|
2
FL/x.H
2
FL/x.H
|
@ -150,6 +150,8 @@ public:
|
|||
static Fl_X* i(const Fl_Window* wi) {return wi->i;}
|
||||
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
|
||||
void sendxjunk();
|
||||
static void set_default_icons(const Fl_RGB_Image*[], int);
|
||||
void set_icons();
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
|
||||
|
|
|
@ -1489,6 +1489,8 @@ void Fl_Window::hide() {
|
|||
handle(FL_HIDE);
|
||||
|
||||
#if defined(WIN32)
|
||||
// make sure any custom icons get freed
|
||||
icons(NULL, 0);
|
||||
// this little trick keeps the current clipboard alive, even if we are about
|
||||
// to destroy the window that owns the selection.
|
||||
if (GetClipboardOwner()==ip->xid)
|
||||
|
@ -1553,6 +1555,8 @@ Fl_Window::~Fl_Window() {
|
|||
if (xclass_) {
|
||||
free(xclass_);
|
||||
}
|
||||
free_icons();
|
||||
delete icon_;
|
||||
}
|
||||
|
||||
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <config.h>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/x.H>
|
||||
#include <FL/Fl_RGB_Image.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
|
@ -45,7 +46,8 @@ void Fl_Window::_Fl_Window() {
|
|||
}
|
||||
i = 0;
|
||||
xclass_ = 0;
|
||||
icon_ = 0;
|
||||
icon_ = new icon_data;
|
||||
memset(icon_, 0, sizeof(*icon_));
|
||||
iconlabel_ = 0;
|
||||
resizable(0);
|
||||
size_range_set = 0;
|
||||
|
@ -301,14 +303,118 @@ const char *Fl_Window::xclass() const
|
|||
}
|
||||
}
|
||||
|
||||
/** Gets the current icon window target dependent data. */
|
||||
const void *Fl_Window::icon() const {
|
||||
return icon_;
|
||||
/** Sets a single default window icon.
|
||||
|
||||
\param[in] icon default icon for all windows subsequently created
|
||||
|
||||
\see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::icons(const Fl_RGB_Image *[], int)
|
||||
*/
|
||||
void Fl_Window::default_icon(const Fl_RGB_Image *icon) {
|
||||
default_icons(&icon, 1);
|
||||
}
|
||||
|
||||
/** Sets the current icon window target dependent data. */
|
||||
/** Sets the default window icons.
|
||||
|
||||
The default icons are used for all windows that don't have their
|
||||
own icons set before show() is called. You can change the default
|
||||
icons whenever you want, but this only affects windows that are
|
||||
created (and shown) after this call.
|
||||
|
||||
The given images in \p icons are copied. You can use a local
|
||||
variable or free the images immediately after this call.
|
||||
|
||||
\param[in] icons default icons for all windows subsequently created
|
||||
\param[in] count number of images in \p icons. set to 0 to remove
|
||||
the current default icons
|
||||
|
||||
\see Fl_Window::default_icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::icons(const Fl_RGB_Image *[], int)
|
||||
*/
|
||||
void Fl_Window::default_icons(const Fl_RGB_Image *icons[], int count) {
|
||||
Fl_X::set_default_icons(icons, count);
|
||||
}
|
||||
|
||||
/** Sets a single window icon.
|
||||
|
||||
\param[in] icon icon for this window
|
||||
|
||||
\see Fl_Window::default_icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::icons(const Fl_RGB_Image *[], int)
|
||||
*/
|
||||
void Fl_Window::icon(const Fl_RGB_Image *icon) {
|
||||
icons(&icon, 1);
|
||||
}
|
||||
|
||||
/** Sets the window icons.
|
||||
|
||||
The given images in \p icons are copied. You can use a local
|
||||
variable or free the images immediately after this call.
|
||||
|
||||
\param[in] icons icons for this window
|
||||
\param[in] count number of images in \p icons. set to 0 to remove
|
||||
the current icons
|
||||
|
||||
\see Fl_Window::default_icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::icon(const Fl_RGB_Image *)
|
||||
*/
|
||||
void Fl_Window::icons(const Fl_RGB_Image *icons[], int count) {
|
||||
free_icons();
|
||||
|
||||
if (count > 0) {
|
||||
icon_->icons = new Fl_RGB_Image*[count];
|
||||
icon_->count = count;
|
||||
// FIXME: Fl_RGB_Image lacks const modifiers on methods
|
||||
for (int i = 0;i < count;i++)
|
||||
icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy();
|
||||
}
|
||||
|
||||
if (i)
|
||||
i->set_icons();
|
||||
}
|
||||
|
||||
/** Gets the current icon window target dependent data.
|
||||
\deprecated in 1.3.3
|
||||
*/
|
||||
const void *Fl_Window::icon() const {
|
||||
return icon_->legacy_icon;
|
||||
}
|
||||
|
||||
/** Sets the current icon window target dependent data.
|
||||
\deprecated in 1.3.3
|
||||
*/
|
||||
void Fl_Window::icon(const void * ic) {
|
||||
icon_ = ic;
|
||||
free_icons();
|
||||
icon_->legacy_icon = ic;
|
||||
}
|
||||
|
||||
void Fl_Window::free_icons() {
|
||||
int i;
|
||||
|
||||
icon_->legacy_icon = 0L;
|
||||
|
||||
if (icon_->icons) {
|
||||
for (i = 0;i < icon_->count;i++)
|
||||
delete icon_->icons[i];
|
||||
delete [] icon_->icons;
|
||||
icon_->icons = 0L;
|
||||
}
|
||||
|
||||
icon_->count = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
if (icon_->big_icon)
|
||||
DestroyIcon(icon_->big_icon);
|
||||
if (icon_->small_icon)
|
||||
DestroyIcon(icon_->small_icon);
|
||||
|
||||
icon_->big_icon = NULL;
|
||||
icon_->small_icon = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
|
324
src/Fl_win32.cxx
324
src/Fl_win32.cxx
|
@ -1820,6 +1820,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
|
|||
);
|
||||
if (lab) free(lab);
|
||||
|
||||
x->set_icons();
|
||||
|
||||
if (w->fullscreen_active()) {
|
||||
/* We need to make sure that the fullscreen is created on the
|
||||
default monitor, ie the desktop where the shortcut is located
|
||||
|
@ -2053,6 +2055,254 @@ void Fl_Window::label(const char *name,const char *iname) {
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
|
||||
int hotx, int hoty) {
|
||||
BITMAPV5HEADER bi;
|
||||
HBITMAP bitmap, mask;
|
||||
DWORD *bits;
|
||||
HICON icon;
|
||||
|
||||
if (!is_icon) {
|
||||
if ((hotx < 0) || (hotx >= image->w()))
|
||||
return NULL;
|
||||
if ((hoty < 0) || (hoty >= image->h()))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&bi, 0, sizeof(BITMAPV5HEADER));
|
||||
|
||||
bi.bV5Size = sizeof(BITMAPV5HEADER);
|
||||
bi.bV5Width = image->w();
|
||||
bi.bV5Height = -image->h(); // Negative for top-down
|
||||
bi.bV5Planes = 1;
|
||||
bi.bV5BitCount = 32;
|
||||
bi.bV5Compression = BI_BITFIELDS;
|
||||
bi.bV5RedMask = 0x00FF0000;
|
||||
bi.bV5GreenMask = 0x0000FF00;
|
||||
bi.bV5BlueMask = 0x000000FF;
|
||||
bi.bV5AlphaMask = 0xFF000000;
|
||||
|
||||
HDC hdc;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
if (bits == NULL)
|
||||
return NULL;
|
||||
|
||||
const uchar *i = (const uchar*)*image->data();
|
||||
for (int y = 0;y < image->h();y++) {
|
||||
for (int x = 0;x < image->w();x++) {
|
||||
switch (image->d()) {
|
||||
case 1:
|
||||
*bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
|
||||
break;
|
||||
case 2:
|
||||
*bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
|
||||
break;
|
||||
case 3:
|
||||
*bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
|
||||
break;
|
||||
case 4:
|
||||
*bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
|
||||
break;
|
||||
}
|
||||
i += image->d();
|
||||
bits++;
|
||||
}
|
||||
i += image->ld();
|
||||
}
|
||||
|
||||
// A mask bitmap is still needed even though it isn't used
|
||||
mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
|
||||
if (mask == NULL) {
|
||||
DeleteObject(bitmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ICONINFO ii;
|
||||
|
||||
ii.fIcon = is_icon;
|
||||
ii.xHotspot = hotx;
|
||||
ii.yHotspot = hoty;
|
||||
ii.hbmMask = mask;
|
||||
ii.hbmColor = bitmap;
|
||||
|
||||
icon = CreateIconIndirect(&ii);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(mask);
|
||||
|
||||
if (icon == NULL)
|
||||
return NULL;
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static HICON default_big_icon = NULL;
|
||||
static HICON default_small_icon = NULL;
|
||||
|
||||
static const Fl_RGB_Image *find_best_icon(int ideal_width,
|
||||
const Fl_RGB_Image *icons[],
|
||||
int count) {
|
||||
const Fl_RGB_Image *best;
|
||||
|
||||
best = NULL;
|
||||
|
||||
for (int i = 0;i < count;i++) {
|
||||
if (best == NULL)
|
||||
best = icons[i];
|
||||
else {
|
||||
if (best->w() < ideal_width) {
|
||||
if (icons[i]->w() > best->w())
|
||||
best = icons[i];
|
||||
} else {
|
||||
if ((icons[i]->w() >= ideal_width) &&
|
||||
(icons[i]->w() < best->w()))
|
||||
best = icons[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
|
||||
const Fl_RGB_Image *best_big, *best_small;
|
||||
|
||||
if (default_big_icon != NULL)
|
||||
DestroyIcon(default_big_icon);
|
||||
if (default_small_icon != NULL)
|
||||
DestroyIcon(default_small_icon);
|
||||
|
||||
default_big_icon = NULL;
|
||||
default_small_icon = NULL;
|
||||
|
||||
best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
|
||||
best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
|
||||
|
||||
if (best_big != NULL)
|
||||
default_big_icon = image_to_icon(best_big, true, 0, 0);
|
||||
|
||||
if (best_small != NULL)
|
||||
default_small_icon = image_to_icon(best_small, true, 0, 0);
|
||||
}
|
||||
|
||||
void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
|
||||
if (default_big_icon != NULL)
|
||||
DestroyIcon(default_big_icon);
|
||||
if (default_small_icon != NULL)
|
||||
DestroyIcon(default_small_icon);
|
||||
|
||||
default_big_icon = NULL;
|
||||
default_small_icon = NULL;
|
||||
|
||||
if (big_icon != NULL)
|
||||
default_big_icon = CopyIcon(big_icon);
|
||||
if (small_icon != NULL)
|
||||
default_small_icon = CopyIcon(small_icon);
|
||||
}
|
||||
|
||||
void Fl_X::set_icons() {
|
||||
HICON big_icon, small_icon;
|
||||
|
||||
// Windows doesn't copy the icons, so we have to "leak" them when
|
||||
// setting, and clean up when we change to some other icons.
|
||||
big_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_BIG, 0);
|
||||
if ((big_icon != NULL) && (big_icon != default_big_icon))
|
||||
DestroyIcon(big_icon);
|
||||
small_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_SMALL, 0);
|
||||
if ((small_icon != NULL) && (small_icon != default_small_icon))
|
||||
DestroyIcon(small_icon);
|
||||
|
||||
big_icon = NULL;
|
||||
small_icon = NULL;
|
||||
|
||||
if (w->icon_->count) {
|
||||
const Fl_RGB_Image *best_big, *best_small;
|
||||
|
||||
best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
|
||||
(const Fl_RGB_Image **)w->icon_->icons,
|
||||
w->icon_->count);
|
||||
best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
|
||||
(const Fl_RGB_Image **)w->icon_->icons,
|
||||
w->icon_->count);
|
||||
|
||||
if (best_big != NULL)
|
||||
big_icon = image_to_icon(best_big, true, 0, 0);
|
||||
if (best_small != NULL)
|
||||
small_icon = image_to_icon(best_small, true, 0, 0);
|
||||
} else {
|
||||
if ((w->icon_->big_icon != NULL) || (w->icon_->small_icon != NULL)) {
|
||||
big_icon = w->icon_->big_icon;
|
||||
small_icon = w->icon_->small_icon;
|
||||
} else {
|
||||
big_icon = default_big_icon;
|
||||
small_icon = default_small_icon;
|
||||
}
|
||||
}
|
||||
|
||||
SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
|
||||
SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
|
||||
}
|
||||
|
||||
/** Sets the default window icons.
|
||||
|
||||
Convenience function to set the default icons using Windows'
|
||||
native HICON icon handles.
|
||||
|
||||
The given icons are copied. You can free the icons immediately after
|
||||
this call.
|
||||
|
||||
\param[in] big_icon default large icon for all windows
|
||||
subsequently created
|
||||
\param[in] small_icon default small icon for all windows
|
||||
subsequently created
|
||||
|
||||
\see Fl_Window::default_icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::icons(HICON, HICON)
|
||||
*/
|
||||
void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
|
||||
Fl_X::set_default_icons(big_icon, small_icon);
|
||||
}
|
||||
|
||||
/** Sets the window icons.
|
||||
|
||||
Convenience function to set this window's icons using Windows'
|
||||
native HICON icon handles.
|
||||
|
||||
The given icons are copied. You can free the icons immediately after
|
||||
this call.
|
||||
|
||||
\param[in] big_icon large icon for this window
|
||||
\param[in] small_icon small icon for this windows
|
||||
|
||||
\see Fl_Window::default_icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
|
||||
\see Fl_Window::default_icons(HICON, HICON)
|
||||
\see Fl_Window::icon(const Fl_RGB_Image *)
|
||||
\see Fl_Window::icons(const Fl_RGB_Image *[], int)
|
||||
*/
|
||||
void Fl_Window::icons(HICON big_icon, HICON small_icon) {
|
||||
free_icons();
|
||||
|
||||
if (big_icon != NULL)
|
||||
icon_->big_icon = CopyIcon(big_icon);
|
||||
if (small_icon != NULL)
|
||||
icon_->small_icon = CopyIcon(small_icon);
|
||||
|
||||
if (i)
|
||||
i->set_icons();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef IDC_HAND
|
||||
# define IDC_HAND MAKEINTRESOURCE(32649)
|
||||
#endif // !IDC_HAND
|
||||
|
@ -2109,81 +2359,9 @@ int Fl_X::set_cursor(Fl_Cursor c) {
|
|||
}
|
||||
|
||||
int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
|
||||
BITMAPV5HEADER bi;
|
||||
HBITMAP bitmap, mask;
|
||||
DWORD *bits;
|
||||
HCURSOR new_cursor;
|
||||
|
||||
if ((hotx < 0) || (hotx >= image->w()))
|
||||
return 0;
|
||||
if ((hoty < 0) || (hoty >= image->h()))
|
||||
return 0;
|
||||
|
||||
memset(&bi, 0, sizeof(BITMAPV5HEADER));
|
||||
|
||||
bi.bV5Size = sizeof(BITMAPV5HEADER);
|
||||
bi.bV5Width = image->w();
|
||||
bi.bV5Height = -image->h(); // Negative for top-down
|
||||
bi.bV5Planes = 1;
|
||||
bi.bV5BitCount = 32;
|
||||
bi.bV5Compression = BI_BITFIELDS;
|
||||
bi.bV5RedMask = 0x00FF0000;
|
||||
bi.bV5GreenMask = 0x0000FF00;
|
||||
bi.bV5BlueMask = 0x000000FF;
|
||||
bi.bV5AlphaMask = 0xFF000000;
|
||||
|
||||
HDC hdc;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
if (bits == NULL)
|
||||
return 0;
|
||||
|
||||
const uchar *i = (const uchar*)*image->data();
|
||||
for (int y = 0;y < image->h();y++) {
|
||||
for (int x = 0;x < image->w();x++) {
|
||||
switch (image->d()) {
|
||||
case 1:
|
||||
*bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
|
||||
break;
|
||||
case 2:
|
||||
*bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
|
||||
break;
|
||||
case 3:
|
||||
*bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
|
||||
break;
|
||||
case 4:
|
||||
*bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
|
||||
break;
|
||||
}
|
||||
i += image->d();
|
||||
bits++;
|
||||
}
|
||||
i += image->ld();
|
||||
}
|
||||
|
||||
// A mask bitmap is still needed even though it isn't used
|
||||
mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
|
||||
if (mask == NULL) {
|
||||
DeleteObject(bitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ICONINFO ii;
|
||||
|
||||
ii.fIcon = FALSE;
|
||||
ii.xHotspot = hotx;
|
||||
ii.yHotspot = hoty;
|
||||
ii.hbmMask = mask;
|
||||
ii.hbmColor = bitmap;
|
||||
|
||||
new_cursor = CreateIconIndirect(&ii);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(mask);
|
||||
|
||||
new_cursor = image_to_icon(image, false, hotx, hoty);
|
||||
if (new_cursor == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
95
src/Fl_x.cxx
95
src/Fl_x.cxx
|
@ -352,6 +352,7 @@ Atom fl_NET_WM_STATE;
|
|||
Atom fl_NET_WM_STATE_FULLSCREEN;
|
||||
Atom fl_NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom fl_NET_WORKAREA;
|
||||
Atom fl_NET_WM_ICON;
|
||||
|
||||
/*
|
||||
X defines 32-bit-entities to have a format value of max. 32,
|
||||
|
@ -662,6 +663,7 @@ void fl_open_display(Display* d) {
|
|||
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
|
||||
fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
|
||||
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
|
||||
fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
|
||||
|
||||
if (sizeof(Atom) < 4)
|
||||
atom_bits = sizeof(Atom) * 8;
|
||||
|
@ -2480,12 +2482,14 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
|
|||
fl_show_iconic = 0;
|
||||
showit = 0;
|
||||
}
|
||||
if (win->icon()) {
|
||||
hints->icon_pixmap = (Pixmap)win->icon();
|
||||
if (win->icon_->legacy_icon) {
|
||||
hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
|
||||
hints->flags |= IconPixmapHint;
|
||||
}
|
||||
XSetWMHints(fl_display, xp->xid, hints);
|
||||
XFree(hints);
|
||||
|
||||
xp->set_icons();
|
||||
}
|
||||
|
||||
// set the window type for menu and tooltip windows to avoid animations (compiz)
|
||||
|
@ -2605,6 +2609,93 @@ void Fl_Window::size_range_() {
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned long *default_net_wm_icons = 0L;
|
||||
static size_t default_net_wm_icons_size = 0;
|
||||
|
||||
static void icons_to_property(const Fl_RGB_Image *icons[], int count,
|
||||
unsigned long **property, size_t *len) {
|
||||
size_t sz;
|
||||
unsigned long *data;
|
||||
|
||||
sz = 0;
|
||||
for (int i = 0;i < count;i++)
|
||||
sz += 2 + icons[i]->w() * icons[i]->h();
|
||||
|
||||
// FIXME: Might want to sort the icons
|
||||
|
||||
*property = data = new unsigned long[sz];
|
||||
*len = sz;
|
||||
|
||||
for (int i = 0;i < count;i++) {
|
||||
const Fl_RGB_Image *image;
|
||||
|
||||
image = icons[i];
|
||||
|
||||
data[0] = image->w();
|
||||
data[1] = image->h();
|
||||
data += 2;
|
||||
|
||||
const uchar *in = (const uchar*)*image->data();
|
||||
for (int y = 0;y < image->h();y++) {
|
||||
for (int x = 0;x < image->w();x++) {
|
||||
switch (image->d()) {
|
||||
case 1:
|
||||
*data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
|
||||
break;
|
||||
case 2:
|
||||
*data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
|
||||
break;
|
||||
case 3:
|
||||
*data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
|
||||
break;
|
||||
case 4:
|
||||
*data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
|
||||
break;
|
||||
}
|
||||
in += image->d();
|
||||
data++;
|
||||
}
|
||||
in += image->ld();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
|
||||
if (default_net_wm_icons) {
|
||||
delete [] default_net_wm_icons;
|
||||
default_net_wm_icons = 0L;
|
||||
default_net_wm_icons_size = 0;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
icons_to_property(icons, count,
|
||||
&default_net_wm_icons, &default_net_wm_icons_size);
|
||||
}
|
||||
|
||||
void Fl_X::set_icons() {
|
||||
unsigned long *net_wm_icons;
|
||||
size_t net_wm_icons_size;
|
||||
|
||||
if (w->icon_->count) {
|
||||
icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
|
||||
&net_wm_icons, &net_wm_icons_size);
|
||||
} else {
|
||||
net_wm_icons = default_net_wm_icons;
|
||||
net_wm_icons_size = default_net_wm_icons_size;
|
||||
}
|
||||
|
||||
XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
|
||||
|
||||
if (w->icon_->count) {
|
||||
delete [] net_wm_icons;
|
||||
net_wm_icons = 0L;
|
||||
net_wm_icons_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
int Fl_X::set_cursor(Fl_Cursor c) {
|
||||
unsigned int shape;
|
||||
Cursor xc;
|
||||
|
|
|
@ -82,6 +82,7 @@ CREATE_EXAMPLE(fonts fonts.cxx fltk)
|
|||
CREATE_EXAMPLE(forms forms.cxx "fltk;fltk_forms")
|
||||
CREATE_EXAMPLE(hello hello.cxx fltk)
|
||||
CREATE_EXAMPLE(help help.cxx "fltk;fltk_images")
|
||||
CREATE_EXAMPLE(icon icon.cxx fltk)
|
||||
CREATE_EXAMPLE(iconize iconize.cxx fltk)
|
||||
CREATE_EXAMPLE(image image.cxx fltk)
|
||||
CREATE_EXAMPLE(inactive inactive.fl fltk)
|
||||
|
|
|
@ -53,6 +53,7 @@ CPPFILES =\
|
|||
glpuzzle.cxx \
|
||||
hello.cxx \
|
||||
help.cxx \
|
||||
icon.cxx \
|
||||
iconize.cxx \
|
||||
image.cxx \
|
||||
inactive.cxx \
|
||||
|
@ -121,6 +122,7 @@ ALL = \
|
|||
forms$(EXEEXT) \
|
||||
hello$(EXEEXT) \
|
||||
help$(EXEEXT) \
|
||||
icon$(EXEEXT) \
|
||||
iconize$(EXEEXT) \
|
||||
image$(EXEEXT) \
|
||||
inactive$(EXEEXT) \
|
||||
|
@ -355,6 +357,8 @@ help$(EXEEXT): help.o $(IMGLIBNAME)
|
|||
$(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) help.o -o $@ $(LINKFLTKIMG) $(LDLIBS)
|
||||
$(OSX_ONLY) ../fltk-config --post $@
|
||||
|
||||
icon$(EXEEXT): icon.o
|
||||
|
||||
iconize$(EXEEXT): iconize.o
|
||||
|
||||
image$(EXEEXT): image.o
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Icon test program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Choice.H>
|
||||
#include <FL/Fl_RGB_Image.H>
|
||||
|
||||
static Fl_Double_Window *win;
|
||||
|
||||
void choice_cb(Fl_Widget *, void *v) {
|
||||
Fl_Color c = (Fl_Color)(fl_intptr_t)v;
|
||||
uchar buffer[32*32*3];
|
||||
Fl_RGB_Image icon(buffer, 32, 32, 3);
|
||||
icon.color_average(c, 0.0);
|
||||
win->icon(&icon);
|
||||
}
|
||||
|
||||
Fl_Menu_Item choices[] = {
|
||||
{"Red",0,choice_cb,(void*)FL_RED},
|
||||
{"Green",0,choice_cb,(void*)FL_GREEN},
|
||||
{"Blue",0,choice_cb,(void*)FL_BLUE},
|
||||
{0}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Fl_Double_Window window(400,300);
|
||||
win = &window;
|
||||
|
||||
Fl_Choice choice(80,100,200,25,"Colour:");
|
||||
choice.menu(choices);
|
||||
choice.callback(choice_cb);
|
||||
choice.when(FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);
|
||||
|
||||
window.end();
|
||||
window.show(argc,argv);
|
||||
return Fl::run();
|
||||
}
|
Loading…
Reference in New Issue