summaryrefslogtreecommitdiff
path: root/src/print_button.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2021-11-14 15:17:03 +0100
committerAlbrecht Schlosser <albrechts.fltk@online.de>2021-11-19 18:50:53 +0100
commit1ce3a84e9fe74297aa764fc12536af544378d265 (patch)
tree61a17c239aca387a978debd3fd3c733c383f902c /src/print_button.cxx
parent0b8eabd184ac71b778c9fab3c6161b65b616f1f5 (diff)
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).
Diffstat (limited to 'src/print_button.cxx')
-rw-r--r--src/print_button.cxx192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/print_button.cxx b/src/print_button.cxx
new file mode 100644
index 000000000..35c7d1063
--- /dev/null
+++ b/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