SCTextField: let's rewrite it

View: New views
4 Messages — Rating Filter:   Alert me  

SCTextField: let's rewrite it

by Dan Stowell :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi -

As discussed in the "new help search" thread, SCTextField doesn't work
like a standard Cocoa text field, because it's implemented in its own
unique way rather than using NSTextField. For usability purposes it
would be better if it worked in the standard way.

I've coded a version that uses NSTextField - attached is a diff for
the source, and a class file, with a bit of test code too. It creates
a class "SCTextField2" class, so it doesn't actually interfere with
current SCTextField behaviour. Comments welcome on the implementation.
A worthwhile thing to do?

Dan

--
http://www.mcld.co.uk

Index: Source/app/SCView.M
===================================================================
--- Source/app/SCView.M (revision 7550)
+++ Source/app/SCView.M (working copy)
@@ -5816,6 +5816,7 @@
 extern SCView* NewSCCocoaTextView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 extern SCView* NewSCMovieView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 extern SCView* NewSCQuartzComposerView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+extern SCView* NewSCTextField(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 
 void registerSCViewClasses()
 {
@@ -5848,6 +5849,7 @@
     new SCViewMaker("SCTextView", NewSCCocoaTextView);
     new SCViewMaker("SCMovieView", NewSCMovieView);
  new SCViewMaker("SCQuartzComposerView", NewSCQuartzComposerView);
+    new SCViewMaker("SCTextField2", NewSCTextField);
  new SCViewMaker("SCScrollTopView", NewSCScrollTopView);
  new SCViewMaker("SCScrollView", NewSCScrollView);
 }
Index: Source/app/SCCocoaView.M
===================================================================
--- Source/app/SCCocoaView.M (revision 7550)
+++ Source/app/SCCocoaView.M (working copy)
@@ -222,6 +222,47 @@
 
 @end
 
+
+@implementation SCTextFieldResponder
+
+- (struct PyrObject*)getSCObject
+{
+ return mSCViewObject->GetSCObj();
+}
+- (void)controlTextDidChange:(NSNotification *)aNotification
+{
+ textReallyChanged = true;
+}
+- (void)controlTextDidEndEditing:(NSNotification *)aNotification
+{
+ if(textReallyChanged){
+ pthread_mutex_lock (&gLangMutex);
+ PyrSymbol *method = getsym("doAction");
+ PyrObject *mObj;
+ if (mObj = mSCViewObject->GetSCObj()) {
+ VMGlobals *g = gMainVMGlobals;
+ g->canCallOS = true;
+ ++g->sp;  SetObject(g->sp, mObj);
+ runInterpreter(g, method, 1);
+ g->canCallOS = false;
+ }
+ pthread_mutex_unlock (&gLangMutex);
+ textReallyChanged = false;
+ }
+}
+- (void)controlTextDidBeginEditing:(NSNotification *)aNotification
+{
+ textReallyChanged = false;
+}
+
+- (void)setSCView: (struct SCTextField*)inObject
+{
+ mSCViewObject = inObject;
+}
+
+@end
+
+
 NSRect SCtoNSRect(SCRect screct);
 
 SCView* NewSCCocoaTextView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds)
@@ -1344,3 +1385,141 @@
  }
  mTop->resetFocus();
 }
+
+
+
+////////////////////
+SCView* NewSCTextField(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds)
+{
+ return new SCTextField(inParent, inObj, inBounds);
+}
+
+SCTextField::SCTextField(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds)
+ : SCView(inParent, inObj, inBounds)
+{
+ NSRect matrect = SCtoNSRect(getDrawBounds());
+ mTextField = [[NSTextField alloc] initWithFrame:matrect];
+ NSView *view = mTop->GetNSView();
+ [view addSubview: mTextField];
+
+ mCocoaToLangAction = [SCTextFieldResponder alloc];
+ [mCocoaToLangAction setSCView: this];
+ [mTextField setDelegate: mCocoaToLangAction];
+
+ setVisibleFromParent();
+}
+
+SCTextField::~SCTextField()
+{
+ [mTextField removeFromSuperview];
+ [mTextField release];
+}
+
+void SCTextField::setBounds(SCRect screct)
+{
+ [[mTextField superview] setNeedsDisplayInRect:[mTextField frame]];
+ mBounds = screct;
+ if(mParent->relativeOrigin()){
+ SCRect pbounds = mParent->getBounds();
+ mLayout.bounds.x = mBounds.x + pbounds.x;
+ mLayout.bounds.y = mBounds.y + pbounds.y;
+ mLayout.bounds.width = mBounds.width;
+ mLayout.bounds.height = mBounds.height;
+ } else {
+ mLayout.bounds = mBounds;
+ }
+
+ [mTextField setFrame: SCtoNSRect(mLayout.bounds)];
+ [mTextField setBounds: SCtoNSRect(mBounds)]; //?
+ [mTextField setNeedsDisplay: YES];
+}
+
+int SCTextField::setProperty(PyrSymbol *symbol, PyrSlot *slot)
+{
+ int err;
+ char *name = symbol->name;
+
+ if (strcmp(name, "string")==0) {
+ if(!isKindOfSlot(slot, class_string)) return errWrongType;
+ PyrString* pstring = slot->uos;
+ if(!pstring) return errNone;
+ NSString *string = [[NSString alloc] initWithCString: pstring->s length: pstring->size];
+ [mTextField setStringValue: string];
+ [string release];
+ return errNone;
+ }
+
+ if (strcmp(name, "visible")==0) {
+ bool visible = IsTrue(slot);
+ mVisible = visible;
+ setVisibleFromParent();
+ return errNone;
+ }
+
+ if (strcmp(name, "bounds")==0) {
+ SCRect screct;
+ err = slotGetSCRect(slot, &screct);
+ if (err) return err;
+ setBounds(screct);
+ return errNone;
+ }
+
+ if (strcmp(name, "setEditable")==0) {
+ if(IsTrue(slot))[mTextField setEditable: YES];
+ else{
+ [mTextField setEditable: NO];
+ [mTextField abortEditing]; // If cursor is in cell, this is required to stop it.
+ }
+ return errNone;
+ }
+
+ if (strcmp(name, "align")==0) {
+ int align;
+ if (IsSym(slot)) {
+ if (slot->us->name[0] == 'l')      [mTextField setAlignment: NSLeftTextAlignment];
+ else if (slot->us->name[0] == 'r') [mTextField setAlignment: NSRightTextAlignment];
+ else if (slot->us->name[0] == 'c') [mTextField setAlignment: NSCenterTextAlignment];
+ else return errFailed;
+ }/* else {
+ err = slotIntVal(slot, &align);
+ if (err) return err;
+ mAlignment = align;
+ } */
+ refresh();
+ return errNone;
+ }
+
+ return SCView::setProperty(symbol, slot);
+}
+
+
+int SCTextField::getProperty(PyrSymbol *symbol, PyrSlot *slot)
+{
+ char *name = symbol->name;
+
+ if (strcmp(name, "string")==0) {
+ NSString* str = [mTextField stringValue];
+        const char * cstr = [str UTF8String];
+        PyrString *string = newPyrString(NULL, cstr, 0, true);
+        SetObject(slot, string);
+ return errNone;
+ }
+
+ return SCView::getProperty(symbol, slot);
+}
+
+
+void SCTextField::setVisibleFromParent()
+{
+ if(mVisible && mParent->isVisible()) {
+ [mTextField setHidden:NO];
+ } else {
+ [mTextField setHidden:YES];
+ }
+ [mTextField setNeedsDisplay:YES];
+ NSRect frame = [mTextField frame];
+ [mTextField setFrame: NSInsetRect(frame,1,1)];
+ [mTextField setFrame: frame];
+ mTop->resetFocus();
+ refresh();
+}
Index: Headers/app/SCCocoaView.h
===================================================================
--- Headers/app/SCCocoaView.h (revision 7550)
+++ Headers/app/SCCocoaView.h (working copy)
@@ -60,6 +60,19 @@
 
 @end
 
+@interface SCTextFieldResponder : NSResponder
+{
+ struct SCTextField *mSCViewObject;
+ bool textReallyChanged;
+}
+
+- (struct PyrObject*)getSCObject;
+- (void)controlTextDidChange:(NSNotification *)aNotification;
+- (void)controlTextDidEndEditing:(NSNotification *)aNotification;
+- (void)controlTextDidBeginEditing:(NSNotification *)aNotification;
+- (void)setSCView: (struct SCTextField*)inObject;
+@end
+
 class SCCocoaTextView : public SCView
 {
 public:
@@ -101,6 +114,21 @@
  Movie mMovie;
 };
 
+class SCTextField : public SCView
+{
+public:
+ SCTextField(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+ virtual ~SCTextField();
+ virtual void setBounds(SCRect inBounds);
+ virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
+ virtual void setVisibleFromParent();
+
+protected:
+ NSTextField *mTextField;
+ SCTextFieldResponder *mCocoaToLangAction;
+};
+
 //////////////////////////////////////
 /*
  SCQuartzComposerView by Scott Wilson
@@ -127,4 +155,5 @@
 SCView* NewSCCocoaTextView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 SCView* NewSCMovieView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 SCView* NewSCQuartzComposerView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
+SCView* NewSCTextField(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
 


_______________________________________________
Sc-devel mailing list
Sc-devel@...
http://lists.create.ucsb.edu/mailman/listinfo/sc-devel

SCTextField2.sc (1K) Download Attachment

Re: SCTextField: let's rewrite it

by Josh Parmenter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 9, 2008, at 10:58 AM, Dan Stowell wrote:

>
> A worthwhile thing to do?
>
Hell yeah.

Josh

> Dan
>
> --  
> http://www.mcld.co.uk
> <svndiff-
> tf
> .txt><SCTextField2.sc>_______________________________________________
> Sc-devel mailing list
> Sc-devel@...
> http://lists.create.ucsb.edu/mailman/listinfo/sc-devel

******************************************
/* Joshua D. Parmenter
http://www.realizedsound.net/josh/

“Every composer – at all times and in all cases – gives his own  
interpretation of how modern society is structured: whether actively  
or passively, consciously or unconsciously, he makes choices in this  
regard. He may be conservative or he may subject himself to continual  
renewal; or he may strive for a revolutionary, historical or social  
palingenesis." - Luigi Nono
*/

_______________________________________________
Sc-devel mailing list
Sc-devel@...
http://lists.create.ucsb.edu/mailman/listinfo/sc-devel

Re: SCTextField: let's rewrite it

by felix-38 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


copy ... paste ?!

is it easy to do a rich text accepting field ?  low priority, just curious.



On Fri, May 9, 2008 at 8:05 PM, Josh Parmenter <josh@...> wrote:

On May 9, 2008, at 10:58 AM, Dan Stowell wrote:

>
> A worthwhile thing to do?
>
Hell yeah.

Josh

> Dan
>
> --

_______________________________________________
Sc-devel mailing list
Sc-devel@...
http://lists.create.ucsb.edu/mailman/listinfo/sc-devel

Re: SCTextField: let's rewrite it

by Dan Stowell :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/5/9 felix <felix@...>:
>
> copy ... paste ?!

You betcha. One of the pleasantries that comes for free with NSTextField.

> is it easy to do a rich text accepting field ?  low priority, just curious.

Probably possible, since I think Cocoa provides some hooks for
rich-text things in these boxes, but let's keep that kind of thing off
the list for now...

Dan


> On Fri, May 9, 2008 at 8:05 PM, Josh Parmenter <josh@...>
> wrote:
>>
>> On May 9, 2008, at 10:58 AM, Dan Stowell wrote:
>>
>> >
>> > A worthwhile thing to do?
>> >
>> Hell yeah.
>>
>> Josh
>>
>> > Dan
>> >
>> > --
>
> _______________________________________________
> Sc-devel mailing list
> Sc-devel@...
> http://lists.create.ucsb.edu/mailman/listinfo/sc-devel
>
>



--
http://www.mcld.co.uk
_______________________________________________
Sc-devel mailing list
Sc-devel@...
http://lists.create.ucsb.edu/mailman/listinfo/sc-devel