Rewrite capture of window decorations using the window driver approach.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11345 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
914248bbf0
commit
2952c530b8
@ -580,8 +580,6 @@ public:
|
||||
*/
|
||||
int decorated_h();
|
||||
|
||||
// Captures the titlebar and borders of the window, if they exist.
|
||||
void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
|
||||
Fl_Window_Driver *driver() { return pWindowDriver; }
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@
|
||||
class Fl_Window;
|
||||
class Fl_X;
|
||||
class Fl_Image;
|
||||
|
||||
class Fl_Shared_Image;
|
||||
|
||||
/**
|
||||
\brief A base class for platform specific window handling code.
|
||||
@ -63,6 +63,7 @@ public:
|
||||
virtual const void *icon() const {return NULL;}
|
||||
virtual void icon(const void * ic) {}
|
||||
virtual void free_icons() {}
|
||||
virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Shared_Image.H>
|
||||
#include <FL/Fl_Window_Driver.H>
|
||||
|
||||
|
||||
/** The constructor.
|
||||
@ -193,7 +194,7 @@ int Fl_Widget_Surface::printable_rect(int *w, int *h) {return 1;}
|
||||
void Fl_Widget_Surface::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset)
|
||||
{
|
||||
Fl_Shared_Image *top, *left, *bottom, *right;
|
||||
win->capture_titlebar_and_borders(top, left, bottom, right);
|
||||
win->driver()->capture_titlebar_and_borders(top, left, bottom, right);
|
||||
int wsides = left ? left->w() : 0;
|
||||
int toph = top ? top->h() : 0;
|
||||
if (top) {
|
||||
|
@ -433,15 +433,6 @@ void Fl_Window::wait_for_expose() {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement Fl_Window::capture_titlebar_and_borders"
|
||||
void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
{
|
||||
top = left = bottom = right = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // ! __APPLE__ // PORTME: Fl_Window_Driver - platform window driver
|
||||
|
||||
//
|
||||
|
@ -156,8 +156,9 @@ void Fl_Window_Driver::shape_pixmap_(Fl_Image* pixmap) {
|
||||
delete rgba;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Fl_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) {
|
||||
top = left = bottom = right = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
@ -41,8 +41,9 @@ extern "C" {
|
||||
#include <FL/Fl_Tooltip.H>
|
||||
#include <FL/Fl_Printer.H>
|
||||
#include <FL/Fl_Shared_Image.H>
|
||||
#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.h"
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.h"
|
||||
#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.H"
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -4338,30 +4339,30 @@ static void draw_layer_to_context(CALayer *layer, CGContextRef gc, int w, int h)
|
||||
/* Returns images of the capture of the window title-bar.
|
||||
On the Mac OS platform, left, bottom and right are returned NULL; top is returned with depth 4.
|
||||
*/
|
||||
void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
void Fl_Cocoa_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
{
|
||||
left = bottom = right = NULL;
|
||||
int htop = decorated_h() - h();
|
||||
CALayer *layer = get_titlebar_layer(this);
|
||||
int htop = pWindow->decorated_h() - pWindow->h();
|
||||
CALayer *layer = get_titlebar_layer(pWindow);
|
||||
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
|
||||
uchar *rgba = new uchar[4 * w() * htop * 4];
|
||||
CGContextRef auxgc = CGBitmapContextCreate(rgba, 2 * w(), 2 * htop, 8, 8 * w(), cspace, kCGImageAlphaPremultipliedLast);
|
||||
uchar *rgba = new uchar[4 * pWindow->w() * htop * 4];
|
||||
CGContextRef auxgc = CGBitmapContextCreate(rgba, 2 * pWindow->w(), 2 * htop, 8, 8 * pWindow->w(), cspace, kCGImageAlphaPremultipliedLast);
|
||||
CGColorSpaceRelease(cspace);
|
||||
CGContextScaleCTM(auxgc, 2, 2);
|
||||
if (layer) {
|
||||
draw_layer_to_context(layer, auxgc, w(), htop);
|
||||
draw_layer_to_context(layer, auxgc, pWindow->w(), htop);
|
||||
} else {
|
||||
CGImageRef img = Fl_X::CGImage_from_window_rect(this, 0, -htop, w(), htop);
|
||||
CGImageRef img = Fl_X::CGImage_from_window_rect(pWindow, 0, -htop, pWindow->w(), htop);
|
||||
CGContextSaveGState(auxgc);
|
||||
Fl_X::clip_to_rounded_corners(auxgc, w(), htop);
|
||||
CGContextDrawImage(auxgc, CGRectMake(0, 0, w(), htop), img);
|
||||
Fl_X::clip_to_rounded_corners(auxgc, pWindow->w(), htop);
|
||||
CGContextDrawImage(auxgc, CGRectMake(0, 0, pWindow->w(), htop), img);
|
||||
CGContextRestoreGState(auxgc);
|
||||
CFRelease(img);
|
||||
}
|
||||
Fl_RGB_Image *top_rgb = new Fl_RGB_Image(rgba, 2 * w(), 2 * htop, 4);
|
||||
Fl_RGB_Image *top_rgb = new Fl_RGB_Image(rgba, 2 * pWindow->w(), 2 * htop, 4);
|
||||
top_rgb->alloc_array = 1;
|
||||
top = Fl_Shared_Image::get(top_rgb);
|
||||
top->scale(w(),htop);
|
||||
top->scale(pWindow->w(),htop);
|
||||
CGContextRelease(auxgc);
|
||||
}
|
||||
|
||||
@ -4413,7 +4414,7 @@ void Fl_System_Printer::draw_decorated_window(Fl_Window *win, int x_offset, int
|
||||
Fl::check();
|
||||
// capture the window title bar with no title
|
||||
Fl_Shared_Image *top, *left, *bottom, *right;
|
||||
win->capture_titlebar_and_borders(top, left, bottom, right);
|
||||
win->driver()->capture_titlebar_and_borders(top, left, bottom, right);
|
||||
win->label(title); // put back the window title
|
||||
this->set_current(); // back to the Fl_Paged_Device
|
||||
top->draw(x_offset, y_offset); // print the title bar
|
||||
|
@ -2556,22 +2556,22 @@ int Fl_Window::decorated_h()
|
||||
On the WIN32 platform, this function exploits a feature of fl_read_image() which, when called
|
||||
with NULL first argument and when fl_gc is set to the screen device context, captures the window decoration.
|
||||
*/
|
||||
void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
{
|
||||
Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right;
|
||||
top = left = bottom = right = NULL;
|
||||
if (!shown() || parent() || !border() || !visible()) return;
|
||||
if (!pWindow->shown() || pWindow->parent() || !pWindow->border() || !pWindow->visible()) return;
|
||||
int wsides, hbottom, bt;
|
||||
RECT r = border_width_title_bar_height(this, wsides, hbottom, bt);
|
||||
RECT r = border_width_title_bar_height(pWindow, wsides, hbottom, bt);
|
||||
int htop = bt + hbottom;
|
||||
Fl_Surface_Device *previous = Fl_Surface_Device::surface();
|
||||
Window save_win = fl_window;
|
||||
Fl_Display_Device::display_device()->set_current();
|
||||
show();
|
||||
pWindow->show();
|
||||
Fl::check();
|
||||
void* save_gc = fl_graphics_driver->gc();
|
||||
fl_graphics_driver->gc(GetDC(NULL));
|
||||
int ww = w() + 2 * wsides;
|
||||
int ww = pWindow->w() + 2 * wsides;
|
||||
// capture the 4 window sides from screen
|
||||
fl_window = NULL; // force use of read_win_rectangle() by fl_read_image()
|
||||
uchar *rgb;
|
||||
@ -2582,12 +2582,12 @@ void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Im
|
||||
top = Fl_Shared_Image::get(r_top);
|
||||
}
|
||||
if (wsides) {
|
||||
rgb = fl_read_image(NULL, r.left, r.top + htop, wsides, h());
|
||||
r_left = new Fl_RGB_Image(rgb, wsides, h(), 3);
|
||||
rgb = fl_read_image(NULL, r.left, r.top + htop, wsides, pWindow->h());
|
||||
r_left = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3);
|
||||
r_left->alloc_array = 1;
|
||||
left = Fl_Shared_Image::get(r_left);
|
||||
rgb = fl_read_image(NULL, r.right - wsides, r.top + htop, wsides, h());
|
||||
r_right = new Fl_RGB_Image(rgb, wsides, h(), 3);
|
||||
rgb = fl_read_image(NULL, r.right - wsides, r.top + htop, wsides, pWindow->h());
|
||||
r_right = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3);
|
||||
r_right->alloc_array = 1;
|
||||
right = Fl_Shared_Image::get(r_right);
|
||||
rgb = fl_read_image(NULL, r.left, r.bottom-hbottom, ww, hbottom);
|
||||
|
54
src/Fl_x.cxx
54
src/Fl_x.cxx
@ -2983,60 +2983,6 @@ int Fl_Window::decorated_w()
|
||||
return w;
|
||||
}
|
||||
|
||||
/* Returns images of the captures of the window title-bar, and the left, bottom and right window borders
|
||||
(or NULL if a particular border is absent).
|
||||
Returned images can be deleted after use. Their depth and size may be platform-dependent.
|
||||
The top and bottom images extend from left of the left border to right of the right border.
|
||||
|
||||
On the X11 platform, this function exploits a feature of fl_read_image() which, when called
|
||||
with negative 4th argument, captures the window decoration.
|
||||
*/
|
||||
void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
{
|
||||
Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right;
|
||||
top = left = bottom = right = NULL;
|
||||
if (decorated_h() == h()) return;
|
||||
Window from = fl_window;
|
||||
Fl_Surface_Device *previous = Fl_Surface_Device::surface();
|
||||
Fl_Display_Device::display_device()->set_current();
|
||||
show();
|
||||
Fl::check();
|
||||
make_current();
|
||||
Window root, parent, *children, child_win;
|
||||
unsigned n = 0;
|
||||
int do_it;
|
||||
int wsides, htop;
|
||||
do_it = (XQueryTree(fl_display, fl_window, &root, &parent, &children, &n) != 0 &&
|
||||
XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &wsides, &htop, &child_win) == True);
|
||||
if (n) XFree(children);
|
||||
if (!do_it) wsides = htop = 0;
|
||||
int hbottom = wsides;
|
||||
fl_window = parent;
|
||||
uchar *rgb;
|
||||
if (htop) {
|
||||
rgb = fl_read_image(NULL, 0, 0, - (w() + 2 * wsides), htop);
|
||||
r_top = new Fl_RGB_Image(rgb, w() + 2 * wsides, htop, 3);
|
||||
r_top->alloc_array = 1;
|
||||
top = Fl_Shared_Image::get(r_top);
|
||||
}
|
||||
if (wsides) {
|
||||
rgb = fl_read_image(NULL, 0, htop, -wsides, h());
|
||||
r_left = new Fl_RGB_Image(rgb, wsides, h(), 3);
|
||||
r_left->alloc_array = 1;
|
||||
left = Fl_Shared_Image::get(r_left);
|
||||
rgb = fl_read_image(NULL, w() + wsides, htop, -wsides, h());
|
||||
r_right = new Fl_RGB_Image(rgb, wsides, h(), 3);
|
||||
r_right->alloc_array = 1;
|
||||
right = Fl_Shared_Image::get(r_right);
|
||||
rgb = fl_read_image(NULL, 0, htop + h(), -(w() + 2*wsides), hbottom);
|
||||
r_bottom = new Fl_RGB_Image(rgb, w() + 2*wsides, hbottom, 3);
|
||||
r_bottom->alloc_array = 1;
|
||||
bottom = Fl_Shared_Image::get(r_bottom);
|
||||
}
|
||||
fl_window = from;
|
||||
previous->Fl_Surface_Device::set_current();
|
||||
}
|
||||
|
||||
#ifdef USE_PRINT_BUTTON
|
||||
// to test the Fl_Printer class creating a "Print front window" button in a separate window
|
||||
// contains also preparePrintFront call above
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
virtual void take_focus();
|
||||
virtual void shape(const Fl_Image* img);
|
||||
virtual void draw();
|
||||
// that one is implemented in Fl_Cocoa.mm because it uses Objective-c
|
||||
virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
virtual void icon(const void * ic);
|
||||
virtual void free_icons();
|
||||
void icons(HICON big_icon, HICON small_icon);
|
||||
// this one is implemented in Fl_win32.cxx
|
||||
virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
virtual const void *icon() const;
|
||||
virtual void icon(const void * ic);
|
||||
virtual void free_icons();
|
||||
virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right);
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
#include "../../config_lib.h"
|
||||
#include "Fl_X11_Window_Driver.H"
|
||||
#include <FL/Fl_Shared_Image.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <string.h>
|
||||
#if HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
@ -275,6 +277,60 @@ void Fl_X11_Window_Driver::free_icons() {
|
||||
}
|
||||
|
||||
|
||||
/* Returns images of the captures of the window title-bar, and the left, bottom and right window borders
|
||||
(or NULL if a particular border is absent).
|
||||
Returned images can be deleted after use. Their depth and size may be platform-dependent.
|
||||
The top and bottom images extend from left of the left border to right of the right border.
|
||||
|
||||
On the X11 platform, this function exploits a feature of fl_read_image() which, when called
|
||||
with negative 4th argument, captures the window decoration.
|
||||
*/
|
||||
void Fl_X11_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right)
|
||||
{
|
||||
Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right;
|
||||
top = left = bottom = right = NULL;
|
||||
if (pWindow->decorated_h() == pWindow->h()) return;
|
||||
Window from = fl_window;
|
||||
Fl_Surface_Device *previous = Fl_Surface_Device::surface();
|
||||
Fl_Display_Device::display_device()->set_current();
|
||||
pWindow->show();
|
||||
Fl::check();
|
||||
pWindow->make_current();
|
||||
Window root, parent, *children, child_win;
|
||||
unsigned n = 0;
|
||||
int do_it;
|
||||
int wsides, htop;
|
||||
do_it = (XQueryTree(fl_display, fl_window, &root, &parent, &children, &n) != 0 &&
|
||||
XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &wsides, &htop, &child_win) == True);
|
||||
if (n) XFree(children);
|
||||
if (!do_it) wsides = htop = 0;
|
||||
int hbottom = wsides;
|
||||
fl_window = parent;
|
||||
uchar *rgb;
|
||||
if (htop) {
|
||||
rgb = fl_read_image(NULL, 0, 0, - (pWindow->w() + 2 * wsides), htop);
|
||||
r_top = new Fl_RGB_Image(rgb, pWindow->w() + 2 * wsides, htop, 3);
|
||||
r_top->alloc_array = 1;
|
||||
top = Fl_Shared_Image::get(r_top);
|
||||
}
|
||||
if (wsides) {
|
||||
rgb = fl_read_image(NULL, 0, htop, -wsides, pWindow->h());
|
||||
r_left = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3);
|
||||
r_left->alloc_array = 1;
|
||||
left = Fl_Shared_Image::get(r_left);
|
||||
rgb = fl_read_image(NULL, pWindow->w() + wsides, htop, -wsides, pWindow->h());
|
||||
r_right = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3);
|
||||
r_right->alloc_array = 1;
|
||||
right = Fl_Shared_Image::get(r_right);
|
||||
rgb = fl_read_image(NULL, 0, htop + pWindow->h(), -(pWindow->w() + 2*wsides), hbottom);
|
||||
r_bottom = new Fl_RGB_Image(rgb, pWindow->w() + 2*wsides, hbottom, 3);
|
||||
r_bottom->alloc_array = 1;
|
||||
bottom = Fl_Shared_Image::get(r_bottom);
|
||||
}
|
||||
fl_window = from;
|
||||
previous->Fl_Surface_Device::set_current();
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user