Avoiding crashes for recrsive common dialogs (this does not fix the issue at hand yet) (STR #1986, 2150) / Added menu shortcut alignment for OS X / Fixed bad system menu hadling in OS X (STR #2153) / Fixed File Input mouse pointer dragging (STR #2181)

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6757 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2009-04-12 20:00:45 +00:00
parent afe1b90dd0
commit ead9c2ce24
7 changed files with 101 additions and 19 deletions

View File

@ -1,5 +1,10 @@
CHANGES IN FLTK 1.3.0 CHANGES IN FLTK 1.3.0
- Avoiding crashes for recursive common dialogs (this does not
fix the issue at hand yet) (STR #1986, 2150)
- Added menu shortcut alignment for OS X
- Fixed bad system menu hadling in OS X (STR #2153)
- Fixed File Input mouse pointer dragging (STR #2181)
- Added alternative text input awareness on OS X - Added alternative text input awareness on OS X
- Fixed 'del' keycode on OS X (must be verified for all keyboards) - Fixed 'del' keycode on OS X (must be verified for all keyboards)
- Fixed OS X support for sending and receiving dnd data as utf8 - Fixed OS X support for sending and receiving dnd data as utf8

View File

@ -436,6 +436,7 @@ FL_EXPORT int fl_measure_pixmap(const char* const* cdata, int &w, int &h);
FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy, FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
void (*draw_area)(void*, int,int,int,int), void* data); void (*draw_area)(void*, int,int,int,int), void* data);
FL_EXPORT const char* fl_shortcut_label(int shortcut); FL_EXPORT const char* fl_shortcut_label(int shortcut);
FL_EXPORT const char* fl_shortcut_label(int shortcuti, const char **eom);
FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h); FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h);
FL_EXPORT void fl_overlay_clear(); FL_EXPORT void fl_overlay_clear();
FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE); FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE);

View File

@ -191,6 +191,7 @@ int // O - TRUE if we handled event
Fl_File_Input::handle(int event) // I - Event Fl_File_Input::handle(int event) // I - Event
{ {
// printf("handle(event = %d)\n", event); // printf("handle(event = %d)\n", event);
static char inButtonBar = 0;
switch (event) { switch (event) {
case FL_MOVE : case FL_MOVE :
@ -203,10 +204,12 @@ Fl_File_Input::handle(int event) // I - Event
return 1; return 1;
case FL_PUSH : case FL_PUSH :
inButtonBar = (Fl::event_y() < (y() + DIR_HEIGHT));
case FL_RELEASE : case FL_RELEASE :
case FL_DRAG : case FL_DRAG :
if (Fl::event_y() < (y() + DIR_HEIGHT) || pressed_ >= 0) return handle_button(event); if (inButtonBar)
return handle_button(event);
else
return Fl_Input::handle(event); return Fl_Input::handle(event);
default : default :
@ -214,7 +217,6 @@ Fl_File_Input::handle(int event) // I - Event
damage(FL_DAMAGE_BAR); damage(FL_DAMAGE_BAR);
return 1; return 1;
} }
return 0; return 0;
} }
} }

View File

@ -106,6 +106,7 @@ public:
int numitems; int numitems;
int selected; int selected;
int drawn_selected; // last redraw has this selected int drawn_selected; // last redraw has this selected
int shortcutWidth;
const Fl_Menu_Item* menu; const Fl_Menu_Item* menu;
menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H, menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H,
const Fl_Menu_Item* picked, const Fl_Menu_Item* title, const Fl_Menu_Item* picked, const Fl_Menu_Item* title,
@ -316,6 +317,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
itemheight = 1; itemheight = 1;
int hotKeysw = 0; int hotKeysw = 0;
int hotModsw = 0;
int Wtitle = 0; int Wtitle = 0;
int Htitle = 0; int Htitle = 0;
if (t) Wtitle = t->measure(&Htitle, button) + 12; if (t) Wtitle = t->measure(&Htitle, button) + 12;
@ -327,14 +329,18 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14; if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14;
if (w1 > W) W = w1; if (w1 > W) W = w1;
if (m->shortcut_) { if (m->shortcut_) {
w1 = int(fl_width(fl_shortcut_label(m->shortcut_))) + 8; const char *k, *s = fl_shortcut_label(m->shortcut_, &k);
w1 = int(fl_width(s, k-s));
if (w1 > hotModsw) hotModsw = w1;
w1 = int(fl_width(k))+4;
if (w1 > hotKeysw) hotKeysw = w1; if (w1 > hotKeysw) hotKeysw = w1;
} }
if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay(); if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay();
} }
shortcutWidth = hotKeysw;
if (selected >= 0 && !Wp) X -= W/2; if (selected >= 0 && !Wp) X -= W/2;
int BW = Fl::box_dx(box()); int BW = Fl::box_dx(box());
W += hotKeysw+2*BW+7; W += hotKeysw+hotModsw+2*BW+7;
if (Wp > W) W = Wp; if (Wp > W) W = Wp;
if (Wtitle > W) W = Wtitle; if (Wtitle > W) W = Wtitle;
@ -437,7 +443,10 @@ void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) {
button ? button->textfont() : FL_HELVETICA; button ? button->textfont() : FL_HELVETICA;
fl_font(f, m->labelsize_ ? m->labelsize_ : fl_font(f, m->labelsize_ ? m->labelsize_ :
button ? button->textsize() : FL_NORMAL_SIZE); button ? button->textsize() : FL_NORMAL_SIZE);
fl_draw(fl_shortcut_label(m->shortcut_), xx, yy, ww-3, hh, FL_ALIGN_RIGHT); const char *k, *s = fl_shortcut_label(m->shortcut_, &k);
char buf[32]; strcpy(buf, s); buf[k-s] = 0;
fl_draw(buf, xx, yy, ww-shortcutWidth, hh, FL_ALIGN_RIGHT);
fl_draw( k, xx+ww-shortcutWidth, yy, shortcutWidth, hh, FL_ALIGN_LEFT);
} }
if (m->flags & FL_MENU_DIVIDER) { if (m->flags & FL_MENU_DIVIDER) {

View File

@ -566,8 +566,11 @@ static pascal OSStatus carbonDispatchHandler( EventHandlerCallRef nextHandler, E
switch (GetEventKind( event ) ) switch (GetEventKind( event ) )
{ {
case kEventCommandProcess: case kEventCommandProcess:
GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd ); ret = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd );
if (ret == noErr && (cmd.attributes & kHICommandFromMenu) != 0)
ret = HandleMenu( &cmd ); ret = HandleMenu( &cmd );
else
ret = eventNotHandledErr;
break; break;
} }
break; break;
@ -1241,7 +1244,7 @@ pascal OSStatus carbonTextHandler(
Fl_Window *window = (Fl_Window*)userData; Fl_Window *window = (Fl_Window*)userData;
Fl::first_window(window); Fl::first_window(window);
fl_lock_function(); fl_lock_function();
int kind = GetEventKind(event); //int kind = GetEventKind(event);
unsigned short buf[200]; unsigned short buf[200];
ByteCount size; ByteCount size;
GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText,
@ -1259,6 +1262,9 @@ pascal OSStatus carbonTextHandler(
fl_lock_function(); fl_lock_function();
Fl::handle(FL_KEYUP, window); Fl::handle(FL_KEYUP, window);
fl_unlock_function(); fl_unlock_function();
// for some reason, the window does not redraw until the next mouse move or button push
// sending a 'redraw()' or 'awake()' does not solve the issue!
Fl::flush();
return noErr; return noErr;
} }

View File

@ -176,12 +176,15 @@ static int innards(const char* fmt, va_list ap,
const char *b1, const char *b1,
const char *b2) const char *b2)
{ {
static char avoidRecursion = 0;
if (avoidRecursion) return -1;
avoidRecursion = 1;
makeform(); makeform();
char buffer[1024]; char buffer[1024];
if (!strcmp(fmt,"%s")) { if (!strcmp(fmt,"%s")) {
message->label(va_arg(ap, const char*)); message->label(va_arg(ap, const char*));
} else { } else {
//: matt: MacOS provides two equally named vsnprintf's...
::vsnprintf(buffer, 1024, fmt, ap); ::vsnprintf(buffer, 1024, fmt, ap);
message->label(buffer); message->label(buffer);
} }
@ -225,6 +228,8 @@ static int innards(const char* fmt, va_list ap,
Fl::grab(g); Fl::grab(g);
message_form->hide(); message_form->hide();
icon->label(prev_icon_label); icon->label(prev_icon_label);
avoidRecursion = 0;
return r; return r;
} }
@ -288,7 +293,11 @@ void fl_beep(int type) {
} }
#endif // WIN32 #endif // WIN32
} }
/** Shows an information message dialog box /** Shows an information message dialog box.
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
*/ */
void fl_message(const char *fmt, ...) { void fl_message(const char *fmt, ...) {
@ -304,6 +313,10 @@ void fl_message(const char *fmt, ...) {
} }
/** Shows an alert message dialog box /** Shows an alert message dialog box
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
*/ */
void fl_alert(const char *fmt, ...) { void fl_alert(const char *fmt, ...) {
@ -319,8 +332,12 @@ void fl_alert(const char *fmt, ...) {
} }
/** Shows a dialog displaying the \p fmt message, /** Shows a dialog displaying the \p fmt message,
this dialog features 2 yes/no buttons this dialog features 2 yes/no buttons
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
\retval 0 if the no button is selected \retval 0 if the no button is selected or another dialog box is still open
\retval 1 if yes is selected \retval 1 if yes is selected
*/ */
int fl_ask(const char *fmt, ...) { int fl_ask(const char *fmt, ...) {
@ -337,11 +354,15 @@ int fl_ask(const char *fmt, ...) {
/** Shows a dialog displaying the \p fmt message, /** Shows a dialog displaying the \p fmt message,
this dialog features up to 3 customizable choice buttons this dialog features up to 3 customizable choice buttons
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
\param[in] b0 text label of button 0 \param[in] b0 text label of button 0
\param[in] b1 text label of button 1 \param[in] b1 text label of button 1
\param[in] b2 text label of button 2 \param[in] b2 text label of button 2
\retval 0 if the first button with \p b0 text is selected \retval 0 if the first button with \p b0 text is selected or another dialog box is still open
\retval 1 if the second button with \p b1 text is selected \retval 1 if the second button with \p b1 text is selected
\retval 2 if the third button with \p b2 text is selected \retval 2 if the third button with \p b2 text is selected
*/ */
@ -377,9 +398,13 @@ static const char* input_innards(const char* fmt, va_list ap,
} }
/** Shows an input dialog displaying the \p fmt message /** Shows an input dialog displaying the \p fmt message
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
\param[in] defstr defines the default returned string if no text is entered \param[in] defstr defines the default returned string if no text is entered
\return the user string input if OK was pushed, NULL if Cancel was pushed \return the user string input if OK was pushed, NULL if Cancel was pushed or another dialog box was still open
*/ */
const char* fl_input(const char *fmt, const char *defstr, ...) { const char* fl_input(const char *fmt, const char *defstr, ...) {
fl_beep(FL_BEEP_QUESTION); fl_beep(FL_BEEP_QUESTION);
@ -395,9 +420,13 @@ const char* fl_input(const char *fmt, const char *defstr, ...) {
Like fl_input() except the input text is not shown, Like fl_input() except the input text is not shown,
'*' characters are displayed instead. '*' characters are displayed instead.
\note Common dialog boxes are application modal. No more than one common dialog box
can be open at any time. Request for additional dialog boxes are ignored.
\param[in] fmt can be used as an sprintf-like format and variables for the message text \param[in] fmt can be used as an sprintf-like format and variables for the message text
\param[in] defstr defines the default returned string if no text is entered \param[in] defstr defines the default returned string if no text is entered
\return the user string input if OK was pushed, NULL if Cancel was pushed \return the user string input if OK was pushed, NULL if Cancel was pushed or aother dialog box was still open
*/ */
const char *fl_password(const char *fmt, const char *defstr, ...) { const char *fl_password(const char *fmt, const char *defstr, ...) {
fl_beep(FL_BEEP_PASSWORD); fl_beep(FL_BEEP_PASSWORD);

View File

@ -169,15 +169,32 @@ static Keyname table[] = {
/** /**
Get a human-readable string from a shortcut value. Get a human-readable string from a shortcut value.
Unparse a shortcut value as used by Fl_Button or Fl_Menu_Item into Unparse a shortcut value as used by Fl_Button or Fl_Menu_Item into
a human-readable string like "Alt+N". This only works if the shortcut a human-readable string like "Alt+N". This only works if the shortcut
is a character key or a numbered function key. If the shortcut is is a character key or a numbered function key. If the shortcut is
zero then an empty string is returned. The return value points at zero then an empty string is returned. The return value points at
a static buffer that is overwritten with each call. a static buffer that is overwritten with each call.
\param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers
\return a pointer to a static buffer containing human readable text for the shortcut
*/ */
const char* fl_shortcut_label(int shortcut) { const char* fl_shortcut_label(int shortcut) {
return fl_shortcut_label(shortcut, 0L);
}
/**
Get a human-readable string from a shortcut value.
\param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers
\param [in] eom if this pointer is set, it will receive a pointer to the end of the modifier text
\return a pointer to a static buffer containing human readable text for the shortcut
\see fl_shortcut_label(int shortcut)
*/
const char* fl_shortcut_label(int shortcut, const char **eom) {
static char buf[20]; static char buf[20];
char *p = buf; char *p = buf;
if (eom) *eom = p;
if (!shortcut) {*p = 0; return buf;} if (!shortcut) {*p = 0; return buf;}
// fix upper case shortcuts // fix upper case shortcuts
int v = shortcut & 0xffff; int v = shortcut & 0xffff;
@ -202,6 +219,7 @@ const char* fl_shortcut_label(int shortcut) {
if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;}
if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
#endif // __APPLE__ #endif // __APPLE__
if (eom) *eom = p;
int key = shortcut & 0xFFFF; int key = shortcut & 0xFFFF;
#if defined(WIN32) || defined(__APPLE__) // if not X #if defined(WIN32) || defined(__APPLE__) // if not X
if (key >= FL_F && key <= FL_F_Last) { if (key >= FL_F && key <= FL_F_Last) {
@ -215,8 +233,14 @@ const char* fl_shortcut_label(int shortcut) {
while (a < b) { while (a < b) {
int c = (a+b)/2; int c = (a+b)/2;
if (table[c].key == key) { if (table[c].key == key) {
if (p > buf) {strcpy(p,table[c].name); return buf;} if (p > buf) {
return table[c].name; strcpy(p,table[c].name);
return buf;
} else {
const char *sp = table[c].name;
if (eom) *eom = sp;
return sp;
}
} }
if (table[c].key < key) a = c+1; if (table[c].key < key) a = c+1;
else b = c; else b = c;
@ -238,7 +262,13 @@ const char* fl_shortcut_label(int shortcut) {
else if (key > 32 && key < 0x100) q = 0; else if (key > 32 && key < 0x100) q = 0;
else q = XKeysymToString(key); else q = XKeysymToString(key);
if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;} if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;}
if (p > buf) {strcpy(p,q); return buf;} else return q; if (p > buf) {
strcpy(p,q);
return buf;
} else {
if (eom) *eom = q;
return q;
}
#endif #endif
} }