This is InputlinePanel.m in view mode; [Download] [Up]
/*+++*
* title: InputlinePanel.m
* abstract: An Inputline Panel in the style of NeXTSTEPs Alert Panel.
* author: T.R.Hageman <Tom_Hageman@RnA.nl>
* created:
* modified: (see RCS Log at end)
* copyright:
*
* Copyright (C) 1996 by Tom R. Hageman.
*
* This software may be redistributed, used and modified without
* restriction, as long as this copyright notice is left intact,
* and modified versions of this software are clearly marked as such.
*
* This software 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.
*
* description:
* (see corresponding *.h file)
*---*/
#import "InputlinePanel.h"
@implementation InputlinePanel
+ (const char *const *)resourcePaths
{
static const char *const paths[] = {
"~/Library/Resources",
"/LocalLibrary/Resources",
NULL
};
return paths;
}
static id theInputlinePanel;
+ new
{
if (theInputlinePanel == nil)
{
const char *nibName = "InputlinePanel";
NXBundle *bundle = [NXBundle mainBundle];
char nibPath[MAXPATHLEN+1];
if ([bundle getPath:nibPath forResource:nibName ofType:"nib"]) {
[NXApp loadNibFile:nibPath owner:self];
// This had better invoke -awakeFromNib, see below.
}
else {
// Not found in ``main bundle'';
// Try some semi-standard locations instead.
const char *const *searchPaths = [self resourcePaths];
const char *searchPath;
while ((searchPath = *searchPaths++) != NULL) {
if (searchPath[0] == '~') {
sprintf(nibPath, "%s%s", NXHomeDirectory(),
&searchPath[1]);
searchPath = nibPath;
}
bundle = [[NXBundle alloc]
initForDirectory:searchPath];
if (bundle == nil) continue;
if ([bundle getPath:nibPath
forResource:nibName ofType:"nib"]) {
[bundle free];
// Found one!
[NXApp loadNibFile:nibPath owner:self];
break;
}
[bundle free];
}
}
}
return theInputlinePanel;
}
- awakeFromNib
{
// Set shared instance pointer when unarchived from nib.
theInputlinePanel = self;
return self;
}
- free
{
// Allow shared instance to be freed (and eventually reloaded.)
if (self == theInputlinePanel) theInputlinePanel = nil;
return [super free];
}
// Button actions.
- cancel:sender
{
[NXApp stopModal:NX_CANCELTAG];
return self;
}
- ok:sender
{
if ([self makeFirstResponder:self])
{
[self endEditingFor:nil];
}
[NXApp stopModal:NX_OKTAG];
return self;
}
// Private support methods
- (void)_adjustSizeOfControl:(Control *)control vertically:(BOOL)vertically
{
NXRect oldFrame, newFrame;
NXSize diff;
[control getFrame:&oldFrame];
if (vertically) {
Cell *cell = [control cell];
NXRect bounds;
NXSize cellSize;
[control getBounds:&bounds];
[cell calcCellSize:&cellSize inRect:&bounds];
// XXX This assumes no scaling (scale factor = 1):
[control sizeTo:cellSize.width :cellSize.height];
}
else {
// XXX This can ge way too wide if string is long enough.
[control sizeToFit];
}
[control getFrame:&newFrame];
diff.width = (newFrame.size.width - oldFrame.size.width);
diff.height = (newFrame.size.height - oldFrame.size.height);
if (diff.width < 0) {
[control sizeBy:-diff.width :0];
diff.width = 0;
}
if (diff.width ||diff.height) {
Window *window = [control window];
NXRect windowFrame;
[window getFrame:&windowFrame];
windowFrame.size.width += diff.width;
windowFrame.size.height += diff.height;
windowFrame.origin.x -= diff.width / 2;
windowFrame.origin.y -= diff.height;
[window placeWindow:&windowFrame];
}
}
- (void)_centerAtScreen
{
// Adjust frame for actual screen size.
const NXSize designScreenSize = { 1120, 832 };
const NXScreen *s = [NXApp mainScreen];
NXRect f;
NXPoint mid;
if (s->screenBounds.size.width == designScreenSize.width &&
s->screenBounds.size.height == designScreenSize.height) {
return;
}
[self getFrame:&f];
mid.x = f.origin.x + f.size.width / 2;
mid.y = f.origin.y + f.size.height / 2;
// scale
mid.x = mid.x * s->screenBounds.size.width / designScreenSize.width;
mid.y = mid.y * s->screenBounds.size.height / designScreenSize.height;
f.origin.x = mid.x - f.size.width / 2;
f.origin.y = mid.y - f.size.height / 2;
[self placeWindow:&f];
}
// Access methods.
- (void)setTitle:(const char *)aTitle
{
[titleField setStringValue:aTitle];
}
- (const char *)title { return [titleField stringValue]; }
- (void)setPrompt:(const char *)aPrompt
{
[promptField setStringValue:aPrompt];
}
- (const char *)prompt { return [promptField stringValue]; }
- (void)setInputline:(const char *)anInputline
{
[inputField setStringValue:anInputline];
[inputField selectText:self];
}
- (const char *)inputline { return [inputField stringValue]; }
- (int)runModal
{
return [self runModalWithInputline:"" invisible:NO];
}
- (int)runModalWithInputline:(const char *)anInputline
invisible:(BOOL)isInvisible;
{
NXRect orgFrame;
int result;
float savedTextGray = 0;
if (isInvisible) {
savedTextGray = [inputField textGray];
[inputField setTextGray:[inputField backgroundGray]];
}
[self setInputline:anInputline];
// Dynamically adjust control (and window) sizes.
[self getFrame:&orgFrame];
[self _centerAtScreen];
[self _adjustSizeOfControl:titleField vertically:NO];
[self _adjustSizeOfControl:promptField vertically:YES];
[self makeKeyAndOrderFront:self];
result = [NXApp runModalFor:self];
[self orderOut:self];
// Restore original panel frame.
[self placeWindow:&orgFrame];
if (isInvisible) {
[inputField setTextGray:savedTextGray];
}
return result;
}
@end // InputlinePanel
/*======================================================================
* $Log: InputlinePanel.m,v $
* Revision 1.3 1996/03/31 20:34:48 tom
* fixed mail address;
* (+new): avoid using -loadNibSection: since that prints a distracting error
* message if the nib is not found; locate it explicitly in main bundle,
* then -loadNibFile: instead.
*
* Revision 1.2 1996/03/28 23:15:33 tom
* (-_adjustSizeOfControl:vertically:,-_centerAtScreen:): new private support
* methods;
* (-setInputline:): select its text;
* (-runModalWithInputline:): center and adjust size of panel before displaying
* it on-screen; restore original panel size afterwards.
*
* Revision 1.1 1996/03/27 23:03:31 tom
* Initial revision
*
*======================================================================*/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.