Author: dejan
Date: 2007-11-13 14:56:23 -0800 (Tue, 13 Nov 2007)
New Revision: 5968
Log:
This commit solves problem(s) reported in STR#1672
by Mr. Davy Durham who has sent patches and was
kind enough to come to our IRC channel
(irc://irc.oftc.net/fltk) and have discussion with
me. Mr. Durham, thank You.
Modified:
trunk/CREDITS
trunk/fltk/ask.h
trunk/src/message.cxx
Modified: trunk/CREDITS
===================================================================
--- trunk/CREDITS 2007-11-13 14:58:42 UTC (rev 5967)
+++ trunk/CREDITS 2007-11-13 22:56:23 UTC (rev 5968)
@@ -55,3 +55,4 @@
Brian Kropf
Jason Bryan
Tobias Markmann
+ Davy Durham ([EMAIL PROTECTED])
Modified: trunk/fltk/ask.h
===================================================================
--- trunk/fltk/ask.h 2007-11-13 14:58:42 UTC (rev 5967)
+++ trunk/fltk/ask.h 2007-11-13 22:56:23 UTC (rev 5968)
@@ -58,6 +58,11 @@
extern FL_API NamedStyle* icon_style;
extern FL_API NamedStyle* message_style;
+extern FL_API const char* message_window_label;
+extern FL_API float message_window_timeout;
+
+extern FL_API bool message_window_scrollable;
+
// pointers you can use to change FLTK to a foreign language:
extern FL_API const char* no;
extern FL_API const char* yes;
Modified: trunk/src/message.cxx
===================================================================
--- trunk/src/message.cxx 2007-11-13 14:58:42 UTC (rev 5967)
+++ trunk/src/message.cxx 2007-11-13 22:56:23 UTC (rev 5968)
@@ -30,8 +30,10 @@
#include <fltk/x.h>
#include <fltk/ask.h>
+#include <fltk/run.h>
#include <fltk/ReturnButton.h>
#include <fltk/SecretInput.h>
+#include <fltk/TextDisplay.h>
#include <fltk/string.h>
#ifdef WIN32
@@ -69,6 +71,12 @@
w->window()->make_exec_return(false);
}
+static int timed_out;
+static void timeout_handler(void *w) {
+ timed_out = 1;
+ ((Window *)w)->make_exec_return(false);
+}
+
#define ICON_W 50
#define ICON_H 50
#define BORDER_W 10
@@ -92,6 +100,10 @@
Group* saved_current_group = Group::current();
load_theme();
Window window(3*BORDER_W+ICON_W+INPUT_W, 3*BORDER_H+ICON_H+BUTTON_H);
+ if(message_window_label && message_window_label[0] != 0)
+ window.copy_label(message_window_label);
+
+ // add message, icon and possibly text input control
window.begin();
// This keeps the icon from resizing.
@@ -100,52 +112,102 @@
Widget icon(0, 0, ICON_W, ICON_H);
icon.style(icon_style);
icon.label(iconlabel);
+ ig.resizable(0); // no, THIS keeps the icon from resizing (when a text input
field is present)
ig.end();
- Widget message(2*BORDER_W+ICON_W, 0, INPUT_W, 2*BORDER_H+ICON_H);
- message.set_flag(ALIGN_LEFT|ALIGN_INSIDE|ALIGN_WRAP);
- message.style(message_style);
+ Widget *shortMessage=NULL;
+ TextDisplay *longMessage=NULL;
+ Widget *eitherMessage=NULL;
+ // Determine the complete and formatted message to show to the user
+ char messageBuffer[100*1024]; // 100k max
+ messageBuffer[sizeof(messageBuffer)-1]=0;
+ if (!strcmp(fmt,"%s")) {
+ strncpy(messageBuffer,va_arg(ap, const char*),sizeof(messageBuffer)-1);
+ } else if (!strchr(fmt, '%')) {
+ strncpy(messageBuffer,fmt,sizeof(messageBuffer)-1);
+ } else {
+ vsnprintf(messageBuffer, sizeof(messageBuffer)-1, fmt, ap);
+ }
+
+ // determine if we need to have a scrollable area or not
+ bool scrollable=false;
+ if(message_window_scrollable) {
+ // it's allowed to scroll, let's see if it needs to
+ int w=(INPUT_W+3*BORDER_W+ICON_W+10), h=0;
+ setfont(window.labelfont(), window.labelsize());
+ measure(messageBuffer, w, h, ALIGN_INSIDE_TOPLEFT | ALIGN_WRAP);
+ scrollable = h>(480-(3*BORDER_H+BUTTON_H));
+ }
+
+ if(scrollable) {
+ // Show a scrollable text display for a long message
+ eitherMessage=longMessage=new TextDisplay(2*BORDER_W+ICON_W, BORDER_H,
INPUT_W, ICON_H);
+
+ longMessage->wrap_mode(true);
+ longMessage->text(messageBuffer);
+
+ window.resizable(longMessage);
+ window.resize_align(ALIGN_TOP|ALIGN_RIGHT);
+
+ } else {
+ // Show a simple label for a short message
+ eitherMessage=shortMessage=new Widget(2*BORDER_W+ICON_W, 0, INPUT_W,
BORDER_H+ICON_H);
+ shortMessage->set_flag(ALIGN_LEFT|ALIGN_INSIDE|ALIGN_WRAP);
+ shortMessage->style(message_style);
+
+ window.resizable(shortMessage);
+ window.resize_align(ALIGN_TOP|ALIGN_RIGHT);
+ //w->size_range(window.w(), window.h(), 0, window.h());
+
+ shortMessage->label(messageBuffer);
+ }
+
+ // Add the text input field if there should be one
if (istr) {
if (textfield)
window.add(textfield);
else
- textfield = new Input(2*BORDER_W+ICON_W, 0, INPUT_W, 0);
- textfield->h(int(textfield->textsize())+10);
- textfield->y(BORDER_H+ICON_H-textfield->h());
- textfield->w(INPUT_W);
- message.h(textfield->y());
+ textfield = new Input(2*BORDER_W+ICON_W, 0, 0, 0);
+
textfield->type(itype);
textfield->text(istr);
+
+ int h=(int)textfield->textsize()+10;
+ textfield->resize(
+ textfield->x(),
+ (eitherMessage->y()+eitherMessage->h())-(h),
+ INPUT_W,
+ h
+ );
+
+ eitherMessage->h(eitherMessage->h()-h-(shortMessage ? 0 : BORDER_H));
window.set_focus(textfield);
}
- window.resizable(message);
- window.resize_align(ALIGN_TOP|ALIGN_RIGHT);
-// w->size_range(window.w(), window.h(), 0, window.h());
+ window.end();
- char buffer[2048];
- if (!strcmp(fmt,"%s")) {
- message.label(va_arg(ap, const char*));
- } else if (!strchr(fmt, '%')) {
- message.label(fmt);
- } else {
- vsnprintf(buffer, 2048, fmt, ap);
- message.label(buffer);
- }
-
- window.end();
+ // calculate into (w,h) how much wider and taller the window should become
window.layout();
- setfont(message.labelfont(), message.labelsize());
int w = 400;
int h = 0;
- measure(message.label(), w, h, message.flags());
- w+=6; h+=6;
- w -= message.w(); if (w < 0) w = 0;
- h -= message.h(); if (h < 0) h = 0;
+ if(shortMessage) {
+ setfont(eitherMessage->labelfont(), eitherMessage->labelsize());
+ measure(shortMessage->label(), w, h, shortMessage->flags());
+ w+=6; h+=2*BORDER_H;
+ w -= shortMessage->w(); if (w < 0) w = 0;
+ h -= shortMessage->h(); if (h < 0) h = 0;
+
+ } else /*if(longMessage)*/ {
+ w = 640-window.w(); if (w < 0) w = 0;
+ h = 400-window.h(); if (h < 0) h = 0;
+
+ }
window.resize(window.x(),window.y(),window.w()+w, window.h()+h);
window.layout();
+
+ // add buttons
window.begin();
const char* blabels[3];
@@ -178,14 +240,38 @@
}
window.end();
+
+ timed_out=0;
+ if(message_window_timeout>0) {
+ add_timeout(message_window_timeout,timeout_handler,&window);
+ }
+
button_number = 0;
window.exec();
+
+ if(message_window_timeout>0) {
+ remove_timeout(timeout_handler,&window);
+ }
+
if (istr)
window.remove(textfield); // don't destroy it yet
Group::current(saved_current_group);
- return button_number;
+
+ delete shortMessage;
+ delete longMessage;
+
+ return timed_out ? -1 : button_number;
}
+/*! Set this to change the title of message(), alert(), ask(), choice(), etc.
windows. */
+const char* fltk::message_window_label= NULL;
+
+/*! Set this to a positive value to cause the message(), alert(), ask(),
choice(), etc. windows to close automatically after this timeout. If the
timeout expires, -1 will be returned by the functions that return int. The
timeout value is in seconds. */
+float fltk::message_window_timeout= 0;
+
+/*! When this is set to true, then (all) message windows will use scrollbars
if the given message is too long. */
+bool fltk::message_window_scrollable = 0;
+
/*! You can change this string to convert fltk to a foreign language. */
const char* fltk::no = "&No";
/*! You can change this string to convert fltk to a foreign language. */
@@ -242,6 +328,9 @@
"No" button and waits for the user to hit a button. The return value
is 1 if the user hits Yes, 0 if they pick No. The enter key is a
shortcut for Yes and ESC is a shortcut for No.
+
+ If message_window_timeout is used, then -1 will be returned if the
+ timeout expires.
*/
int fltk::ask(const char *fmt, ...) {
if (fltk::beep_on_dialog()) (fltk::beep(BEEP_QUESTION));
@@ -259,6 +348,9 @@
is hit. If one of the strings begins with the special character '*'
then the associated button will be the default which is selected
when the enter key is pressed. ESC is a shortcut for b2.
+
+ If message_window_timeout is used, then -1 will be returned if the
+ timeout expires.
*/
int fltk::choice(const char*fmt,const char *b0,const char *b1,const char
*b2,...){
if (fltk::beep_on_dialog()) (fltk::beep(fltk::BEEP_QUESTION));
@@ -266,6 +358,8 @@
va_start(ap, b2);
int r = innards("?", 0, 0, fmt, ap, b2, b1, b0);
va_end(ap);
+ if(r<0)
+ return r;
return 2-r;
}
@@ -276,6 +370,8 @@
va_start(ap, b2);
int r = innards("!", 0, 0, fmt, ap, b2, b1, b0);
va_end(ap);
+ if(r<0)
+ return r;
return 2-r;
}
@@ -283,7 +379,7 @@
const char* defstr, uchar type) {
int r = innards("?", defstr ? defstr : "", type,
fmt, ap, fltk::cancel, fltk::ok, 0);
- return r ? textfield->text() : 0;
+ return r>=0 ? textfield->text() : 0;
}
/*!
@@ -293,6 +389,9 @@
pointer is only valid until the next time fltk::input() is
called. Due to back-compatability, the arguments to any printf
commands in the label are after the default value.
+
+ If message_window_timeout is used, then 0 will be returned if the
+ timeout expires.
*/
const char* fltk::input(const char *fmt, const char *defstr, ...) {
if (fltk::beep_on_dialog()) (fltk::beep(fltk::BEEP_QUESTION));
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit