[master] 1ce3a84 - Refactor and improve "Print front window" dialog

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 1ce3a84 - Refactor and improve "Print front window" dialog "Albrecht Schlosser" 10:02 Nov 19 top right image
 
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 ]
 
bottom left image   bottom right image
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2022 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.