melder_progress.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef _melder_progress_h_
  2. #define _melder_progress_h_
  3. /* melder_progress.h
  4. *
  5. * Copyright (C) 1992-2018 Paul Boersma
  6. *
  7. * This code is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * This code is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. * See the GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /*
  21. SYNOPSIS
  22. Melder_progress (double progress, messageArgs...);
  23. Function:
  24. Show the progress of a time-consuming process.
  25. Arguments:
  26. Any of 'args' may be null.
  27. Batch behaviour:
  28. Does nothing, always returns 1.
  29. Interactive behaviour:
  30. Shows the progress of a time-consuming process:
  31. - if 'progress' <= 0.0, show a window with text and a Cancel button, and return 1;
  32. - if 0.0 < 'progress' < 1.0, show text and a partially filled progress bar,
  33. and return 0 if user interrupts, else return 1;
  34. - if 'progress' >= 1, hide the window.
  35. Usage:
  36. - call with 'progress' = 0.0 before the process starts:
  37. (void) Melder_progress (0.0, U"Starting work...");
  38. - at every turn in your loop, call with 'progress' between 0.0 and 1.0:
  39. Melder_progress (i / (n + 1.0), U"Working on part ", i, U" out of ", n, U"...");
  40. an exception is thrown if the user clicks Cancel; if you don't want that, catch it:
  41. try {
  42. Melder_progress (i / (n + 1.0), U"Working on part ", i, U" out of ", n, U"...");
  43. } catch (MelderError) {
  44. Melder_clearError ();
  45. break;
  46. }
  47. - after the process has finished, call with 'progress' = 1.0:
  48. (void) Melder_progress (1.0);
  49. - the first and third steps can be automated by autoMelderProgress:
  50. autoMelderProgress progress (U"Starting work...");
  51. void* Melder_monitor (double progress, messageArgs...);
  52. Function:
  53. Show the progress of a time-consuming process.
  54. Arguments:
  55. Any of 'args' may be null.
  56. Batch behaviour:
  57. Does nothing, returns null if 'progress' <= 0.0 and a non-null pointer otherwise.
  58. Interactive behaviour:
  59. Shows the progress of a time-consuming process:
  60. - if 'progress' <= 0.0, show a window with text and a Cancel button and
  61. room for a square drawing, and return a Graphics;
  62. - if 0.0 < 'progress' < 1.0, show text and a partially filled progress bar,
  63. and return nullptr if user interrupts, else return a non-null pointer;
  64. - if 'progress' >= 1, hide the window.
  65. Usage:
  66. - call with 'progress' = 0.0 before the process starts.
  67. - assign the return value to a Graphics:
  68. Graphics graphics = Melder_monitor (0.0, U"Starting work...");
  69. - at every turn of your loop, draw something in the Graphics:
  70. if (graphics) { // always check; might be batch
  71. Graphics_clearWs (graphics); // only if you redraw all every time
  72. Graphics_polyline (graphics, ...);
  73. Graphics_text (graphics, ...);
  74. }
  75. - immediately after this in your loop, call with 'progress' between 0.0 and 1.0:
  76. Melder_monitor (i / (n + 1.0), U"Working on part ", i, U" out of ", n, U"...");
  77. an exception is thrown if the user clicks Cancel; if you don't want that, catch it:
  78. try {
  79. Melder_monitor (i / (n + 1.0), U"Working on part ", i, U" out of ", n, U"...");
  80. } catch (MelderError) {
  81. Melder_clearError ();
  82. break;
  83. }
  84. - after the process has finished, call with 'progress' = 1.0:
  85. (void) Melder_monitor (1.0, nullptr);
  86. - showing and hiding can be automated by autoMelderMonitor:
  87. autoMelderMonitor monitor ("Starting work...");
  88. if (monitor.graphics()) { // always check; might be batch
  89. Graphics_clearWs (monitor.graphics()); // only if you redraw all every time
  90. Graphics_polyline (monitor.graphics(), ...);
  91. Graphics_text (monitor.graphics(), ...);
  92. }
  93. */
  94. namespace MelderProgress {
  95. extern int _depth;
  96. using ProgressProc = void (*) (double progress, conststring32 message);
  97. using MonitorProc = void * (*) (double progress, conststring32 message);
  98. extern ProgressProc _p_progressProc;
  99. extern MonitorProc _p_monitorProc;
  100. void _doProgress (double progress, conststring32 message);
  101. void * _doMonitor (double progress, conststring32 message);
  102. extern MelderString _buffer;
  103. }
  104. void Melder_progressOff ();
  105. void Melder_progressOn ();
  106. inline static void Melder_progress (double progress) {
  107. MelderProgress::_doProgress (progress, U"");
  108. }
  109. template <typename... Args>
  110. void Melder_progress (double progress, const MelderArg& first, Args... rest) {
  111. MelderString_copy (& MelderProgress::_buffer, first, rest...);
  112. MelderProgress::_doProgress (progress, MelderProgress::_buffer.string);
  113. }
  114. class autoMelderProgress {
  115. public:
  116. autoMelderProgress (conststring32 message) {
  117. Melder_progress (0.0, message);
  118. }
  119. ~autoMelderProgress () {
  120. Melder_progress (1.0);
  121. }
  122. };
  123. inline static void * Melder_monitor (double progress) {
  124. return MelderProgress::_doMonitor (progress, U"");
  125. }
  126. template <typename... Args>
  127. void * Melder_monitor (double progress, const MelderArg& first, Args... rest) {
  128. MelderString_copy (& MelderProgress::_buffer, first, rest...);
  129. return MelderProgress::_doMonitor (progress, MelderProgress::_buffer.string);
  130. }
  131. typedef class structGraphics *Graphics;
  132. class autoMelderMonitor {
  133. Graphics _graphics;
  134. public:
  135. autoMelderMonitor (conststring32 message) {
  136. _graphics = (Graphics) Melder_monitor (0.0, message);
  137. }
  138. ~autoMelderMonitor () {
  139. Melder_monitor (1.0);
  140. }
  141. Graphics graphics () { return _graphics; }
  142. };
  143. struct autoMelderProgressOff {
  144. autoMelderProgressOff () { Melder_progressOff (); }
  145. ~autoMelderProgressOff () { Melder_progressOn (); }
  146. };
  147. void Melder_setProgressProc (MelderProgress::ProgressProc p_proc);
  148. void Melder_setMonitorProc (MelderProgress::MonitorProc p_proc);
  149. /* End of file melder_progress.h */
  150. #endif