|
commit 1ce3a84e9fe74297aa764fc12536af544378d265
Author: Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Sun Nov 14 15:17:03 2021 +0100
Commit: Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Fri Nov 19 18:50:53 2021 +0100
Refactor and improve "Print front window" dialog
src/print_button.cxx: "Print front window" implementation (new file)
This is compiled and activated if USE_PRINT_BUTTON is defined.
The feature can be fine controlled by environment variable
'FLTK_PRINT_BUTTON' (see docs in source file).
src/CMakeLists.txt | 9 +--
src/Fl_Window_Driver.H | 3 +
src/Fl_win32.cxx | 89 +----------------------
src/Fl_x.cxx | 78 +-------------------
src/Makefile | 7 +-
src/print_button.cxx | 192 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 208 insertions(+), 170 deletions(-)
diff --git src/CMakeLists.txt src/CMakeLists.txt
index 0efbfed..8b64485 100644
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -133,6 +133,8 @@ set (CPPFILES
fl_diamond_box.cxx
fl_draw.cxx
fl_draw_pixmap.cxx
+ fl_encoding_latin1.cxx
+ fl_encoding_mac_roman.cxx
fl_engraved_label.cxx
fl_file_dir.cxx
fl_font.cxx
@@ -153,13 +155,12 @@ set (CPPFILES
fl_shadow_box.cxx
fl_shortcut.cxx
fl_show_colormap.cxx
+ fl_string.cxx
fl_symbols.cxx
+ fl_utf8.cxx
fl_vertex.cxx
+ print_button.cxx
screen_xywh.cxx
- fl_utf8.cxx
- fl_string.cxx
- fl_encoding_latin1.cxx
- fl_encoding_mac_roman.cxx
)
# find all header files in source directory <FL/...>
diff --git src/Fl_Window_Driver.H src/Fl_Window_Driver.H
index 6d74089..aa1a62b 100644
--- src/Fl_Window_Driver.H
+++ src/Fl_Window_Driver.H
@@ -38,6 +38,9 @@ class Fl_X;
class Fl_Image;
class Fl_RGB_Image;
+// not directly window driver related, but ...
+int fl_create_print_window(); // used internally on some platforms
+
/**
\brief A base class for platform specific window handling code.
diff --git src/Fl_win32.cxx src/Fl_win32.cxx
index 3ca0744..9abbb5d 100644
--- src/Fl_win32.cxx
+++ src/Fl_win32.cxx
@@ -1,7 +1,7 @@
//
// Windows-specific code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2018 by Bill Spitzak and others.
+// Copyright 1998-2021 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
@@ -105,7 +105,6 @@ extern void fl_cleanup_pens(void);
#define round(A) int((A) + 0.5)
#endif // _MSC_VER <= 1600
-//
// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
// USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
/*
@@ -568,8 +567,8 @@ void Fl_WinAPI_Screen_Driver::open_display_platform() {
}
}
OleInitialize(0L);
-
get_imm_module();
+ fl_create_print_window();
}
@@ -594,7 +593,7 @@ void Fl_WinAPI_Screen_Driver::desktop_scale_factor() {
dpi[ns][0] = float(dpiX);
dpi[ns][1] = float(dpiY);
scale(ns, dpiX / 96.f);
- //fprintf(LOG, "desktop_scale_factor ns=%d factor=%.2f dpi=%.1f\n", ns, scale(ns), dpi[ns][0]);
+ // fprintf(LOG, "desktop_scale_factor ns=%d factor=%.2f dpi=%.1f\n", ns, scale(ns), dpi[ns][0]);
}
}
@@ -2631,10 +2630,6 @@ void Fl_WinAPI_Window_Driver::show() {
BringWindowToTop(i->xid);
// ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE);
}
-#ifdef USE_PRINT_BUTTON
- void preparePrintFront(void);
- preparePrintFront();
-#endif
}
// the current context
@@ -2807,82 +2802,4 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image *&top, F
Fl_Surface_Device::pop_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
-#include <FL/Fl_Printer.H>
-#include <FL/Fl_Button.H>
-void printFront(Fl_Widget *o, void *data) {
- Fl_Printer printer;
- o->window()->hide();
- Fl_Window *win = Fl::first_window();
- if (!win)
- return;
- int w, h;
- if (printer.begin_job(1)) {
- o->window()->show();
- return;
- }
- if (printer.begin_page()) {
- o->window()->show();
- return;
- }
- printer.printable_rect(&w, &h);
- int wh, ww;
- wh = win->decorated_h();
- ww = win->decorated_w();
- // scale the printer device so that the window fits on the page
- float scale = 1;
- if (ww > w || wh > h) {
- scale = (float)w / ww;
- if ((float)h / wh < scale)
- scale = (float)h / wh;
- printer.scale(scale, scale);
- }
-// #define ROTATE 20.0
-#ifdef ROTATE
- printer.scale(scale * 0.8, scale * 0.8);
- printer.printable_rect(&w, &h);
- printer.origin(w / 2, h / 2);
- printer.rotate(ROTATE);
- printer.print_widget(win, -win->w() / 2, -win->h() / 2);
- // printer.print_window_part(win, 0, 0, win->w(), win->h(), -win->w() / 2, -win->h() / 2);
-#else
- printer.print_window(win);
-#endif
- printer.end_page();
- printer.end_job();
- 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
- 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, 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();
-}
-#endif // USE_PRINT_BUTTON
-
#endif // defined(_WIN32) and !defined(FL_DOXYGEN)
diff --git src/Fl_x.cxx src/Fl_x.cxx
index 0a81f5a..4d30cc2 100644
--- src/Fl_x.cxx
+++ src/Fl_x.cxx
@@ -716,6 +716,7 @@ void Fl_X11_Screen_Driver::open_display_platform() {
// the unique GC used by all X windows
GC gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0);
Fl_Graphics_Driver::default_driver().gc(gc);
+ fl_create_print_window();
}
@@ -3216,81 +3217,4 @@ void Fl_X11_Window_Driver::show() {
}
}
-
-//#define USE_PRINT_BUTTON 1
-#ifdef USE_PRINT_BUTTON
-
-// to test the Fl_Printer class creating a "Print front window" button in a separate window
-#include <FL/Fl_Printer.H>
-#include <FL/Fl_Button.H>
-
-void printFront(Fl_Widget *o, void *data)
-{
- Fl_Printer printer;
- o->window()->hide();
- Fl_Window *win = Fl::first_window();
- if(!win) return;
- int w, h;
- if( printer.begin_job(1) ) { o->window()->show(); return; }
- if( printer.begin_page() ) { o->window()->show(); return; }
- printer.printable_rect(&w,&h);
- // scale the printer device so that the window fits on the page
- float scale = 1;
- int ww = win->decorated_w();
- int wh = win->decorated_h();
- if (ww > w || wh > h) {
- scale = (float)w/ww;
- if ((float)h/wh < scale) scale = (float)h/wh;
- printer.scale(scale, scale);
- printer.printable_rect(&w, &h);
- }
-
-// #define ROTATE 20.0
-#ifdef ROTATE
- printer.scale(scale * 0.8, scale * 0.8);
- printer.printable_rect(&w, &h);
- printer.origin(w/2, h/2 );
- printer.rotate(ROTATE);
- printer.print_window( win, - win->w()/2, - win->h()/2);
- //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 );
-#else
- printer.origin(w/2, h/2 );
- printer.print_window(win, -ww/2, -wh/2);
- //printer.print_window_part( win, 0,0, win->w(), win->h(), -ww/2, -wh/2 );
-#endif
-
- printer.end_page();
- printer.end_job();
- 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());
- Fl_Surface_Device::push_current(surf);
- surf->draw_decorated_window(win); // draw the window content
- Fl_Surface_Device::pop_current();
- delete surf; // put the window on the clipboard
- o->window()->show();
-}
-
-static int prepare_print_button() {
- 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();
- return 0;
-}
-
-static int unused = prepare_print_button();
-
-#endif // USE_PRINT_BUTTON
-
#endif // !defined(FL_DOXYGEN)
diff --git src/Makefile src/Makefile
index 0b7b89a..e380403 100644
--- src/Makefile
+++ src/Makefile
@@ -157,11 +157,12 @@ CPPFILES = \
fl_shadow_box.cxx \
fl_shortcut.cxx \
fl_show_colormap.cxx \
+ fl_string.cxx \
fl_symbols.cxx \
- fl_vertex.cxx \
- screen_xywh.cxx \
fl_utf8.cxx \
- fl_string.cxx
+ fl_vertex.cxx \
+ print_button.cxx \
+ screen_xywh.cxx
OBJCPPFILES = \
Fl_cocoa.mm \
diff --git src/print_button.cxx src/print_button.cxx
new file mode 100644
index 0000000..35c7d10
--- /dev/null
+++ src/print_button.cxx
@@ -0,0 +1,192 @@
+//
+// "Print Window" functions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2021 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:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+// Notes: This function must be activated by defining the preprocessor macro
+// USE_PRINT_BUTTON on the commandline.
+//
+// Although this function is compiled on all platforms it is only used by
+// platform specific code of fl_open_display() on Linux (X11) and Windows.
+// macOS uses the "Print front window" menu in the application menu.
+//
+// The environment variable FLTK_PRINT_BUTTON can be defined to control the
+// creation of the sometimes annoying print button feature at runtime if it
+// has been compiled in (see above):
+//
+// - FLTK_PRINT_BUTTON undefined: like 1 below (default)
+//
+// - FLTK_PRINT_BUTTON = 0 : print front window disabled for this program
+// - FLTK_PRINT_BUTTON = 1 : window shown at startup
+// - FLTK_PRINT_BUTTON = 2 : window not shown, shortcut available to show
+// - FLTK_PRINT_BUTTON = 3 : window shown at startup, shortcut available
+//
+// If options 2 or 3 are used the shortcut can be used to show the window
+// if it was not shown (2) or accidentally closed (3).
+//
+// Currently the shortcut can't be configured and is always ALT+SHIFT+'s'.
+// Todo: make the shortcut configurable.
+
+#ifdef USE_PRINT_BUTTON
+
+#include <FL/Fl_Printer.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Copy_Surface.H>
+#include <FL/Fl_Image_Surface.H>
+#include <FL/Fl_RGB_Image.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_ask.H>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// define the optional rotation of print output in degrees to test it
+// #define ROTATE 20.0
+
+// Global variables to simplify and clarify the code:
+
+static Fl_Window *print_window = 0; // "print front window" dialog window
+static Fl_Check_Button *deco_button = 0; // window decoration button
+
+// The button callback does the job for both printing and copying to the
+// clipboard. The callback is called with 'mode' == (int)(data).
+// 1: print window
+// 2: copy window to clipboard
+// else: see 2.
+
+static void output_cb(Fl_Widget *o, void *data) {
+
+ print_window->hide();
+ Fl_Window *win = Fl::first_window();
+
+ // if no (other) window exists we return silently w/o showing the
+ // print window again (which ends the program)
+
+ if (!win) return;
+
+ int mode = fl_int(data);
+ int deco = deco_button->value();
+ int ww = deco ? win->decorated_w() : win->w();
+ int wh = deco ? win->decorated_h() : win->h();
+
+ if (mode == 1) { // print window
+
+ Fl_Printer printer;
+ int w, h;
+ if (printer.begin_job(1)) { // fail or cancel
+ print_window->show();
+ return;
+ }
+ if (printer.begin_page()) { // fail or cancel
+ print_window->show();
+ return;
+ }
+ printer.printable_rect(&w, &h);
+ // scale the printer device so that the window fits on the page
+ float scale = 1;
+ if (ww > w || wh > h) {
+ scale = (float)w / ww;
+ if ((float)h / wh < scale)
+ scale = (float)h / wh;
+ printer.scale(scale, scale);
+ printer.printable_rect(&w, &h);
+ }
+#ifdef ROTATE
+ printer.scale(scale * 0.8, scale * 0.8);
+ printer.printable_rect(&w, &h);
+ printer.origin(w / 2, h / 2);
+ printer.rotate(ROTATE);
+ printer.print_widget(win, -win->w() / 2, -win->h() / 2);
+#else
+ printer.origin(w / 2, h / 2);
+ printer.print_window(win, -ww / 2, -wh / 2);
+#endif
+ printer.end_page();
+ printer.end_job();
+
+ } else { // copy window to clipboard
+
+ Fl_Copy_Surface *surf = new Fl_Copy_Surface(ww, wh);
+ if (deco)
+ surf->draw_decorated_window(win); // draw the window content
+ else
+ surf->draw(win); // draw the window content
+ delete surf; // put the window on the clipboard
+
+ } // print | copy
+
+ print_window->show();
+}
+
+// Global event handler for screenshot (ctrl/alt/command + s)
+// This pops up the "Print front window" dialog if it had been closed
+
+static int shortcut_handler(int event) { // global shortcut handler
+
+ // required key and keyboard states for shortcut
+ // (should be configurable)
+
+ const int key = 's'; // global shortcut key
+ const int state = FL_ALT | FL_SHIFT; // | FL_CTRL | FL_COMMAND;
+
+ if (print_window &&
+ (event == FL_SHORTCUT || event == FL_KEYBOARD) &&
+ ((Fl::event_state() & state) == state) &&
+ (Fl::event_key() == key)) {
+ print_window->show();
+ return 1;
+ }
+ return 0;
+}
+
+// create and initialize the "Print/copy front window" dialog window
+
+int fl_create_print_window() {
+ static int first = 1;
+ if (!first)
+ return 0;
+ first = 0;
+ int val = 1;
+ const char *print_button = fl_getenv("FLTK_PRINT_BUTTON");
+ if (print_button)
+ val = atoi(print_button);
+ if (val) {
+ // prevent becoming a subwindow
+ Fl_Group *cg = Fl_Group::current();
+ Fl_Group::current(0);
+ print_window = new Fl_Window( 0, 0, 200, 110, "FLTK screenshot");
+ Fl_Button *bp = new Fl_Button(10, 10, 180, 30, "Print front window");
+ Fl_Button *bc = new Fl_Button(10, 40, 180, 30, "Copy front window");
+ deco_button = new Fl_Check_Button(10, 70, 180, 30, "Window decoration");
+ bp->callback(output_cb, (void *)1);
+ bc->callback(output_cb, (void *)2);
+ print_window->end();
+ if (val & 1)
+ print_window->show();
+ // reset saved current group
+ Fl_Group::current(cg);
+ if (val & 2)
+ Fl::add_handler(shortcut_handler);
+ }
+ return 1;
+}
+
+#else // USE_PRINT_BUTTON not defined
+
+int fl_create_print_window() {
+ return 0;
+}
+
+#endif // USE_PRINT_BUTTON
[ Direct Link to Message ] | |