Improve NS dialogs. Add close button, remove ugly casts.

* nsmenu.m (initWithContentRect:styleMask:backing:defer:): Initialize
button_values to NULL. Call setStykeMask so dialogs get a close button.
(windowShouldClose:): Set window_closed.
(dealloc): New member, free button_values.
(process_dialog:): Make member function. Remove window argument,
replace window with self. Count buttons and allocate and store values
in button_values.
(addButton:value:row:): value is int with the name tag.  Call setTag
with tag. Remove return self, declare return value as void.
(addString:row:): Remove return self, declare return value as void.
(addSplit): Remove return self, declare return value as void.
(clicked:): Remove return self, declare return value as void.
Set dialog_return to button_values[seltag]. Code formatting change.
(initFromContents:isQuestion:): Adjust call to process_dialog.
Code formatting change.
(timeout_handler:): Set timer_fired to YES.
(runDialogAt:): Set timer_fired to NO.
Handle click on close button as quit.

* nsterm.h (EmacsDialogPanel): Make timer_fired BOOL.
Add window_closed and button_values.  Add void as return value for
add(Button|String|Split).  addButton takes int instead of Lisp_Object.
Add process_dialog as new member.
This commit is contained in:
Jan Djärv 2012-08-28 18:05:17 +02:00
parent eada086196
commit 7f8941d8b2
3 changed files with 80 additions and 40 deletions

View file

@ -1,3 +1,29 @@
2012-08-28 Jan Djärv <jan.h.d@swipnet.se>
* nsmenu.m (initWithContentRect:styleMask:backing:defer:): Initialize
button_values to NULL. Call setStykeMask so dialogs get a close button.
(windowShouldClose:): Set window_closed.
(dealloc): New member, free button_values.
(process_dialog:): Make member function. Remove window argument,
replace window with self. Count buttons and allocate and store values
in button_values.
(addButton:value:row:): value is int with the name tag. Call setTag
with tag. Remove return self, declare return value as void.
(addString:row:): Remove return self, declare return value as void.
(addSplit): Remove return self, declare return value as void.
(clicked:): Remove return self, declare return value as void.
Set dialog_return to button_values[seltag]. Code formatting change.
(initFromContents:isQuestion:): Adjust call to process_dialog.
Code formatting change.
(timeout_handler:): Set timer_fired to YES.
(runDialogAt:): Set timer_fired to NO.
Handle click on close button as quit.
* nsterm.h (EmacsDialogPanel): Make timer_fired BOOL.
Add window_closed and button_values. Add void as return value for
add(Button|String|Split). addButton takes int instead of Lisp_Object.
Add process_dialog as new member.
2012-08-28 Eli Zaretskii <eliz@gnu.org>
* ralloc.c (free_bloc): Don't dereference a 'heap' structure if it

View file

@ -1498,6 +1498,7 @@ @implementation EmacsDialogPanel
NSImage *img;
dialog_return = Qundefined;
button_values = NULL;
area.origin.x = 3*SPACER;
area.origin.y = 2*SPACER;
area.size.width = ICONSIZE;
@ -1579,44 +1580,65 @@ @implementation EmacsDialogPanel
[self setOneShot: YES];
[self setReleasedWhenClosed: YES];
[self setHidesOnDeactivate: YES];
[self setStyleMask:
NSTitledWindowMask|NSClosableWindowMask|NSUtilityWindowMask];
return self;
}
- (BOOL)windowShouldClose: (id)sender
{
window_closed = YES;
[NSApp stop:self];
return NO;
}
void process_dialog (id window, Lisp_Object list)
- (void)dealloc
{
Lisp_Object item;
xfree (button_values);
[super dealloc];
}
- (void)process_dialog: (Lisp_Object) list
{
Lisp_Object item, lst = list;
int row = 0;
int buttons = 0, btnnr = 0;
for (; XTYPE (lst) == Lisp_Cons; lst = XCDR (lst))
{
item = XCAR (list);
if (XTYPE (item) == Lisp_Cons)
++buttons;
}
if (buttons > 0)
button_values = (Lisp_Object *) xmalloc (buttons * sizeof (*button_values));
for (; XTYPE (list) == Lisp_Cons; list = XCDR (list))
{
item = XCAR (list);
if (XTYPE (item) == Lisp_String)
{
[window addString: SSDATA (item) row: row++];
[self addString: SSDATA (item) row: row++];
}
else if (XTYPE (item) == Lisp_Cons)
{
[window addButton: SSDATA (XCAR (item))
value: XCDR (item) row: row++];
button_values[btnnr] = XCDR (item);
[self addButton: SSDATA (XCAR (item)) value: btnnr row: row++];
++btnnr;
}
else if (NILP (item))
{
[window addSplit];
[self addSplit];
row = 0;
}
}
}
- addButton: (char *)str value: (Lisp_Object)val row: (int)row
- (void)addButton: (char *)str value: (int)tag row: (int)row
{
id cell;
@ -1629,15 +1651,13 @@ void process_dialog (id window, Lisp_Object list)
[cell setTarget: self];
[cell setAction: @selector (clicked: )];
[cell setTitle: [NSString stringWithUTF8String: str]];
[cell setTag: XHASH (val)]; // FIXME: BIG UGLY HACK!!
[cell setTag: tag];
[cell setBordered: YES];
[cell setEnabled: YES];
return self;
}
- addString: (char *)str row: (int)row
- (void)addString: (char *)str row: (int)row
{
id cell;
@ -1650,36 +1670,28 @@ void process_dialog (id window, Lisp_Object list)
[cell setTitle: [NSString stringWithUTF8String: str]];
[cell setBordered: YES];
[cell setEnabled: NO];
return self;
}
- addSplit
- (void)addSplit
{
[matrix addColumn];
cols++;
return self;
}
- clicked: sender
- (void)clicked: sender
{
NSArray *sellist = nil;
EMACS_INT seltag;
sellist = [sender selectedCells];
if ([sellist count]<1)
return self;
if ([sellist count] < 1)
return;
seltag = [[sellist objectAtIndex: 0] tag];
if (seltag != XHASH (Qundefined)) // FIXME: BIG UGLY HACK!!
{
dialog_return = seltag;
[NSApp stop:self];
}
return self;
dialog_return = button_values[seltag];
[NSApp stop:self];
}
@ -1691,7 +1703,7 @@ void process_dialog (id window, Lisp_Object list)
if (XTYPE (contents) == Lisp_Cons)
{
head = Fcar (contents);
process_dialog (self, Fcdr (contents));
[self process_dialog: Fcdr (contents)];
}
else
head = contents;
@ -1711,7 +1723,7 @@ void process_dialog (id window, Lisp_Object list)
if (cols == 1 && rows > 1) /* Never told where to split */
{
[matrix addColumn];
for (i = 0; i<rows/2; i++)
for (i = 0; i < rows/2; i++)
{
[matrix putCell: [matrix cellAtRow: (rows+1)/2 column: 0]
atRow: i column: 1];
@ -1771,7 +1783,7 @@ - (void)timeout_handler: (NSTimer *)timedEntry
data1: 0
data2: 0];
timer_fired = 1;
timer_fired = YES;
/* We use sto because stopModal/abortModal out of the main loop does not
seem to work in 10.6. But as we use stop we must send a real event so
the stop is seen and acted upon. */
@ -1799,9 +1811,9 @@ - (Lisp_Object)runDialogAt: (NSPoint)p
[[NSRunLoop currentRunLoop] addTimer: tmo
forMode: NSModalPanelRunLoopMode];
}
timer_fired = 0;
timer_fired = NO;
dialog_return = Qundefined;
ret = [NSApp runModalForWindow: self];
[NSApp runModalForWindow: self];
ret = dialog_return;
if (! timer_fired)
{
@ -1810,11 +1822,11 @@ - (Lisp_Object)runDialogAt: (NSPoint)p
}
}
{ /* FIXME: BIG UGLY HACK!!! */
Lisp_Object tmp;
*(EMACS_INT*)(&tmp) = ret;
return tmp;
}
if (EQ (ret, Qundefined) && window_closed)
/* Make close button pressed equivalent to C-g. */
Fsignal (Qquit, Qnil);
return ret;
}
@end

View file

@ -195,13 +195,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
NSTextField *title;
NSMatrix *matrix;
int rows, cols;
int timer_fired;
BOOL timer_fired, window_closed;
Lisp_Object dialog_return;
Lisp_Object *button_values;
}
- initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ;
- addButton: (char *)str value: (Lisp_Object)val row: (int)row;
- addString: (char *)str row: (int)row;
- addSplit;
- (void)process_dialog: (Lisp_Object)list;
- (void)addButton: (char *)str value: (int)tag row: (int)row;
- (void)addString: (char *)str row: (int)row;
- (void)addSplit;
- (Lisp_Object)runDialogAt: (NSPoint)p;
- (void)timeout_handler: (NSTimer *)timedEntry;
@end