STR#3093 continued: deleted the Fl_Shaped_Window class. Instead, added new member function Fl_Window::shape(Fl_Image*)

that gives a non-rectangular shape to a standard window. The benefit is that it works with Fl_Double_Window and Fl_Menu_Window as well.
It also works for free with Fl_Gl_Window on the X11 platform only.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10325 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2014-09-21 14:10:36 +00:00
parent 6781789948
commit f1b2c92fce
12 changed files with 216 additions and 259 deletions

View File

@ -1,78 +0,0 @@
//
// "$Id$"
//
// Fl_Shaped_Window header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2014 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 to:
//
// http://www.fltk.org/str.php
//
#ifndef Fl_Shaped_Window_H
#define Fl_Shaped_Window_H
#include <FL/Fl_Window.H>
#if defined(__APPLE__)
#include <FL/x.H>
#endif
class Fl_Bitmap;
class Fl_Pixmap;
/**
The Fl_Shaped_Window is an Fl_Window that can take an arbitrary shape (not just a rectangular region).
The window shape is determined by the argument of the Fl_Shaped_Window::shape(const Fl_Image*)
member function.
An Fl_Image of any dimension can be used as mask; it is rescaled to the window's dimension as needed.
The layout and widgets inside are unaware of the mask shape, and most will act as though the window's
rectangular bounding box is available
to them. It is up to you to make sure they adhere to the bounds of their masking shape.
On the Mac platform, OS version 10.4 or above is required.
On the unix/linux platform, the SHAPE extension of the X server is required.
The window borders and caption created by the window system are turned off by default. They
can be re-enabled by calling void Fl_Window::border(1).
A usage example is found at example/shapedwindow.cxx.
*/
class FL_EXPORT Fl_Shaped_Window : public Fl_Window {
private:
int lw_, lh_;
Fl_Image* shape_;
#if defined(__APPLE__)
CGImageRef mask;
#endif
Fl_Bitmap *todelete_;
void shape_bitmap_(Fl_Bitmap*);
void shape_pixmap_(Fl_Pixmap*);
void shape_alpha_(Fl_RGB_Image* img, int offset);
protected:
virtual void draw();
public:
Fl_Shaped_Window(int w, int h, const char* l = 0);
Fl_Shaped_Window(int x, int y, int w, int h, const char* l = 0);
~Fl_Shaped_Window();
void shape(const Fl_Image*);
/** Set the window's shape with an Fl_Image */
inline void shape(const Fl_Image& b) { shape(&b); }
#if ! (defined(WIN32) || defined(__APPLE__) || defined(FL_DOXYGEN))
void combine_mask(void);
#endif
};
#endif // Fl_Shaped_Window_H
//
// End of "$Id$".
//

View File

@ -27,14 +27,16 @@
#endif
#include "Fl_Group.H"
#include "Fl_Bitmap.H"
#include <stdlib.h>
#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this
#define FL_DOUBLE_WINDOW 0xF1 ///< double window type id
#define FL_SHAPED_WINDOW 0xF2 ///< shaped window type id
class Fl_X;
class Fl_RGB_Image;
/**
This widget produces an actual window. This can either be a main
window, with a border and title and all the window management controls,
@ -117,6 +119,40 @@ class FL_EXPORT Fl_Window : public Fl_Group {
// legacy, not used
Fl_Color cursor_fg, cursor_bg;
#endif
protected:
/** Data supporting a non-rectangular window shape */
struct shape_data_type {
int lw_; ///< width of shape image
int lh_; ///< height of shape image
Fl_Image* shape_; ///< shape image
#if defined(__APPLE__)
typedef struct CGImage* CGImageRef;
CGImageRef mask;
#endif
Fl_Bitmap *todelete_; ///< auxiliary bitmap image
};
#if FLTK_ABI_VERSION < 10303 && !defined(FL_DOXYGEN)
static
#endif
shape_data_type *shape_data_; ///< non-null means the window has a non-rectangular shape
private:
void shape_bitmap_(Fl_Bitmap* b);
void shape_alpha_(Fl_RGB_Image* img, int offset);
void shape_pixmap_(Fl_Pixmap* pixmap);
public:
void shape(const Fl_Image* img);
/** Set the window's shape with an Fl_Image.
\see void shape(const Fl_Image* img)
*/
inline void shape(const Fl_Image& b) { shape(&b); }
#if ! (defined(WIN32) || defined(__APPLE__) || defined(FL_DOXYGEN))
void combine_mask(void);
#endif
private:
void size_range_();
void _Fl_Window(); // constructor innards
void fullscreen_x(); // platform-specific part of sending a window to full screen
@ -280,7 +316,7 @@ public:
/** Returns true if this window is a menu window. */
unsigned int menu_window() const {return flags() & MENU_WINDOW;}
/**
Marks the window as a tooltip window.

View File

@ -20,7 +20,7 @@
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <FL/Fl.H>
#include <FL/Fl_Shaped_Window.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Tiled_Image.H>
#include <FL/Fl_Image_Surface.H>
@ -91,7 +91,7 @@ Fl_RGB_Image* prepare_shape(int w)
int main(int argc, char **argv) {
int dim = 200;
Fl_Shaped_Window *win = new Fl_Shaped_Window(100, 100, dim, dim, "Testing1");
Fl_Double_Window *win = new Fl_Double_Window(100, 100, dim, dim, "Testing1");
Fl_RGB_Image *img = prepare_shape(dim);
win->shape(img);
dragbox *box = new dragbox(0, 0, win->w(), win->h());

View File

@ -328,10 +328,10 @@
7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */; };
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
7F6F526219CF0F530075F408 /* Fl_Window_shape.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F6F526119CF0F530075F408 /* Fl_Window_shape.cxx */; };
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 299E717718BC503400FF83F2 /* fl_gleam.cxx */; };
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */; };
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */; };
7FD807F719ADD610007622B2 /* Fl_Shaped_Window.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */; };
7FFDD15A19BE072000779AD1 /* Fl_PostScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDD15919BE072000779AD1 /* Fl_PostScript.cxx */; };
7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */; };
812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; };
@ -4340,6 +4340,7 @@
7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_cocoa.mm; path = ../../src/Fl_cocoa.mm; sourceTree = SOURCE_ROOT; };
7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Native_File_Chooser_MAC.mm; path = ../../src/Fl_Native_File_Chooser_MAC.mm; sourceTree = SOURCE_ROOT; };
7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Quartz_Printer.mm; path = ../../src/Fl_Quartz_Printer.mm; sourceTree = SOURCE_ROOT; };
7F6F526119CF0F530075F408 /* Fl_Window_shape.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Window_shape.cxx; path = ../../src/Fl_Window_shape.cxx; sourceTree = "<group>"; };
7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Copy_Surface.cxx; path = ../../src/Fl_Copy_Surface.cxx; sourceTree = SOURCE_ROOT; };
7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Image_Surface.cxx; path = ../../src/Fl_Image_Surface.cxx; sourceTree = SOURCE_ROOT; };
7F76E019192FAD740071728B /* Fl_Copy_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Copy_Surface.H; path = ../../FL/Fl_Copy_Surface.H; sourceTree = SOURCE_ROOT; };
@ -4347,8 +4348,6 @@
7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; };
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
7FD807F419ADD5F4007622B2 /* Fl_Shaped_Window.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Shaped_Window.H; path = ../../FL/Fl_Shaped_Window.H; sourceTree = SOURCE_ROOT; };
7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Shaped_Window.cxx; path = ../../src/Fl_Shaped_Window.cxx; sourceTree = SOURCE_ROOT; };
7FFDD15919BE072000779AD1 /* Fl_PostScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_PostScript.cxx; path = ../../src/Fl_PostScript.cxx; sourceTree = "<group>"; };
7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; };
@ -5508,7 +5507,6 @@
13BCF00369D5254F0CE49599 /* Fl_Round_Button.cxx */,
3F60A41762817C834FF38947 /* Fl_Scroll.cxx */,
A5B9A5CE605BB8A57F66A2E6 /* Fl_Scrollbar.cxx */,
7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */,
57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */,
9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */,
5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */,
@ -5534,6 +5532,7 @@
F42EEFA08A75F71B33094D50 /* Fl_Window_fullscreen.cxx */,
CC2482EC04B752BF38D4DBE2 /* Fl_Window_hotspot.cxx */,
9E22773911BDBADEA86730D4 /* Fl_Window_iconize.cxx */,
7F6F526119CF0F530075F408 /* Fl_Window_shape.cxx */,
9951B49F640C2C15321EED9C /* Fl_Wizard.cxx */,
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */,
0CBC6DC7942212D47B70681B /* Fl_XPM_Image.cxx */,
@ -6297,7 +6296,6 @@
28F3E4EBB6E5F8420624A5DA /* Fl_Scrollbar.H */,
42FEA3A2967D04217C27FA61 /* Fl_Secret_Input.H */,
9DA766AE10DC532F3D0401A2 /* Fl_Select_Browser.H */,
7FD807F419ADD5F4007622B2 /* Fl_Shaped_Window.H */,
A46A39199806D09CE0ABEE59 /* Fl_Shared_Image.H */,
9B57B581401BD8575BFAF2F1 /* Fl_Simple_Counter.H */,
0EC11A5CAD4E3607A72BEF84 /* Fl_Single_Window.H */,
@ -9438,6 +9436,7 @@
DB29DA4D89702B490E69B569 /* Fl_Table.cxx in Sources */,
644FEEF43A0CCBD89E2CE6FC /* Fl_Table_Row.cxx in Sources */,
CDCB453B3493D8E96E80DFF7 /* Fl_Tabs.cxx in Sources */,
7F6F526219CF0F530075F408 /* Fl_Window_shape.cxx in Sources */,
FB93EB94C997FC6F8C5D389D /* Fl_Text_Buffer.cxx in Sources */,
4536387C357FBA58B3C5258B /* Fl_Text_Display.cxx in Sources */,
8F77031B8CCFF315D4CB151E /* Fl_Text_Editor.cxx in Sources */,
@ -9534,7 +9533,6 @@
01C68DB0192C6089000BD75C /* Fl_sleep.cxx in Sources */,
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */,
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */,
7FD807F719ADD610007622B2 /* Fl_Shaped_Window.cxx in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -328,9 +328,9 @@
7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */; };
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
7F6F526419CF0FED0075F408 /* Fl_Window_shape.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F6F526319CF0FED0075F408 /* Fl_Window_shape.cxx */; };
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BD192FAEBB00519823 /* Fl_Copy_Surface.cxx */; };
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BF192FAECA00519823 /* Fl_Image_Surface.cxx */; };
7FD8085119ADD6F2007622B2 /* Fl_Shaped_Window.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */; };
7FDBB8F416B2D1EA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032516B1A90A000FC50F /* Localizable.strings */; };
7FDBB8F516B2D1EE00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032216B1A909000FC50F /* Localizable.strings */; };
7FDBB8F616B2D1FA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031F16B1A909000FC50F /* Localizable.strings */; };
@ -4330,6 +4330,7 @@
7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_cocoa.mm; path = ../../src/Fl_cocoa.mm; sourceTree = SOURCE_ROOT; };
7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Native_File_Chooser_MAC.mm; path = ../../src/Fl_Native_File_Chooser_MAC.mm; sourceTree = SOURCE_ROOT; };
7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Quartz_Printer.mm; path = ../../src/Fl_Quartz_Printer.mm; sourceTree = SOURCE_ROOT; };
7F6F526319CF0FED0075F408 /* Fl_Window_shape.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Window_shape.cxx; path = ../../src/Fl_Window_shape.cxx; sourceTree = "<group>"; };
7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; };
7F92031A16B1A909000FC50F /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = Localizable.strings; sourceTree = "<group>"; };
7F92031D16B1A909000FC50F /* French */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = French; path = Localizable.strings; sourceTree = "<group>"; };
@ -4342,8 +4343,6 @@
7FA5C2C2192FAEF200519823 /* Fl_Copy_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Copy_Surface.H; path = ../../FL/Fl_Copy_Surface.H; sourceTree = SOURCE_ROOT; };
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
7FD8084F19ADD6DE007622B2 /* Fl_Shaped_Window.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Shaped_Window.H; path = ../../FL/Fl_Shaped_Window.H; sourceTree = SOURCE_ROOT; };
7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Shaped_Window.cxx; path = ../../src/Fl_Shaped_Window.cxx; sourceTree = SOURCE_ROOT; };
7FFDD15B19BE08A800779AD1 /* Fl_PostScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_PostScript.cxx; path = ../../src/Fl_PostScript.cxx; sourceTree = "<group>"; };
7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; };
@ -5502,7 +5501,6 @@
13BCF00369D5254F0CE49599 /* Fl_Round_Button.cxx */,
3F60A41762817C834FF38947 /* Fl_Scroll.cxx */,
A5B9A5CE605BB8A57F66A2E6 /* Fl_Scrollbar.cxx */,
7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */,
57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */,
9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */,
5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */,
@ -5528,6 +5526,7 @@
F42EEFA08A75F71B33094D50 /* Fl_Window_fullscreen.cxx */,
CC2482EC04B752BF38D4DBE2 /* Fl_Window_hotspot.cxx */,
9E22773911BDBADEA86730D4 /* Fl_Window_iconize.cxx */,
7F6F526319CF0FED0075F408 /* Fl_Window_shape.cxx */,
9951B49F640C2C15321EED9C /* Fl_Wizard.cxx */,
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */,
0CBC6DC7942212D47B70681B /* Fl_XPM_Image.cxx */,
@ -6336,7 +6335,6 @@
28F3E4EBB6E5F8420624A5DA /* Fl_Scrollbar.H */,
42FEA3A2967D04217C27FA61 /* Fl_Secret_Input.H */,
9DA766AE10DC532F3D0401A2 /* Fl_Select_Browser.H */,
7FD8084F19ADD6DE007622B2 /* Fl_Shaped_Window.H */,
A46A39199806D09CE0ABEE59 /* Fl_Shared_Image.H */,
9B57B581401BD8575BFAF2F1 /* Fl_Simple_Counter.H */,
0EC11A5CAD4E3607A72BEF84 /* Fl_Single_Window.H */,
@ -9526,6 +9524,7 @@
7FFDD15C19BE08A800779AD1 /* Fl_PostScript.cxx in Sources */,
2C8EFE6F2A1297FB4B263B2A /* fl_cursor.cxx in Sources */,
5DE5BC3242C44595E62FA505 /* fl_curve.cxx in Sources */,
7F6F526419CF0FED0075F408 /* Fl_Window_shape.cxx in Sources */,
CD2C6C2797C19E76EA67D308 /* fl_diamond_box.cxx in Sources */,
BDB3A4C9B2AC519DC6A95D84 /* fl_dnd.cxx in Sources */,
93E6F83B3B6E8F6473DE0FFC /* fl_draw.cxx in Sources */,
@ -9570,7 +9569,6 @@
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */,
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */,
7FD8085119ADD6F2007622B2 /* Fl_Shaped_Window.cxx in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -56,7 +56,6 @@ set(CPPFILES
Fl_Round_Button.cxx
Fl_Scroll.cxx
Fl_Scrollbar.cxx
Fl_Shaped_Window.cxx
Fl_Shared_Image.cxx
Fl_Single_Window.cxx
Fl_Slider.cxx
@ -82,6 +81,7 @@ set(CPPFILES
Fl_Window_fullscreen.cxx
Fl_Window_hotspot.cxx
Fl_Window_iconize.cxx
Fl_Window_shape.cxx
Fl_Wizard.cxx
Fl_XBM_Image.cxx
Fl_XPM_Image.cxx

View File

@ -1596,14 +1596,6 @@ void Fl_Window::hide() {
delete ip;
}
Fl_Window::~Fl_Window() {
hide();
if (xclass_) {
free(xclass_);
}
free_icons();
delete icon_;
}
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
// or any parent changes. We must correctly map/unmap the system's window.

View File

@ -52,6 +52,7 @@ void Fl_Window::_Fl_Window() {
resizable(0);
size_range_set = 0;
minw = maxw = minh = maxh = 0;
shape_data_ = NULL;
#if FLTK_ABI_VERSION >= 10301
no_fullscreen_x = 0;
no_fullscreen_y = 0;
@ -78,6 +79,25 @@ Fl_Window::Fl_Window(int W, int H, const char *l)
clear_visible();
}
Fl_Window::~Fl_Window() {
hide();
if (xclass_) {
free(xclass_);
}
free_icons();
delete icon_;
if (shape_data_) {
if (shape_data_->todelete_) delete shape_data_->todelete_;
#if defined(__APPLE__)
if (shape_data_->mask) {
CGImageRelease(shape_data_->mask);
}
#endif
delete shape_data_;
}
}
/** Returns a pointer to the nearest parent window up the widget hierarchy.
This will return sub-windows if there are any, or the parent window if there's no sub-windows.
If this widget IS the top-level window, NULL is returned.
@ -133,46 +153,6 @@ int Fl_Window::y_root() const {
return y();
}
void Fl_Window::draw() {
// The following is similar to Fl_Group::draw(), but ...
// - we draw the box with x=0 and y=0 instead of x() and y()
// - we don't draw a label
if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0
}
draw_children();
#ifdef __APPLE_QUARTZ__
// on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
// corner. This code draws a little ribbed triangle for dragging.
if (fl_mac_os_version < 100700 && fl_gc && !parent() && resizable() &&
(!size_range_set || minh!=maxh || minw!=maxw)) {
int dx = Fl::box_dw(box())-Fl::box_dx(box());
int dy = Fl::box_dh(box())-Fl::box_dy(box());
if (dx<=0) dx = 1;
if (dy<=0) dy = 1;
int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1;
Fl_Color c[4] = {
color(),
fl_color_average(color(), FL_WHITE, 0.7f),
fl_color_average(color(), FL_BLACK, 0.6f),
fl_color_average(color(), FL_BLACK, 0.8f),
};
int i;
for (i=dx; i<12; i++) {
fl_color(c[i&3]);
fl_line(x1--, y1, x2, y2--);
}
}
#endif
# if defined(FLTK_USE_CAIRO)
Fl::cairo_make_current(this); // checkout if an update is necessary
# endif
}
void Fl_Window::label(const char *name) {
label(name, iconlabel()); // platform dependent
}

View File

@ -1,7 +1,7 @@
//
// "$Id$"
//
// Fl_Shaped_Window source file for the Fast Light Tool Kit (FLTK).
// implementation of Fl_Window::shape(Fl_Image*) for the Fast Light Tool Kit (FLTK).
//
// Copyright 2010-2014 by Bill Spitzak and others.
//
@ -16,10 +16,13 @@
// http://www.fltk.org/str.php
//
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/Fl_Shaped_Window.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Bitmap.H>
#include <FL/Fl_Pixmap.H>
#include <string.h>
#ifdef WIN32
# include <malloc.h> // needed for VisualC2010
@ -29,36 +32,6 @@
#define ShapeSet 0
#endif
/** Create a shaped window with the given size and title */
Fl_Shaped_Window::Fl_Shaped_Window(int w, int h, const char* title)
: Fl_Window(w, h, title), lw_(0), lh_(0), shape_(0), todelete_(0) {
type(FL_SHAPED_WINDOW);
border(false);
#if defined(__APPLE__)
mask = NULL;
#endif
}
/** Create a shaped window with the given position, size and title */
Fl_Shaped_Window::Fl_Shaped_Window(int x, int y, int w, int h, const char* title)
: Fl_Window(x, y, w, h, title), lw_(0), lh_(0), shape_(0), todelete_(0) {
type(FL_SHAPED_WINDOW);
border(false);
#if defined(__APPLE__)
mask = NULL;
#endif
}
/** Destroys the shaped window but not its associated Fl_Image */
Fl_Shaped_Window::~Fl_Shaped_Window() {
if (todelete_) delete todelete_;
#if defined(__APPLE__)
if (mask) {
CGImageRelease(mask);
}
#endif
}
#if defined(__APPLE__)
@ -74,17 +47,6 @@ static inline uchar swap_byte(const uchar b) {
return (swapped[b & 0xF] << 4) | swapped[b >> 4];
}
void Fl_Shaped_Window::draw() {
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (mask && (CGContextClipToMask != NULL)) CGContextClipToMask(fl_gc, CGRectMake(0,0,w(),h()), mask); // requires Mac OS 10.4
CGContextSaveGState(fl_gc);
# endif
Fl_Window::draw();
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
CGContextRestoreGState(fl_gc);
# endif
}
#elif defined(WIN32)
static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); }
@ -165,24 +127,10 @@ static HRGN bitmap2region(Fl_Bitmap* image) {
return hRgn;
}
void Fl_Shaped_Window::draw() {
if ((lw_ != w() || lh_ != h()) && shape_) {
// size of window has changed since last time
lw_ = w();
lh_ = h();
Fl_Bitmap* temp = (Fl_Bitmap*)shape_->copy(lw_, lh_);
HRGN region = bitmap2region(temp);
SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
delete temp;
}
Fl_Window::draw();
}
#else
#ifndef FL_DOXYGEN
void Fl_Shaped_Window::combine_mask()
void Fl_Window::combine_mask()
{
typedef void (*XShapeCombineMask_type)(Display*, int, int, int, int, Pixmap, int);
static XShapeCombineMask_type XShapeCombineMask_f = NULL;
@ -200,9 +148,9 @@ void Fl_Shaped_Window::combine_mask()
XShapeQueryExtension_f(fl_display, &shapeEventBase, &error_base) ) ) XShapeCombineMask_f = NULL;
}
if (!XShapeCombineMask_f) return;
lw_ = w();
lh_ = h();
Fl_Bitmap* temp = (Fl_Bitmap*)shape_->copy(lw_, lh_);
shape_data_->lw_ = w();
shape_data_->lh_ = h();
Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
Pixmap pbitmap = XCreateBitmapFromData(fl_display, fl_xid(this),
(const char*)temp->array,
temp->w(), temp->h());
@ -212,26 +160,12 @@ void Fl_Shaped_Window::combine_mask()
}
#endif // !FL_DOXYGEN
void Fl_Shaped_Window::draw() {
if (( lw_ != w() || lh_ != h() ) && shape_) {
// size of window has changed since last time
combine_mask();
}
Fl_Window::draw();
}
#endif // __APPLE__
void Fl_Shaped_Window::shape_bitmap_(Fl_Bitmap* b) {
if (todelete_) { delete todelete_; todelete_ = NULL; }
shape_ = b;
lw_ = lh_ = 0; // so change in mask is detected
void Fl_Window::shape_bitmap_(Fl_Bitmap* b) {
shape_data_->shape_ = b;
#if defined(__APPLE__)
if (mask) {
CGImageRelease(mask);
mask = NULL;
}
if (b) {
// complement mask bits and perform bitwise inversion of all bytes and also reverse top and bottom
int bytes_per_row = (b->w() + 7)/8;
@ -241,11 +175,11 @@ void Fl_Shaped_Window::shape_bitmap_(Fl_Bitmap* b) {
uchar *last = p + bytes_per_row;
uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
while (p < last) {
*q++ = swap_byte(~*p++);
*q++ = swap_byte(~*p++);
}
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, bytes_per_row * b->h(), MyProviderReleaseData);
mask = CGImageMaskCreate(b->w(), b->h(), 1, 1, bytes_per_row, provider, NULL, false);
shape_data_->mask = CGImageMaskCreate(b->w(), b->h(), 1, 1, bytes_per_row, provider, NULL, false);
CFRelease(provider);
}
#endif
@ -256,16 +190,10 @@ void Fl_Shaped_Window::shape_bitmap_(Fl_Bitmap* b) {
/* the image can be of any depth
offset gives the byte offset from the pixel start to the byte used to construct the shape
*/
void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
int i, d = img->d(), w = img->w(), h = img->h();
if (todelete_) { delete todelete_; todelete_ = NULL; }
shape_ = img;
lw_ = lh_ = 0; // so change in mask is detected
if (mask) {
CGImageRelease(mask);
mask = NULL;
}
if (shape_) {
shape_data_->shape_ = img;
if (shape_data_->shape_) {
// reverse top and bottom and convert to gray scale if img->d() == 3 and complement bits
int bytes_per_row = w * d;
uchar *from = new uchar[w * h];
@ -274,20 +202,20 @@ void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
uchar *last = p + bytes_per_row;
uchar *q = from + (h - 1 - i) * w;
while (p < last) {
if (d == 3) {
unsigned u = *p++;
u += *p++;
u += *p++;
*q++ = ~(u/3);
}
else {
*q++ = ~(*p);
p += d;
}
if (d == 3) {
unsigned u = *p++;
u += *p++;
u += *p++;
*q++ = ~(u/3);
}
else {
*q++ = ~(*p);
p += d;
}
}
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, w * h, MyProviderReleaseData);
mask = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false);
shape_data_->mask = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false);
CFRelease(provider);
}
}
@ -297,7 +225,7 @@ void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
/* the img image can be of any depth
offset gives the byte offset from the pixel start to the byte used to construct the shape
*/
void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8;
unsigned u;
uchar byte, onebit;
@ -310,19 +238,19 @@ void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
onebit = 1;
for (j = 0; j < w; j++) {
if (d == 3) {
u = *alpha;
u += *(alpha+1);
u += *(alpha+2);
u = *alpha;
u += *(alpha+1);
u += *(alpha+2);
}
else u = *alpha;
if (u > 0) { // if the pixel is not fully transparent/black
byte |= onebit; // turn on the corresponding bit of the bitmap
byte |= onebit; // turn on the corresponding bit of the bitmap
}
onebit = onebit << 1; // move the single set bit one position to the left
if (onebit == 0 || j == w-1) {
onebit = 1;
*p++ = byte; // store in bitmap one pack of bits
byte = 0;
onebit = 1;
*p++ = byte; // store in bitmap one pack of bits
byte = 0;
}
alpha += d; // point to alpha value of next pixel
}
@ -330,19 +258,41 @@ void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
Fl_Bitmap* bitmap = new Fl_Bitmap(bits, w, h);
bitmap->alloc_array = 1;
shape_bitmap_(bitmap);
todelete_ = bitmap;
shape_data_->todelete_ = bitmap;
}
#endif
void Fl_Shaped_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
void Fl_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
Fl_RGB_Image* rgba = new Fl_RGB_Image(pixmap);
shape_alpha_(rgba, 3);
delete rgba;
}
/** Set the window's shape with an image.
#if FLTK_ABI_VERSION < 10303 && !defined(FL_DOXYGEN)
shape_data_type* Fl_Window::shape_data_ = NULL;
#endif
/** Assigns a non-rectangular shape to the window.
This function gives an arbitrary shape (not just a rectangular region) to an Fl_Window.
An Fl_Image of any dimension can be used as mask; it is rescaled to the window's dimension as needed.
The layout and widgets inside are unaware of the mask shape, and most will act as though the window's
rectangular bounding box is available
to them. It is up to you to make sure they adhere to the bounds of their masking shape.
Platform details:
\li On the unix/linux platform, the SHAPE extension of the X server is required.
This function does control the shape of Fl_GL_Window instances.
\li On the MSWindows platform, this function does nothing with class Fl_GL_Window.
\li On the Mac platform, OS version 10.4 or above is required. This function does nothing with class Fl_GL_Window.
The window borders and caption created by the window system are turned off by default. They
can be re-enabled by calling void Fl_Window::border(1).
A usage example is found at example/shapedwindow.cxx.
The \p img argument can be an Fl_Bitmap, Fl_Pixmap or Fl_RGB_Image.
\li With Fl_Bitmap or Fl_Pixmap, the shaped window covers the image part where bitmap bits equal one,
or where the pixmap is not fully transparent.
@ -355,15 +305,97 @@ void Fl_Shaped_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
are out of the shaped window;
with depths 1 or 3, white and black are in and out of the
shaped window, respectively, and other colors give intermediate masking scores.
\version 1.3.3 (and requires compilation with -DFLTK_ABI_VERSION = 10303)
*/
void Fl_Shaped_Window::shape(const Fl_Image* img) {
void Fl_Window::shape(const Fl_Image* img) {
#if FLTK_ABI_VERSION >= 10303
if (shape_data_) {
if (shape_data_->todelete_) { delete shape_data_->todelete_; }
#if defined(__APPLE__)
if (shape_data_->mask) { CGImageRelease(shape_data_->mask); }
#endif
}
else {
shape_data_ = new shape_data_type;
}
memset(shape_data_, 0, sizeof(shape_data_type));
border(false);
int d = img->d();
if (d && img->count() >= 2) shape_pixmap_((Fl_Pixmap*)img);
else if (d == 0) shape_bitmap_((Fl_Bitmap*)img);
else if (d == 2 || d == 4) shape_alpha_((Fl_RGB_Image*)img, d - 1);
else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_RGB_Image*)img, 0);
#endif
}
void Fl_Window::draw() {
if (shape_data_) {
# if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_->mask && (CGContextClipToMask != NULL)) {
CGContextClipToMask(fl_gc, CGRectMake(0,0,w(),h()), shape_data_->mask); // requires Mac OS 10.4
}
CGContextSaveGState(fl_gc);
#elif defined(WIN32)
if ((shape_data_->lw_ != w() || shape_data_->lh_ != h()) && shape_data_->shape_) {
// size of window has changed since last time
shape_data_->lw_ = w();
shape_data_->lh_ = h();
Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
HRGN region = bitmap2region(temp);
SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
delete temp;
}
#elif !(defined(__APPLE__) || defined(WIN32))
if (( shape_data_->lw_ != w() || shape_data_->lh_ != h() ) && shape_data_->shape_) {
// size of window has changed since last time
combine_mask();
}
# endif
}
// The following is similar to Fl_Group::draw(), but ...
// - we draw the box with x=0 and y=0 instead of x() and y()
// - we don't draw a label
if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0
}
draw_children();
#ifdef __APPLE_QUARTZ__
// on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
// corner. This code draws a little ribbed triangle for dragging.
if (fl_mac_os_version < 100700 && fl_gc && !parent() && resizable() &&
(!size_range_set || minh!=maxh || minw!=maxw)) {
int dx = Fl::box_dw(box())-Fl::box_dx(box());
int dy = Fl::box_dh(box())-Fl::box_dy(box());
if (dx<=0) dx = 1;
if (dy<=0) dy = 1;
int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1;
Fl_Color c[4] = {
color(),
fl_color_average(color(), FL_WHITE, 0.7f),
fl_color_average(color(), FL_BLACK, 0.6f),
fl_color_average(color(), FL_BLACK, 0.8f),
};
int i;
for (i=dx; i<12; i++) {
fl_color(c[i&3]);
fl_line(x1--, y1, x2, y2--);
}
}
#endif
# if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (shape_data_) CGContextRestoreGState(fl_gc);
# endif
# if defined(FLTK_USE_CAIRO)
Fl::cairo_make_current(this); // checkout if an update is necessary
# endif
}
//
// End of "$Id$".
//

View File

@ -2667,7 +2667,7 @@ void Fl_X::make(Fl_Window* w)
[cw setFrameOrigin:crect.origin];
[cw setHasShadow:YES];
[cw setAcceptsMouseMovedEvents:YES];
if (w->type() == FL_SHAPED_WINDOW) {
if (w->shape_data_) {
[cw setOpaque:NO]; // shaped windows must be non opaque
[cw setBackgroundColor:[NSColor clearColor]]; // and with transparent background color
}

View File

@ -35,7 +35,6 @@
# include <FL/fl_draw.H>
# include <FL/Fl_Paged_Device.H>
# include <FL/Fl_Shared_Image.H>
# include <FL/Fl_Shaped_Window.H>
# include <FL/fl_ask.H>
# include <FL/filename.H>
# include <stdio.h>
@ -2549,8 +2548,8 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
}
#endif
if (win->type() == FL_SHAPED_WINDOW) {
((Fl_Shaped_Window*)win)->combine_mask();
if (win->shape_data_) {
win->combine_mask();
}
XMapWindow(fl_display, xp->xid);
if (showit) {

View File

@ -72,7 +72,6 @@ CPPFILES = \
Fl_Round_Button.cxx \
Fl_Scroll.cxx \
Fl_Scrollbar.cxx \
Fl_Shaped_Window.cxx \
Fl_Shared_Image.cxx \
Fl_Single_Window.cxx \
Fl_Slider.cxx \
@ -98,6 +97,7 @@ CPPFILES = \
Fl_Window_fullscreen.cxx \
Fl_Window_hotspot.cxx \
Fl_Window_iconize.cxx \
Fl_Window_shape.cxx \
Fl_Wizard.cxx \
Fl_XBM_Image.cxx \
Fl_XPM_Image.cxx \