Added new method Fl_Copy_Surface::draw_decorated_window()
that copies a window to the clipboard together with its title bar and borders. This requires very little new code because the capture of window decorations is shared with the Fl_Paged_Device::print window() method. The device test program is changed to call the new method. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10928 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
a2b8700a82
commit
b0696db39a
@ -76,6 +76,7 @@ public:
|
|||||||
~Fl_Copy_Surface();
|
~Fl_Copy_Surface();
|
||||||
void set_current();
|
void set_current();
|
||||||
void draw(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
|
void draw(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
|
||||||
|
void draw_decorated_window(Fl_Window* win, int delta_x = 0, int delta_y = 0);
|
||||||
/** Returns the pixel width of the copy surface */
|
/** Returns the pixel width of the copy surface */
|
||||||
int w() { return width; }
|
int w() { return width; }
|
||||||
/** Returns the pixel height of the copy surface */
|
/** Returns the pixel height of the copy surface */
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
or Fl_PostScript_File_Device instead.
|
or Fl_PostScript_File_Device instead.
|
||||||
*/
|
*/
|
||||||
class FL_EXPORT Fl_Paged_Device : public Fl_Surface_Device {
|
class FL_EXPORT Fl_Paged_Device : public Fl_Surface_Device {
|
||||||
|
#ifndef __APPLE__
|
||||||
|
friend class Fl_Copy_Surface;
|
||||||
|
void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset);
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
\brief Possible page formats.
|
\brief Possible page formats.
|
||||||
|
@ -211,6 +211,14 @@ void Fl_Copy_Surface::prepare_copy_pdf_and_tiff(int w, int h)
|
|||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#if !defined(__APPLE__)
|
||||||
|
/** Copies a window and its borders and title bar to the clipboard. */
|
||||||
|
void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
|
||||||
|
{
|
||||||
|
helper->draw_decorated_window(win, delta_x, delta_y, this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
|
#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
|
||||||
/* graphics driver that translates all graphics coordinates before calling Xlib */
|
/* graphics driver that translates all graphics coordinates before calling Xlib */
|
||||||
class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
|
class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
|
||||||
|
@ -3855,6 +3855,45 @@ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
|
|||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
|
||||||
|
{
|
||||||
|
int bx, by, bt;
|
||||||
|
get_window_frame_sizes(bx, by, bt);
|
||||||
|
draw(win, 0, bt); // draw the window content
|
||||||
|
if (win->border()) {
|
||||||
|
// draw the window title bar
|
||||||
|
CGContextSaveGState(gc);
|
||||||
|
CGContextTranslateCTM(gc, 0, bt);
|
||||||
|
CGContextScaleCTM(gc, 1, -1);
|
||||||
|
Fl_X::clip_to_rounded_corners(gc, win->w(), bt);
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||||
|
CALayer *layer = fl_mac_os_version >= 101000 ?
|
||||||
|
[[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer] : nil; // 10.5
|
||||||
|
if (layer) {
|
||||||
|
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
|
||||||
|
// for unknown reason, rendering the layer to the Fl_Copy_Surface pdf graphics context does not work;
|
||||||
|
// we use an auxiliary bitmap context
|
||||||
|
CGContextRef auxgc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
|
||||||
|
CGColorSpaceRelease(cspace);
|
||||||
|
CGContextClearRect(auxgc, CGRectMake(0, 0, win->w(), bt));
|
||||||
|
CGContextTranslateCTM(auxgc, 0, bt);
|
||||||
|
CGContextScaleCTM(auxgc, 1, -1);
|
||||||
|
[layer renderInContext:auxgc]; // 10.5
|
||||||
|
fl_draw_image((uchar*)CGBitmapContextGetData(auxgc), 0, 0, win->w(), bt, 4, CGBitmapContextGetBytesPerRow(auxgc));
|
||||||
|
CGContextRelease(auxgc);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
|
||||||
|
CGContextDrawImage(gc, CGRectMake(0, 0, win->w(), bt), img);
|
||||||
|
CFRelease(img);
|
||||||
|
}
|
||||||
|
CGContextRestoreGState(gc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createAppleMenu(void)
|
static void createAppleMenu(void)
|
||||||
{
|
{
|
||||||
static BOOL donethat = NO;
|
static BOOL donethat = NO;
|
||||||
|
@ -2731,10 +2731,14 @@ int Fl_Window::decorated_h()
|
|||||||
|
|
||||||
void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
||||||
{
|
{
|
||||||
if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
|
if (!win->shown() || win->parent() || !win->border() || !win->visible())
|
||||||
this->print_widget(win, x_offset, y_offset);
|
print_widget(win, x_offset, y_offset);
|
||||||
return;
|
else
|
||||||
}
|
draw_decorated_window(win, x_offset, y_offset, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
|
||||||
|
{
|
||||||
int X, Y, bt, bx, by, ww, wh; // compute the window border sizes
|
int X, Y, bt, bx, by, ww, wh; // compute the window border sizes
|
||||||
Fl_X::fake_X_wm(win, X, Y, bt, bx, by);
|
Fl_X::fake_X_wm(win, X, Y, bt, bx, by);
|
||||||
ww = win->w() + 2 * bx;
|
ww = win->w() + 2 * bx;
|
||||||
@ -2757,21 +2761,17 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
|||||||
Window save_win = fl_window;
|
Window save_win = fl_window;
|
||||||
fl_window = NULL; // force use of read_win_rectangle() by fl_read_image()
|
fl_window = NULL; // force use of read_win_rectangle() by fl_read_image()
|
||||||
uchar *top_image = fl_read_image(NULL, r.left, r.top, ww, bt + by);
|
uchar *top_image = fl_read_image(NULL, r.left, r.top, ww, bt + by);
|
||||||
uchar *left_image = fl_read_image(NULL, r.left, r.top, bx, wh);
|
uchar *left_image = bx ? fl_read_image(NULL, r.left, r.top, bx, wh) : NULL;
|
||||||
uchar *right_image = fl_read_image(NULL, r.right - bx, r.top, bx, wh);
|
uchar *right_image = bx ? fl_read_image(NULL, r.right - bx, r.top, bx, wh) : NULL;
|
||||||
uchar *bottom_image = fl_read_image(NULL, r.left, r.bottom-by, ww, by);
|
uchar *bottom_image = by ? fl_read_image(NULL, r.left, r.bottom-by, ww, by) : NULL;
|
||||||
fl_window = save_win;
|
fl_window = save_win;
|
||||||
ReleaseDC(NULL, fl_gc); fl_gc = save_gc;
|
ReleaseDC(NULL, fl_gc); fl_gc = save_gc;
|
||||||
this->set_current();
|
toset->set_current();
|
||||||
// print the 4 window sides
|
// print the 4 window sides
|
||||||
fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3);
|
fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image;
|
||||||
fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3);
|
if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; }
|
||||||
fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3);
|
if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; }
|
||||||
fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3);
|
if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; }
|
||||||
delete[] top_image;
|
|
||||||
delete[] left_image;
|
|
||||||
delete[] right_image;
|
|
||||||
delete[] bottom_image;
|
|
||||||
// print the window inner part
|
// print the window inner part
|
||||||
this->print_widget(win, x_offset + bx, y_offset + bt + by);
|
this->print_widget(win, x_offset + bx, y_offset + bt + by);
|
||||||
fl_gc = GetDC(fl_xid(win));
|
fl_gc = GetDC(fl_xid(win));
|
||||||
@ -2819,14 +2819,30 @@ void printFront(Fl_Widget *o, void *data)
|
|||||||
o->window()->show();
|
o->window()->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <FL/Fl_Copy_Surface.H>
|
||||||
|
void copyFront(Fl_Widget *o, void *data)
|
||||||
|
{
|
||||||
|
o->window()->hide();
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
if (!win) return;
|
||||||
|
Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w() + 1, (int)(win->decorated_h() *0.985));
|
||||||
|
surf->set_current();
|
||||||
|
surf->draw_decorated_window(win); // draw the window content
|
||||||
|
delete surf; // put the window on the clipboard
|
||||||
|
Fl_Display_Device::display_device()->set_current();
|
||||||
|
o->window()->show();
|
||||||
|
}
|
||||||
|
|
||||||
void preparePrintFront(void)
|
void preparePrintFront(void)
|
||||||
{
|
{
|
||||||
static BOOL first=TRUE;
|
static BOOL first=TRUE;
|
||||||
if(!first) return;
|
if(!first) return;
|
||||||
first=FALSE;
|
first=FALSE;
|
||||||
static Fl_Window w(0,0,120,30);
|
static Fl_Window w(0,0,120,60);
|
||||||
static Fl_Button b(0,0,w.w(),w.h(), "Print front window");
|
static Fl_Button bp(0,0,w.w(),30, "Print front window");
|
||||||
b.callback(printFront);
|
bp.callback(printFront);
|
||||||
|
static Fl_Button bc(0,30,w.w(),30, "Copy front window");
|
||||||
|
bc.callback(copyFront);
|
||||||
w.end();
|
w.end();
|
||||||
w.show();
|
w.show();
|
||||||
}
|
}
|
||||||
|
28
src/Fl_x.cxx
28
src/Fl_x.cxx
@ -3024,6 +3024,11 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
|||||||
this->print_widget(win, x_offset, y_offset);
|
this->print_widget(win, x_offset, y_offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
draw_decorated_window(win, x_offset, y_offset, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
|
||||||
|
{
|
||||||
Fl_Display_Device::display_device()->set_current();
|
Fl_Display_Device::display_device()->set_current();
|
||||||
win->show();
|
win->show();
|
||||||
Fl::check();
|
Fl::check();
|
||||||
@ -3052,7 +3057,7 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
|||||||
bottom_image = fl_read_image(NULL, 0, bt + win->h(), -(win->w() + 2*bx), bx);
|
bottom_image = fl_read_image(NULL, 0, bt + win->h(), -(win->w() + 2*bx), bx);
|
||||||
}
|
}
|
||||||
fl_window = from;
|
fl_window = from;
|
||||||
this->set_current();
|
toset->set_current();
|
||||||
if (top_image) {
|
if (top_image) {
|
||||||
fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3);
|
fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3);
|
||||||
delete[] top_image;
|
delete[] top_image;
|
||||||
@ -3110,14 +3115,29 @@ void printFront(Fl_Widget *o, void *data)
|
|||||||
o->window()->show();
|
o->window()->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <FL/Fl_Copy_Surface.H>
|
||||||
|
void copyFront(Fl_Widget *o, void *data)
|
||||||
|
{
|
||||||
|
o->window()->hide();
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
if (!win) return;
|
||||||
|
Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w(), win->decorated_h());
|
||||||
|
surf->set_current();
|
||||||
|
surf->draw_decorated_window(win); // draw the window content
|
||||||
|
delete surf; // put the window on the clipboard
|
||||||
|
o->window()->show();
|
||||||
|
}
|
||||||
|
|
||||||
void preparePrintFront(void)
|
void preparePrintFront(void)
|
||||||
{
|
{
|
||||||
static int first=1;
|
static int first=1;
|
||||||
if(!first) return;
|
if(!first) return;
|
||||||
first=0;
|
first=0;
|
||||||
static Fl_Window w(0,0,150,30);
|
static Fl_Window w(0,0,140,60);
|
||||||
static Fl_Button b(0,0,w.w(),w.h(), "Print front window");
|
static Fl_Button bp(0,0,w.w(),30, "Print front window");
|
||||||
b.callback(printFront);
|
bp.callback(printFront);
|
||||||
|
static Fl_Button bc(0,30,w.w(),30, "Copy front window");
|
||||||
|
bc.callback(copyFront);
|
||||||
w.end();
|
w.end();
|
||||||
w.show();
|
w.show();
|
||||||
}
|
}
|
||||||
|
@ -568,10 +568,18 @@ void copy(Fl_Widget *, void *data) {
|
|||||||
|
|
||||||
|
|
||||||
if (strcmp(operation, "Fl_Copy_Surface") == 0) {
|
if (strcmp(operation, "Fl_Copy_Surface") == 0) {
|
||||||
Fl_Copy_Surface *copy_surf = new Fl_Copy_Surface(target->w()+10, target->h()+20);
|
Fl_Copy_Surface *copy_surf;
|
||||||
copy_surf->set_current();
|
if (target->as_window() && !target->parent()) {
|
||||||
fl_color(FL_YELLOW);fl_rectf(0,0,copy_surf->w(), copy_surf->h());
|
copy_surf = new Fl_Copy_Surface(target->as_window()->decorated_w(), target->as_window()->decorated_h());
|
||||||
copy_surf->draw(target, 5, 10);
|
copy_surf->set_current();
|
||||||
|
copy_surf->draw_decorated_window(target->as_window(), 0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copy_surf = new Fl_Copy_Surface(target->w()+10, target->h()+20);
|
||||||
|
copy_surf->set_current();
|
||||||
|
fl_color(FL_YELLOW);fl_rectf(0,0,copy_surf->w(), copy_surf->h());
|
||||||
|
copy_surf->draw(target, 5, 10);
|
||||||
|
}
|
||||||
delete copy_surf;
|
delete copy_surf;
|
||||||
Fl_Display_Device::display_device()->set_current();
|
Fl_Display_Device::display_device()->set_current();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user