diff options
| author | Manolo Gouy <Manolo> | 2015-11-24 14:26:52 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2015-11-24 14:26:52 +0000 |
| commit | b0696db39a39d9c2aadd35f74902ff22535e4d1b (patch) | |
| tree | 84b876ad7ba4d38ba20e8cbb5cbb75d5ea0571da | |
| parent | a2b8700a82f9d1eda078c91464c17a98146174b8 (diff) | |
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
| -rw-r--r-- | FL/Fl_Copy_Surface.H | 1 | ||||
| -rw-r--r-- | FL/Fl_Paged_Device.H | 4 | ||||
| -rw-r--r-- | src/Fl_Copy_Surface.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 39 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 54 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 28 | ||||
| -rw-r--r-- | test/device.cxx | 16 |
7 files changed, 123 insertions, 27 deletions
diff --git a/FL/Fl_Copy_Surface.H b/FL/Fl_Copy_Surface.H index aa2af3ed9..6b3f50799 100644 --- a/FL/Fl_Copy_Surface.H +++ b/FL/Fl_Copy_Surface.H @@ -76,6 +76,7 @@ public: ~Fl_Copy_Surface(); void set_current(); 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 */ int w() { return width; } /** Returns the pixel height of the copy surface */ diff --git a/FL/Fl_Paged_Device.H b/FL/Fl_Paged_Device.H index 48367fab1..5869018b5 100644 --- a/FL/Fl_Paged_Device.H +++ b/FL/Fl_Paged_Device.H @@ -36,6 +36,10 @@ or Fl_PostScript_File_Device instead. */ 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: /** \brief Possible page formats. diff --git a/src/Fl_Copy_Surface.cxx b/src/Fl_Copy_Surface.cxx index 69f9fea6c..c14e0ce74 100644 --- a/src/Fl_Copy_Surface.cxx +++ b/src/Fl_Copy_Surface.cxx @@ -211,6 +211,14 @@ void Fl_Copy_Surface::prepare_copy_pdf_and_tiff(int w, int h) #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)) /* graphics driver that translates all graphics coordinates before calling Xlib */ class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver { diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index d05d3ad5b..8089f75df 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -3855,6 +3855,45 @@ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) { } @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 BOOL donethat = NO; diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index c14055336..d1927e7a3 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -2731,10 +2731,14 @@ int Fl_Window::decorated_h() void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset) { - if (!win->shown() || win->parent() || !win->border() || !win->visible()) { - this->print_widget(win, x_offset, y_offset); - return; - } + if (!win->shown() || win->parent() || !win->border() || !win->visible()) + print_widget(win, x_offset, y_offset); + 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 Fl_X::fake_X_wm(win, X, Y, bt, bx, by); 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; 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 *left_image = fl_read_image(NULL, r.left, r.top, bx, wh); - uchar *right_image = fl_read_image(NULL, r.right - bx, r.top, bx, wh); - uchar *bottom_image = fl_read_image(NULL, r.left, r.bottom-by, ww, by); + uchar *left_image = bx ? fl_read_image(NULL, r.left, r.top, bx, wh) : NULL; + uchar *right_image = bx ? fl_read_image(NULL, r.right - bx, r.top, bx, wh) : NULL; + uchar *bottom_image = by ? fl_read_image(NULL, r.left, r.bottom-by, ww, by) : NULL; fl_window = save_win; ReleaseDC(NULL, fl_gc); fl_gc = save_gc; - this->set_current(); + toset->set_current(); // print the 4 window sides - fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); - fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); - fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); - fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); - delete[] top_image; - delete[] left_image; - delete[] right_image; - delete[] bottom_image; + fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image; + if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; } + if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; } + if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; } // print the window inner part this->print_widget(win, x_offset + bx, y_offset + bt + by); fl_gc = GetDC(fl_xid(win)); @@ -2819,14 +2819,30 @@ void printFront(Fl_Widget *o, void *data) 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) { static BOOL first=TRUE; if(!first) return; first=FALSE; - static Fl_Window w(0,0,120,30); - static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); - b.callback(printFront); + static Fl_Window w(0,0,120,60); + static Fl_Button bp(0,0,w.w(),30, "Print front window"); + bp.callback(printFront); + static Fl_Button bc(0,30,w.w(),30, "Copy front window"); + bc.callback(copyFront); w.end(); w.show(); } diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 094f271a5..7bb8761f2 100644 --- a/src/Fl_x.cxx +++ b/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); 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(); win->show(); 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); } fl_window = from; - this->set_current(); + toset->set_current(); if (top_image) { fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3); delete[] top_image; @@ -3110,14 +3115,29 @@ void printFront(Fl_Widget *o, void *data) 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) { static int first=1; if(!first) return; first=0; - static Fl_Window w(0,0,150,30); - static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); - b.callback(printFront); + static Fl_Window w(0,0,140,60); + static Fl_Button bp(0,0,w.w(),30, "Print front window"); + bp.callback(printFront); + static Fl_Button bc(0,30,w.w(),30, "Copy front window"); + bc.callback(copyFront); w.end(); w.show(); } diff --git a/test/device.cxx b/test/device.cxx index 9c489507a..1ad26890f 100644 --- a/test/device.cxx +++ b/test/device.cxx @@ -568,10 +568,18 @@ void copy(Fl_Widget *, void *data) { if (strcmp(operation, "Fl_Copy_Surface") == 0) { - Fl_Copy_Surface *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); + Fl_Copy_Surface *copy_surf; + if (target->as_window() && !target->parent()) { + copy_surf = new Fl_Copy_Surface(target->as_window()->decorated_w(), target->as_window()->decorated_h()); + 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; Fl_Display_Device::display_device()->set_current(); } |
