mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-04-23 06:20:47 +00:00
Fixes to handle matrixes better. Editable matrix cells. Improved
editors for window size and buttons. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@10917 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
4e2f2e9eea
commit
6f5ebc106f
12 changed files with 851 additions and 190 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2001-09-16 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Fixes to handle matrixes better. Editable matrix cells. Improved
|
||||
editors for window size and buttons.
|
||||
* GormObjectEditor.m ([GormViewSizeInspector -init]): Add size
|
||||
form for resizing. New methods for resizing and obtaining
|
||||
window sizes.
|
||||
* GormMatrixEditor.m: New class for editing matrix cells.
|
||||
* GormWindowEditor.m (_editTextView:withEvent:) Moved to
|
||||
GormMatrixEditor.m.
|
||||
(-_validateFrame:forViewPtr:withEvent:update:update): When replacing
|
||||
view with matrix detach old view and attach matrix to document.
|
||||
(-mouseDown:): Open matrix subeditor on double-click of matrix.
|
||||
(-deleteSelection): Detach subviews of a box before deleting box.
|
||||
|
||||
* Palettes/2Controls/inspectors.m: New button inspector.
|
||||
|
||||
2001-08-21 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
|
||||
|
||||
Added the ability to change the font of the selected objects
|
||||
|
|
|
@ -86,6 +86,7 @@ Gorm_OBJC_FILES = \
|
|||
GormViewKnobs.m \
|
||||
GormFilesOwner.m \
|
||||
GormClassEditor.m \
|
||||
GormMatrixEditor.m \
|
||||
GormObjectEditor.m \
|
||||
GormObjectInspector.m \
|
||||
GormWindowEditor.m \
|
||||
|
|
2
Gorm.m
2
Gorm.m
|
@ -1182,7 +1182,7 @@ main(int argc, const char **argv)
|
|||
extern BOOL NSImageDoesCaching;
|
||||
|
||||
NSImageDoesCaching = YES;
|
||||
//[NSObject enableDoubleReleaseCheck: YES];
|
||||
//[NSObject enableDoubleReleaseCheck: YES];
|
||||
|
||||
NSApplicationMain(argc, argv);
|
||||
|
||||
|
|
|
@ -1218,7 +1218,6 @@ static NSImage *classesImage = nil;
|
|||
id obj = [nameTable objectForKey: name];
|
||||
|
||||
NSMapInsert(objToName, (void*)obj, (void*)name);
|
||||
|
||||
if ([obj isKindOfClass: [NSMenu class]] == YES)
|
||||
{
|
||||
[objectsView addObject: obj];
|
||||
|
|
434
GormMatrixEditor.m
Normal file
434
GormMatrixEditor.m
Normal file
|
@ -0,0 +1,434 @@
|
|||
/* GormMatrixEditor.m - Editor for matrices.
|
||||
*
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Adam Fedor <fedor@gnu.org>
|
||||
* Date: Sep 2001
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "GormPrivate.h"
|
||||
|
||||
@implementation NSMatrix (GormObjectAdditions)
|
||||
- (NSString*) editorClassName
|
||||
{
|
||||
return @"GormMatrixEditor";
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSForm (GormAdditions)
|
||||
- (float) titleWidth;
|
||||
@end
|
||||
|
||||
@implementation NSForm (GormAdditions)
|
||||
|
||||
- (float)titleWidth
|
||||
{
|
||||
int i, count = [self numberOfRows];
|
||||
float new_title_width = 0;
|
||||
float candidate_title_width = 0;
|
||||
|
||||
// Compute max of title width in the cells
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
candidate_title_width = [_cells[i][0] titleWidth];
|
||||
if (candidate_title_width > new_title_width)
|
||||
new_title_width = candidate_title_width;
|
||||
}
|
||||
return new_title_width;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GormMatrixEditor
|
||||
|
||||
static NSMapTable *docMap = 0;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [GormMatrixEditor class])
|
||||
{
|
||||
docMap = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 2);
|
||||
}
|
||||
}
|
||||
|
||||
- (id) changeSelection: (id)sender
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) copySelection
|
||||
{
|
||||
if (selected != nil)
|
||||
{
|
||||
[document copyObjects: [self selection]
|
||||
type: IBViewPboardType
|
||||
toPasteboard: [NSPasteboard generalPasteboard]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(matrix);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) deleteSelection
|
||||
{
|
||||
NSLog(@"Cannot delete Matrix cell\n");
|
||||
}
|
||||
|
||||
static BOOL done_editing;
|
||||
|
||||
- (void) handleNotification: (NSNotification*)aNotification
|
||||
{
|
||||
NSString *name = [aNotification name];
|
||||
if ([name isEqual: NSControlTextDidEndEditingNotification] == YES)
|
||||
{
|
||||
done_editing = YES;
|
||||
}
|
||||
else
|
||||
NSLog(@"GormMatrixEditor got unhandled notification %@", name);
|
||||
}
|
||||
|
||||
- (id) editedObject
|
||||
{
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialisation
|
||||
*/
|
||||
- (id) initWithObject: (id)anObject inDocument: (id<IBDocuments>)aDocument
|
||||
{
|
||||
id old = NSMapGet(docMap, (void*)aDocument);
|
||||
|
||||
if (old != nil)
|
||||
{
|
||||
RELEASE(self);
|
||||
self = RETAIN(old);
|
||||
[self changeObject: anObject];
|
||||
return self;
|
||||
}
|
||||
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
document = aDocument;
|
||||
NSMapInsert(docMap, (void*)aDocument, (void*)self);
|
||||
[self changeObject: anObject];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Called when we double-click on a text/editable cell or form. Overlay
|
||||
a text field so the user can edit the title.
|
||||
FIXME: Only works with NSForms now, doesn't handle different fonts
|
||||
or cell sizes, etc. Needs some work.*/
|
||||
- (void) editTitleWithEvent: (NSEvent *)theEvent
|
||||
{
|
||||
int row, col;
|
||||
unsigned eventMask;
|
||||
id edit_view;
|
||||
BOOL isForm;
|
||||
NSRect frame;
|
||||
NSTextField *editField;
|
||||
NSDate *future = [NSDate distantFuture];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
isForm = [matrix isKindOfClass: [NSForm class]];
|
||||
if (isForm == NO && [selected type] != NSTextCellType)
|
||||
return;
|
||||
|
||||
/* FIXME: Seems wierd to do this. */
|
||||
edit_view = [matrix superview];
|
||||
|
||||
[matrix getRow: &row column: &col ofCell: selected];
|
||||
frame = [matrix cellFrameAtRow: row column: col];
|
||||
frame.origin.x += NSMinX([matrix frame]);
|
||||
if (isForm)
|
||||
frame.size.width = [(NSForm *)matrix titleWidth];
|
||||
else
|
||||
frame = [selected titleRectForBounds: frame];
|
||||
if ([matrix isFlipped])
|
||||
{
|
||||
frame.origin.y = NSMaxY([matrix frame]) - NSMaxY(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.origin.y = NSMinY([matrix frame]) + NSMinY(frame);
|
||||
}
|
||||
|
||||
/* Now create an edit field and allow the user to edit the text */
|
||||
editField = [[NSTextField alloc] initWithFrame: frame];
|
||||
[editField setEditable: YES];
|
||||
[editField setSelectable: YES];
|
||||
[editField setBezeled: NO];
|
||||
[editField setEnabled: YES];
|
||||
if (isForm)
|
||||
[editField setStringValue: [(NSFormCell *)selected title]];
|
||||
else
|
||||
[editField setStringValue: [selected stringValue]];
|
||||
[edit_view addSubview: editField];
|
||||
[edit_view displayRect: frame];
|
||||
[nc addObserver: self
|
||||
selector: @selector(handleNotification:)
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
|
||||
/* Do some modal editing */
|
||||
[editField selectText: self];
|
||||
eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
||||
NSKeyDownMask | NSKeyUpMask | NSFlagsChangedMask;
|
||||
|
||||
done_editing = NO;
|
||||
while (!done_editing)
|
||||
{
|
||||
NSEvent *e;
|
||||
NSEventType eType;
|
||||
e = [NSApp nextEventMatchingMask: eventMask
|
||||
untilDate: future
|
||||
inMode: NSEventTrackingRunLoopMode
|
||||
dequeue: YES];
|
||||
eType = [e type];
|
||||
switch (eType)
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
{
|
||||
NSPoint dp = [edit_view convertPoint: [e locationInWindow]
|
||||
fromView: nil];
|
||||
if (NSMouseInRect(dp, frame, NO) == NO)
|
||||
{
|
||||
done_editing = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[[editField currentEditor] mouseDown: e];
|
||||
break;
|
||||
case NSLeftMouseUp:
|
||||
[[editField currentEditor] mouseUp: e];
|
||||
break;
|
||||
case NSLeftMouseDragged:
|
||||
[[editField currentEditor] mouseDragged: e];
|
||||
break;
|
||||
case NSKeyDown:
|
||||
[[editField currentEditor] keyDown: e];
|
||||
break;
|
||||
case NSKeyUp:
|
||||
[[editField currentEditor] keyUp: e];
|
||||
break;
|
||||
case NSFlagsChanged:
|
||||
[[editField currentEditor] flagsChanged: e];
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Internal Error: Unhandled event during editing: %@", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[nc removeObserver: self
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
|
||||
[self makeSelectionVisible: NO];
|
||||
if (isForm)
|
||||
{
|
||||
/* Set the new title and resize the form to match the titles */
|
||||
float oldTitleWidth, titleWidth;
|
||||
NSRect oldFrame;
|
||||
oldTitleWidth = [(NSForm *)matrix titleWidth];
|
||||
[(NSFormCell *)selected setTitle: [editField stringValue]];
|
||||
[(NSForm *)matrix calcSize];
|
||||
titleWidth = [(NSForm *)matrix titleWidth];
|
||||
oldFrame = frame = [matrix frame];
|
||||
frame.origin.x -= (titleWidth - oldTitleWidth);
|
||||
frame.size.width += (titleWidth - oldTitleWidth);
|
||||
[(NSForm *)matrix setEntryWidth: NSWidth(frame)];
|
||||
[(NSForm *)matrix setFrame: frame];
|
||||
frame = NSUnionRect(frame, oldFrame);
|
||||
}
|
||||
else
|
||||
[selected setStringValue: [editField stringValue]];
|
||||
|
||||
[edit_view removeSubview: editField];
|
||||
[edit_view displayRect: frame];
|
||||
[self makeSelectionVisible: YES];
|
||||
|
||||
RELEASE(editField);
|
||||
}
|
||||
|
||||
- (void) mouseDown: (NSEvent*)theEvent
|
||||
{
|
||||
int row, col;
|
||||
id obj;
|
||||
NSPoint loc = [theEvent locationInWindow];
|
||||
|
||||
/*
|
||||
* Double-click on a cell allows one to edit the cell title
|
||||
*/
|
||||
if (selected != nil && ([theEvent clickCount] == 2) )
|
||||
{
|
||||
[self editTitleWithEvent: theEvent];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find which cell the mouse is in */
|
||||
loc = [matrix convertPoint: loc fromView: nil];
|
||||
if ([matrix getRow: &row column: &col forPoint: loc] == NO)
|
||||
return;
|
||||
|
||||
NSLog(@"Got hit in cell %d %d", row, col);
|
||||
obj = [matrix cellAtRow: row column: col];
|
||||
if (obj != nil && obj != selected)
|
||||
{
|
||||
[self selectObjects: [NSArray arrayWithObject: obj]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) makeSelectionVisible: (BOOL)flag
|
||||
{
|
||||
if (selected != nil)
|
||||
{
|
||||
int row, col;
|
||||
if ([matrix getRow: &row column: &col ofCell: selected])
|
||||
{
|
||||
NSRect frame = [matrix cellFrameAtRow: row column: col];
|
||||
if (flag == YES)
|
||||
[matrix selectCellAtRow: row column: col];
|
||||
[matrix lockFocus];
|
||||
[[NSColor controlShadowColor] set];
|
||||
NSHighlightRect(frame);
|
||||
[matrix unlockFocus];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[matrix deselectAllCells];
|
||||
}
|
||||
[matrix display];
|
||||
[[matrix window] flushWindow];
|
||||
}
|
||||
|
||||
- (void) changeObject: anObject
|
||||
{
|
||||
ASSIGN(matrix, anObject);
|
||||
selected = nil;
|
||||
}
|
||||
|
||||
- (void) selectObjects: (NSArray*)anArray
|
||||
{
|
||||
id obj = [anArray lastObject];
|
||||
[self makeSelectionVisible: NO];
|
||||
selected = obj;
|
||||
[document setSelectionFromEditor: self];
|
||||
[self makeSelectionVisible: YES];
|
||||
}
|
||||
|
||||
- (NSArray*) selection
|
||||
{
|
||||
if (selected == nil)
|
||||
return [NSArray array];
|
||||
else
|
||||
return [NSArray arrayWithObject: selected];
|
||||
}
|
||||
|
||||
- (unsigned) selectionCount
|
||||
{
|
||||
return (selected == nil) ? 0 : 1;
|
||||
}
|
||||
|
||||
- (id<IBEditors>) openSubeditorForObject: (id)anObject
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) acceptsTypeFromArray: (NSArray*)types
|
||||
{
|
||||
if ([types containsObject: IBObjectPboardType] == YES)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) activate
|
||||
{
|
||||
NSLog(@"Ack - GormMatrix - activate");
|
||||
//[[self window] makeKeyAndOrderFront: self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) close
|
||||
{
|
||||
[self deactivate];
|
||||
[self closeSubeditors];
|
||||
}
|
||||
|
||||
- (void) closeSubeditors
|
||||
{
|
||||
}
|
||||
|
||||
- (void) deactivate
|
||||
{
|
||||
selected = nil;
|
||||
}
|
||||
|
||||
- (void) drawSelection
|
||||
{
|
||||
}
|
||||
|
||||
- (id<IBDocuments>) document
|
||||
{
|
||||
return document;
|
||||
}
|
||||
|
||||
- (void) orderFront
|
||||
{
|
||||
NSLog(@"Ack - GormMatrix - orderFront");
|
||||
//[[self window] orderFront: self];
|
||||
}
|
||||
|
||||
- (void) pasteInSelection
|
||||
{
|
||||
}
|
||||
|
||||
- (void) resetObject: (id)anObject
|
||||
{
|
||||
[self changeObject: anObject];
|
||||
selected = nil;
|
||||
}
|
||||
|
||||
- (void) validateEditing
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL) wantsSelection
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSWindow*) window
|
||||
{
|
||||
NSLog(@"Ack - GormMatrix - window");
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
@ -687,6 +687,7 @@ static NSMapTable *docMap = 0;
|
|||
NSButton *right;
|
||||
NSButton *width;
|
||||
NSButton *height;
|
||||
NSForm *sizeForm;
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -729,6 +730,7 @@ NSImage *mVLine = nil;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
RELEASE(window);
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -740,7 +742,7 @@ NSImage *mVLine = nil;
|
|||
{
|
||||
NSView *contents;
|
||||
NSButton *button;
|
||||
NSBox *box;
|
||||
NSBox *box, *sizeBox;
|
||||
NSRect rect;
|
||||
|
||||
rect = NSMakeRect(0, 0, IVW, IVH);
|
||||
|
@ -750,6 +752,36 @@ NSImage *mVLine = nil;
|
|||
defer: NO];
|
||||
contents = [window contentView];
|
||||
|
||||
rect = NSMakeRect((IVW-200)/2, IVW, 200, 80);
|
||||
sizeBox = [[NSBox alloc] initWithFrame: NSZeroRect];
|
||||
[sizeBox setBorderType: NSBezelBorder];
|
||||
[sizeBox setTitle: @"Size"];
|
||||
[sizeBox setTitlePosition: NSAtTop];
|
||||
[sizeBox setFrameFromContentFrame: rect];
|
||||
[contents addSubview: sizeBox];
|
||||
RELEASE(sizeBox);
|
||||
|
||||
rect = NSMakeRect(25, 5, 150, 75);
|
||||
sizeForm = [[NSForm alloc] initWithFrame: rect];
|
||||
[sizeForm addEntry: @"X"];
|
||||
[sizeForm addEntry: @"Y"];
|
||||
[sizeForm addEntry: @"Width"];
|
||||
[sizeForm addEntry: @"Height"];
|
||||
[sizeForm setEntryWidth: 150];
|
||||
[sizeForm setInterlineSpacing: 3];
|
||||
[sizeBox addSubview: sizeForm];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(viewFrameChangeNotification:)
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(controlTextDidEndEditing:)
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
|
||||
rect = NSMakeRect((IVW-200)/2, (IVW-200)/2, 200, 200);
|
||||
box = [[NSBox alloc] initWithFrame: NSZeroRect];
|
||||
[box setBorderType: NSBezelBorder];
|
||||
|
@ -846,6 +878,47 @@ NSImage *mVLine = nil;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) _setValuesFromControl: control
|
||||
{
|
||||
if (control == sizeForm)
|
||||
{
|
||||
NSRect rect;
|
||||
rect = NSMakeRect([[control cellAtIndex: 0] floatValue],
|
||||
[[control cellAtIndex: 1] floatValue],
|
||||
[[control cellAtIndex: 2] floatValue],
|
||||
[[control cellAtIndex: 3] floatValue]);
|
||||
[object setFrame: rect];
|
||||
[object setNeedsDisplay: YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _getValuesFromObject: anObject
|
||||
{
|
||||
NSRect frame;
|
||||
|
||||
if (anObject != object)
|
||||
return;
|
||||
|
||||
frame = [anObject frame];
|
||||
[[sizeForm cellAtIndex: 0] setFloatValue: NSMinX(frame)];
|
||||
[[sizeForm cellAtIndex: 1] setFloatValue: NSMinY(frame)];
|
||||
[[sizeForm cellAtIndex: 2] setFloatValue: NSWidth(frame)];
|
||||
[[sizeForm cellAtIndex: 3] setFloatValue: NSHeight(frame)];
|
||||
}
|
||||
|
||||
- (void) controlTextDidEndEditing: (NSNotification*)aNotification
|
||||
{
|
||||
id notifier = [aNotification object];
|
||||
[self _setValuesFromControl: notifier];
|
||||
}
|
||||
|
||||
- (void) viewFrameChangeNotification: (NSNotification*)aNotification
|
||||
{
|
||||
id notifier = [aNotification object];
|
||||
|
||||
[self _getValuesFromObject: notifier];
|
||||
}
|
||||
|
||||
- (void) setAutosize: (id)sender
|
||||
{
|
||||
unsigned mask = [sender tag];
|
||||
|
@ -863,8 +936,12 @@ NSImage *mVLine = nil;
|
|||
|
||||
- (void) setObject: (id)anObject
|
||||
{
|
||||
if (object != nil)
|
||||
[object setPostsFrameChangedNotifications: NO];
|
||||
|
||||
if (anObject != nil && anObject != object)
|
||||
{
|
||||
NSRect frame;
|
||||
unsigned mask = [anObject autoresizingMask];
|
||||
|
||||
ASSIGN(object, anObject);
|
||||
|
@ -897,6 +974,13 @@ NSImage *mVLine = nil;
|
|||
[height setState: NSOnState];
|
||||
else
|
||||
[height setState: NSOffState];
|
||||
|
||||
frame = [anObject frame];
|
||||
[[sizeForm cellAtIndex: 0] setFloatValue: NSMinX(frame)];
|
||||
[[sizeForm cellAtIndex: 1] setFloatValue: NSMinY(frame)];
|
||||
[[sizeForm cellAtIndex: 2] setFloatValue: NSWidth(frame)];
|
||||
[[sizeForm cellAtIndex: 3] setFloatValue: NSHeight(frame)];
|
||||
[anObject setPostsFrameChangedNotifications: YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,16 @@ extern NSString *GormLinkPboardType;
|
|||
- (NSWindow*) window;
|
||||
@end
|
||||
|
||||
@interface GormMatrixEditor : NSObject <IBEditors>
|
||||
{
|
||||
id<IBDocuments> document;
|
||||
id selected;
|
||||
NSMatrix *matrix;
|
||||
}
|
||||
|
||||
- (void) changeObject: anObject;
|
||||
@end
|
||||
|
||||
/*
|
||||
* Functions for drawing knobs etc.
|
||||
*/
|
||||
|
|
|
@ -62,46 +62,6 @@ _constrainPointToBounds(NSPoint point, NSRect bounds)
|
|||
return point;
|
||||
}
|
||||
|
||||
@interface NSFormCell (GormAdditions)
|
||||
- (void) printAuto;
|
||||
@end
|
||||
|
||||
@implementation NSFormCell (GormAdditions)
|
||||
|
||||
- (void) printAuto
|
||||
{
|
||||
NSLog(@"Auto for cell is %d, width %f",
|
||||
_formcell_auto_title_width, _displayedTitleWidth);
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSForm (GormAdditions)
|
||||
- (float) titleWidth;
|
||||
@end
|
||||
|
||||
@implementation NSForm (GormAdditions)
|
||||
|
||||
- (float)titleWidth
|
||||
{
|
||||
int i, count = [self numberOfRows];
|
||||
float new_title_width = 0;
|
||||
float candidate_title_width = 0;
|
||||
|
||||
// Compute max of title width in the cells
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
candidate_title_width = [_cells[i][0] titleWidth];
|
||||
[_cells[i][0] printAuto];
|
||||
if (candidate_title_width > new_title_width)
|
||||
new_title_width = candidate_title_width;
|
||||
}
|
||||
return new_title_width;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation NSWindow (GormObjectAdditions)
|
||||
- (NSString*) editorClassName
|
||||
{
|
||||
|
@ -240,145 +200,6 @@ _constrainPointToBounds(NSPoint point, NSRect bounds)
|
|||
return nil;
|
||||
}
|
||||
|
||||
static BOOL done_editing;
|
||||
|
||||
- (void) handleTextEditNotification: (NSNotification*)aNotification
|
||||
{
|
||||
NSString *name = [aNotification name];
|
||||
|
||||
if ([name isEqual: NSControlTextDidEndEditingNotification] == YES)
|
||||
{
|
||||
done_editing = YES;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when we double-click on a text/editable field or form. Overlay
|
||||
a text field so the user can enter the text.
|
||||
FIXME: Only works with NSForms now, doesn't handle different fonts
|
||||
or cell sizes, etc. Needs some work.*/
|
||||
- (void) _editTextView: (NSView *)view withEvent: (NSEvent *)theEvent
|
||||
{
|
||||
int row, col;
|
||||
unsigned eventMask;
|
||||
NSRect frame;
|
||||
NSPoint point;
|
||||
NSCell *editCell;
|
||||
NSTextField *editField;
|
||||
NSDate *future = [NSDate distantFuture];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
point = [edit_view convertPoint: [theEvent locationInWindow]
|
||||
fromView: nil];
|
||||
point = [view convertPoint: point fromView: edit_view];
|
||||
if ([(NSForm *)view getRow: &row column: &col forPoint: point] == NO)
|
||||
return;
|
||||
|
||||
editCell = [(NSForm *)view cellAtRow: row column: col];
|
||||
frame = [(NSForm *)view cellFrameAtRow: row column: col];
|
||||
frame.origin.x += NSMinX([view frame]);
|
||||
frame.size.width = [(NSForm *)view titleWidth];
|
||||
if ([view isFlipped])
|
||||
{
|
||||
frame.origin.y = NSMaxY([view frame]) - NSMaxY(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.origin.y = NSMinY([view frame]) + NSMinY(frame);
|
||||
}
|
||||
|
||||
/* Now create an edit field and allow the user to edit the text */
|
||||
editField = [[NSTextField alloc] initWithFrame: frame];
|
||||
[editField setEditable: YES];
|
||||
[editField setSelectable: YES];
|
||||
[editField setBezeled: NO];
|
||||
[editField setEnabled: YES];
|
||||
[editField setStringValue: [(NSFormCell *)editCell title]];
|
||||
[edit_view addSubview: editField];
|
||||
[edit_view displayRect: frame];
|
||||
[nc addObserver: self
|
||||
selector: @selector(handleTextEditNotification:)
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
|
||||
/* Do some modal editing */
|
||||
[editField selectText: self];
|
||||
eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
||||
NSKeyDownMask | NSKeyUpMask | NSFlagsChangedMask;
|
||||
|
||||
done_editing = NO;
|
||||
while (!done_editing)
|
||||
{
|
||||
NSEvent *e;
|
||||
NSEventType eType;
|
||||
e = [NSApp nextEventMatchingMask: eventMask
|
||||
untilDate: future
|
||||
inMode: NSEventTrackingRunLoopMode
|
||||
dequeue: YES];
|
||||
eType = [e type];
|
||||
switch (eType)
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
{
|
||||
NSPoint dp = [edit_view convertPoint: [e locationInWindow]
|
||||
fromView: nil];
|
||||
if (NSMouseInRect(dp, frame, NO) == NO)
|
||||
{
|
||||
done_editing = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[[editField currentEditor] mouseDown: e];
|
||||
break;
|
||||
case NSLeftMouseUp:
|
||||
[[editField currentEditor] mouseUp: e];
|
||||
break;
|
||||
case NSLeftMouseDragged:
|
||||
[[editField currentEditor] mouseDragged: e];
|
||||
break;
|
||||
case NSKeyDown:
|
||||
[[editField currentEditor] keyDown: e];
|
||||
break;
|
||||
case NSKeyUp:
|
||||
[[editField currentEditor] keyUp: e];
|
||||
break;
|
||||
case NSFlagsChanged:
|
||||
[[editField currentEditor] flagsChanged: e];
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Internal Error: Unhandled event during editing: %@", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[nc removeObserver: self
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
|
||||
/* Set the new title and resize the form to match the titles */
|
||||
[self makeSelectionVisible: NO];
|
||||
{
|
||||
float oldTitleWidth, titleWidth;
|
||||
NSRect oldFrame;
|
||||
oldTitleWidth = [(NSForm *)view titleWidth];
|
||||
[(NSFormCell *)editCell setTitle: [editField stringValue]];
|
||||
[(NSForm *)view calcSize];
|
||||
titleWidth = [(NSForm *)view titleWidth];
|
||||
NSLog(@"old width %f new %f", oldTitleWidth, titleWidth);
|
||||
oldFrame = frame = [view frame];
|
||||
frame.origin.x -= (titleWidth - oldTitleWidth);
|
||||
frame.size.width += (titleWidth - oldTitleWidth);
|
||||
[(NSForm *)view setEntryWidth: NSWidth(frame)];
|
||||
[(NSForm *)view setFrame: frame];
|
||||
frame = NSUnionRect(frame, oldFrame);
|
||||
}
|
||||
[edit_view removeSubview: editField];
|
||||
[edit_view displayRect: frame];
|
||||
[self makeSelectionVisible: YES];
|
||||
|
||||
RELEASE(editField);
|
||||
}
|
||||
|
||||
|
||||
/* Called when the frame of a view object is changed. Takes care of
|
||||
validating the frame and updating the object */
|
||||
- (BOOL) _validateFrame: (NSRect)frame
|
||||
|
@ -473,8 +294,9 @@ static BOOL done_editing;
|
|||
cellSize.width = [view frame].size.width;
|
||||
cellSize.height = [view frame].size.height;
|
||||
/* Remove this view and add the new matrix */
|
||||
[document detachObject: view];
|
||||
[document attachObject: matrix toParent: edited];
|
||||
[edit_view addSubview: AUTORELEASE(matrix)];
|
||||
//[self makeSelectionVisible: NO];
|
||||
array = [NSMutableArray arrayWithArray: [self selection]];
|
||||
[array removeObjectIdenticalTo: view];
|
||||
[array addObject: matrix];
|
||||
|
@ -715,6 +537,7 @@ static BOOL done_editing;
|
|||
[self selectObjects: [NSArray arrayWithObject: view]];
|
||||
}
|
||||
}
|
||||
[self closeSubeditors];
|
||||
}
|
||||
else if ([selection indexOfObjectIdenticalTo: view] == NSNotFound)
|
||||
{
|
||||
|
@ -722,6 +545,7 @@ static BOOL done_editing;
|
|||
* This view has just been deselected.
|
||||
*/
|
||||
view = nil;
|
||||
[self closeSubeditors];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -768,13 +592,25 @@ static BOOL done_editing;
|
|||
[[view superview] unlockFocus];
|
||||
[self selectObjects: [NSArray array]];
|
||||
}
|
||||
else if ([view isKindOfClass: [NSForm class]])
|
||||
else if ([view isKindOfClass: [NSMatrix class]])
|
||||
{
|
||||
[self _editTextView: view withEvent: theEvent];
|
||||
return;
|
||||
id subeditor;
|
||||
if ((subeditor = [self openSubeditorForObject: view]) == nil)
|
||||
{
|
||||
NSLog(@"Could not open editor for %@", view);
|
||||
}
|
||||
if ([subeditor editedObject] != view)
|
||||
[subeditor changeObject: view];
|
||||
}
|
||||
}
|
||||
|
||||
/* If a subeditor exists, it should handle the mouse events */
|
||||
if ([subeditors lastObject])
|
||||
{
|
||||
[[subeditors lastObject] mouseDown: theEvent];
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Having determined the current selection, we now handle events.
|
||||
*/
|
||||
|
@ -1301,6 +1137,13 @@ static BOOL done_editing;
|
|||
{
|
||||
id obj = [a objectAtIndex: c];
|
||||
|
||||
if ([obj isKindOfClass: [NSBox class]] == YES)
|
||||
{
|
||||
NSArray *sub = [obj subviews];
|
||||
int sc = [sub count];
|
||||
while (sc-- > 0)
|
||||
[document detachObject: [sub objectAtIndex: sc] ];
|
||||
}
|
||||
[document detachObject: obj];
|
||||
[self setNeedsDisplayInRect: [obj frame]];
|
||||
[obj removeFromSuperview];
|
||||
|
@ -1481,6 +1324,7 @@ static BOOL done_editing;
|
|||
{
|
||||
[subeditors addObject: sub];
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ PALETTE_NAME = 2Controls
|
|||
2Controls_PRINCIPAL_CLASS = ControlsPalette
|
||||
|
||||
2Controls_RESOURCE_FILES = ControlsPalette.tiff \
|
||||
GormButtonInspector.gorm \
|
||||
GormSliderInspector.gorm \
|
||||
GormStepperInspector.gorm
|
||||
|
||||
|
|
78
Palettes/2Controls/GormButtonInspector.classes
Normal file
78
Palettes/2Controls/GormButtonInspector.classes
Normal file
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
GormButtonInspector = {
|
||||
Actions = (
|
||||
);
|
||||
Outlets = (
|
||||
alignMatrix,
|
||||
iconMatrix,
|
||||
keyField,
|
||||
optionMatrix,
|
||||
tagField,
|
||||
titleForm,
|
||||
typeButton
|
||||
);
|
||||
Super = IBInspector;
|
||||
};
|
||||
IBInspector = {
|
||||
Actions = (
|
||||
);
|
||||
Outlets = (
|
||||
okButton,
|
||||
revertButton,
|
||||
window
|
||||
);
|
||||
Super = NSObject;
|
||||
};
|
||||
NSApplication = {
|
||||
Outlets = (
|
||||
delegate
|
||||
);
|
||||
Super = NSResponder;
|
||||
};
|
||||
NSButton = {
|
||||
Super = NSControl;
|
||||
};
|
||||
NSControl = {
|
||||
Actions = (
|
||||
"takeDoubleValueFrom:",
|
||||
"takeFloatValueFrom:",
|
||||
"takeIntValueFrom:",
|
||||
"takeObjectValueFrom:",
|
||||
"takeStringValueFrom:"
|
||||
);
|
||||
Outlets = (
|
||||
target
|
||||
);
|
||||
Super = NSView;
|
||||
};
|
||||
NSMenu = {
|
||||
Super = NSObject;
|
||||
};
|
||||
NSMenuItem = {
|
||||
Outlets = (
|
||||
target
|
||||
);
|
||||
Super = NSObject;
|
||||
};
|
||||
NSResponder = {
|
||||
Super = NSObject;
|
||||
};
|
||||
NSSlider = {
|
||||
Super = NSControl;
|
||||
};
|
||||
NSTextField = {
|
||||
Outlets = (
|
||||
delegate
|
||||
);
|
||||
Super = NSControl;
|
||||
};
|
||||
NSView = {
|
||||
Super = NSResponder;
|
||||
};
|
||||
NSWindow = {
|
||||
Outlets = (
|
||||
delegate
|
||||
);
|
||||
Super = NSResponder;
|
||||
};
|
||||
}
|
BIN
Palettes/2Controls/GormButtonInspector.gorm
Normal file
BIN
Palettes/2Controls/GormButtonInspector.gorm
Normal file
Binary file not shown.
|
@ -25,16 +25,206 @@
|
|||
#include <AppKit/AppKit.h>
|
||||
#include "../../GormPrivate.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
NSButton
|
||||
*/
|
||||
@implementation NSButton (IBInspectorClassNames)
|
||||
- (NSString*) inspectorClassName
|
||||
{
|
||||
return @"GormButtonAttributesInspector";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface GormButtonAttributesInspector : IBInspector
|
||||
{
|
||||
id alignMatrix;
|
||||
id iconMatrix;
|
||||
id keyField;
|
||||
id optionMatrix;
|
||||
id tagField;
|
||||
id titleForm;
|
||||
id typeButton;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GormButtonAttributesInspector
|
||||
|
||||
- (void) _setValuesFromControl: control
|
||||
{
|
||||
if (control == alignMatrix)
|
||||
{
|
||||
[object setAlignment: (NSTextAlignment)[[control selectedCell] tag] ];
|
||||
}
|
||||
else if (control == iconMatrix)
|
||||
{
|
||||
[object setImagePosition:
|
||||
(NSCellImagePosition)[[control selectedCell] tag] ];
|
||||
}
|
||||
else if (control == keyField)
|
||||
{
|
||||
[object setKeyEquivalent: [[control cellAtIndex: 0] stringValue] ];
|
||||
}
|
||||
else if (control == optionMatrix)
|
||||
{
|
||||
BOOL flag;
|
||||
flag = ([[control cellAtRow: 0 column: 0] state] == NSOnState) ? YES : NO;
|
||||
[object setBordered: flag];
|
||||
flag = ([[control cellAtRow: 1 column: 0] state] == NSOnState) ? YES : NO;
|
||||
[object setContinuous: flag];
|
||||
flag = ([[control cellAtRow: 2 column: 0] state] == NSOnState) ? YES : NO;
|
||||
[object setEnabled: flag];
|
||||
|
||||
[object setState: [[control cellAtRow: 3 column: 0] state]];
|
||||
flag = ([[control cellAtRow: 4 column: 0] state] == NSOnState) ? YES : NO;
|
||||
[object setTransparent: flag];
|
||||
}
|
||||
else if (control == tagField)
|
||||
{
|
||||
[object setTag: [[control cellAtIndex: 0] intValue] ];
|
||||
}
|
||||
else if (control == titleForm)
|
||||
{
|
||||
NSString *string;
|
||||
NSImage *image;
|
||||
[object setTitle: [[control cellAtIndex: 0] stringValue] ];
|
||||
[object setAlternateTitle: [[control cellAtIndex: 1] stringValue] ];
|
||||
string = [[control cellAtIndex: 2] stringValue];
|
||||
if ([string length] > 0)
|
||||
{
|
||||
image = [NSImage imageNamed: string ];
|
||||
[object setImage: image ];
|
||||
}
|
||||
string = [[control cellAtIndex: 3] stringValue];
|
||||
if ([string length] > 0)
|
||||
{
|
||||
image = [NSImage imageNamed: string ];
|
||||
[object setAlternateImage: image ];
|
||||
}
|
||||
}
|
||||
else if (control == typeButton)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _getValuesFromObject: anObject
|
||||
{
|
||||
NSImage *image;
|
||||
if (anObject != object)
|
||||
return;
|
||||
|
||||
[alignMatrix selectCellWithTag: [anObject alignment] ];
|
||||
[iconMatrix selectCellWithTag: [anObject imagePosition] ];
|
||||
[[keyField cellAtIndex: 0] setStringValue: [anObject keyEquivalent] ];
|
||||
|
||||
[optionMatrix deselectAllCells];
|
||||
if ([anObject isBordered])
|
||||
[optionMatrix selectCellAtRow: 0 column: 0];
|
||||
if ([anObject isContinuous])
|
||||
[optionMatrix selectCellAtRow: 1 column: 0];
|
||||
if ([anObject isEnabled])
|
||||
[optionMatrix selectCellAtRow: 2 column: 0];
|
||||
if ([anObject state] == NSOnState)
|
||||
[optionMatrix selectCellAtRow: 3 column: 0];
|
||||
if ([anObject isTransparent])
|
||||
[optionMatrix selectCellAtRow: 4 column: 0];
|
||||
|
||||
[[tagField cellAtIndex: 0] setIntValue: [anObject tag] ];
|
||||
|
||||
[[titleForm cellAtIndex: 0] setStringValue: [anObject title] ];
|
||||
[[titleForm cellAtIndex: 1] setStringValue: [anObject alternateTitle] ];
|
||||
image = [anObject image];
|
||||
if (image)
|
||||
[[titleForm cellAtIndex: 2] setStringValue: [image name] ];
|
||||
else
|
||||
[[titleForm cellAtIndex: 2] setStringValue: @""];
|
||||
image = [anObject alternateImage];
|
||||
if (image)
|
||||
[[titleForm cellAtIndex: 3] setStringValue: [image name] ];
|
||||
else
|
||||
[[titleForm cellAtIndex: 3] setStringValue: @"" ];
|
||||
|
||||
}
|
||||
|
||||
- (void) controlTextDidEndEditing: (NSNotification*)aNotification
|
||||
{
|
||||
id notifier = [aNotification object];
|
||||
[self _setValuesFromControl: notifier];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
RELEASE(window);
|
||||
RELEASE(okButton);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ([super init] == nil)
|
||||
return nil;
|
||||
|
||||
if ([NSBundle loadNibNamed: @"GormButtonInspector" owner: self] == NO)
|
||||
{
|
||||
NSLog(@"Could not gorm GormButtonInspector");
|
||||
return nil;
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(controlTextDidEndEditing:)
|
||||
name: NSControlTextDidEndEditingNotification
|
||||
object: nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) wantsButtons
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSButton*) okButton
|
||||
{
|
||||
if (okButton == nil)
|
||||
{
|
||||
okButton = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,90,20)];
|
||||
[okButton setAutoresizingMask: NSViewMaxYMargin | NSViewMinXMargin];
|
||||
[okButton setAction: @selector(ok:)];
|
||||
[okButton setTarget: self];
|
||||
[okButton setTitle: @"OK"];
|
||||
[okButton setEnabled: YES];
|
||||
}
|
||||
return okButton;
|
||||
}
|
||||
|
||||
- (void) ok: (id)sender
|
||||
{
|
||||
[self _setValuesFromControl: alignMatrix];
|
||||
[self _setValuesFromControl: iconMatrix];
|
||||
[self _setValuesFromControl: keyField];
|
||||
[self _setValuesFromControl: tagField];
|
||||
[self _setValuesFromControl: titleForm];
|
||||
[self _setValuesFromControl: optionMatrix];
|
||||
[self _setValuesFromControl: typeButton];
|
||||
}
|
||||
|
||||
- (void) setObject: (id)anObject
|
||||
{
|
||||
[super setObject: anObject];
|
||||
[self _getValuesFromObject: anObject];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
NSSlider
|
||||
*/
|
||||
@implementation NSSlider (IBInspectorClassNames)
|
||||
- (NSString*) inspectorClassName
|
||||
{
|
||||
return @"GormSliderAttributesInspector";
|
||||
}
|
||||
|
||||
- (NSString*) sizeInspectorClassName
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface GormSliderAttributesInspector : IBInspector
|
||||
|
@ -123,6 +313,9 @@
|
|||
|
||||
@end
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
NSStepper
|
||||
*/
|
||||
@implementation NSStepper (IBInspectorClassNames)
|
||||
- (NSString*) inspectorClassName
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue