2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <Cocoa/Cocoa.h>
23 #include <Carbon/Carbon.h>
26 #include "PyrSymbol.h"
27 #include "PyrPrimitive.h"
28 #include "PyrObject.h"
29 #include "PyrKernel.h"
31 #include "VMGlobals.h"
33 #include "SC_BoundsMacros.h"
34 #include "SC_InlineBinaryOp.h"
35 #include "SCGraphView.h"
36 #import "SCVirtualMachine.h"
43 void QDDrawBevelRect(CGContextRef cgc
, CGRect bounds
, float width
, bool inout);
45 SCViewMaker
*gSCViewMakers
= 0;
46 SCView
*gAnimatedViews
= 0;
48 extern PyrSymbol
* s_color
;
49 extern PyrSymbol
* s_doaction
;
50 extern PyrSymbol
* s_draw
;
58 PyrSymbol
* s_sccontview
;
59 PyrSymbol
* s_sctopview
;
60 PyrSymbol
* s_scscrollview
;
61 PyrSymbol
* s_beginDrag
;
62 PyrSymbol
* s_receiveDrag
;
63 PyrSymbol
* s_canReceiveDrag
;
64 PyrSymbol
* s_mouseDown
;
66 PyrSymbol
* s_callDrawFunc
;
67 PyrSymbol
* s_toggleEditMode
;
69 extern pthread_mutex_t gLangMutex
;
71 int stringDrawCenteredInRect(const char *cString
, SCRect screct
, char *cFontName
, float fontSize
, SCColor sccolor
);
72 int stringDrawLeftInRect(const char *cString
, SCRect screct
, char *cFontName
, float fontSize
, SCColor sccolor
);
73 int stringDrawRightInRect(const char *cString
, SCRect screct
, char *cFontName
, float fontSize
, SCColor sccolor
);
75 int nsStringDrawInRectAlign(NSString
*nsstring
, SCRect screct
, char *cFontName
, float fontSize
, SCColor sccolor
, int hAlign
, int vAlign
, NSSize
*outSize
);
77 RGBColor
SCtoQDColor(SCColor sccolor
)
81 qdcolor.red
= (unsigned short)(sccolor.red
* 65535.
);
82 qdcolor.green
= (unsigned short)(sccolor.green
* 65535.
);
83 qdcolor.blue
= (unsigned short)(sccolor.blue
* 65535.
);
87 // CoreGraphics coords get switched around in an NSQuickDrawView
88 Rect
SCtoQDRect(SCRect screct
)
92 qdrect.left
= (int)screct.x
;
93 qdrect.top
= (int)screct.y
;
94 qdrect.right
= (int)(screct.x
+ screct.width
);
95 qdrect.bottom
= (int)(screct.y
+ screct.height
);
99 CGRect
SCtoCGRect(SCRect screct
)
103 cgrect.origin.x
= screct.x
;
104 cgrect.origin.y
= screct.y
;
105 cgrect.size.width
= screct.width
;
106 cgrect.size.height
= screct.height
;
110 int slotColorVal(PyrSlot
*slot
, SCColor
*sccolor
)
112 if (!(isKindOfSlot(slot
, s_color
->u.classobj
))) return errWrongType
;
114 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
117 err
= slotFloatVal(slots
+0, &sccolor
->red
);
119 err
= slotFloatVal(slots
+1, &sccolor
->green
);
121 err
= slotFloatVal(slots
+2, &sccolor
->blue
);
123 err
= slotFloatVal(slots
+3, &sccolor
->alpha
);
127 int setSlotColor(PyrSlot
*slot
, SCColor
*sccolor
)
129 if (!(isKindOfSlot(slot
, s_color
->u.classobj
))) return errWrongType
;
131 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
133 SetFloat(slots
+0, sccolor
->red
);
134 SetFloat(slots
+1, sccolor
->green
);
135 SetFloat(slots
+2, sccolor
->blue
);
136 SetFloat(slots
+3, sccolor
->alpha
);
140 int slotGetSCRect(PyrSlot
* a
, SCRect
*r
)
142 if (!isKindOfSlot(a
, s_rect
->u.classobj
)) return errWrongType
; // arg check - br
143 PyrSlot
*slots
= slotRawObject(a
)->slots
;
145 err
= slotFloatVal(slots
+0, &r
->x
);
147 err
= slotFloatVal(slots
+1, &r
->y
);
149 err
= slotFloatVal(slots
+2, &r
->width
);
151 err
= slotFloatVal(slots
+3, &r
->height
);
158 int getBackgroundVal(PyrSlot
*slot
, DrawBackground
*inPtr
);
159 int getBackgroundVal(PyrSlot
*slot
, DrawBackground
*inPtr
)
162 //inPtr->GetSlot(slot);
166 int slotBackgroundVal(PyrSlot
*slot
, DrawBackground
**ioPtr
);
167 int slotBackgroundVal(PyrSlot
*slot
, DrawBackground
**ioPtr
)
169 int err
, direction
, steps
;
170 SCColor color1
, color2
;
171 PyrClass
*classobj
= classOfSlot(slot
);
172 char *classname
= slotRawSymbol(&classobj
->name
)->name
;
174 if (strcmp(classname
, "Color")==0) {
175 err
= slotColorVal(slot
, &color1
);
179 *ioPtr
= new SolidColorBackground(color1
);
180 } else if (strcmp(classname
, "Gradient") == 0) {
181 PyrObject
*obj
= slotRawObject(slot
);
182 PyrSlot
*slots
= obj
->slots
;
184 err
= slotColorVal(slots
+0, &color1
);
186 err
= slotColorVal(slots
+1, &color2
);
189 if (IsSym(slots
+2)) {
190 if (strncmp(slotRawSymbol(&slots
[2])->name
, "h", 1)==0) direction
= grad_Horizontal
;
191 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "v", 1)==0) direction
= grad_Vertical
;
192 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "n", 1)==0) direction
= grad_Narrow
;
193 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "w", 1)==0) direction
= grad_Wide
;
194 else direction
= grad_Vertical
;
196 direction
= grad_Horizontal
;
199 err
= slotIntVal(slots
+3, &steps
);
203 *ioPtr
= new GradientBackground(color1
, color2
, direction
, steps
);
205 } else if (strcmp(classname
, "HiliteGradient") == 0) {
206 PyrObject
*obj
= slotRawObject(slot
);
207 PyrSlot
*slots
= obj
->slots
;
209 err
= slotColorVal(slots
+0, &color1
);
211 err
= slotColorVal(slots
+1, &color2
);
214 if (IsSym(slots
+2)) {
215 if (strncmp(slotRawSymbol(&slots
[2])->name
, "h", 1)==0) direction
= grad_Horizontal
;
216 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "v", 1)==0) direction
= grad_Vertical
;
217 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "n", 1)==0) direction
= grad_Narrow
;
218 else if (strncmp(slotRawSymbol(&slots
[2])->name
, "w", 1)==0) direction
= grad_Wide
;
219 else direction
= grad_Vertical
;
221 direction
= grad_Horizontal
;
224 err
= slotIntVal(slots
+3, &steps
);
228 err
= slotFloatVal(slots
+4, &frac
);
232 *ioPtr
= new HiliteGradientBackground(color1
, color2
, direction
, steps
, frac
);
238 int slotBackgroundImageVal(PyrSlot
*slot
, DrawBackground
**ioPtr
);
239 int slotBackgroundImageVal(PyrSlot
*slot
, DrawBackground
**ioPtr
)
241 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
243 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
244 PyrClass
*classobj
= classOfSlot(slots
+ 0);
245 char *classname
= slotRawSymbol(&classobj
->name
)->name
;
246 if( strcmp(classname
, "SCImage") == 0 )
250 PyrObject
*obj
= slotRawObject(slots
+ 0);
251 scImage
= (SCImage
*)slotRawPtr(obj
->slots
+ 0); // Instance of Cocoa SCImage
254 err
= slotIntVal(slots
+1, &tileMode
);
258 err
= slotFloatVal(slots
+2, &frac
);
262 if (NotNil(slots
+3)) {
265 err
= slotGetSCRect(slots
+3, &screct
);
268 fromRect
= NSMakeRect(screct.x
, screct.y
, screct.width
, screct.height
);
272 fromRect
= NSMakeRect(0.
, 0.
, [scImage width
], [scImage height
]);
277 *ioPtr
= new SCImageBackground(scImage
, fromRect
, tileMode
, frac
);
282 // for any sc class that supports mouseDown and mouseUp methods
283 #import "TabletEvents.h"
285 #define TABLETTRACK(METHOD,X,Y) \
287 pthread_mutex_lock (&gLangMutex
); \
288 VMGlobals
*g
= gMainVMGlobals
; \
289 g
->canCallOS
= true; \
290 ++g
->sp
; SetObject(g
->sp
, mObj
); \
291 SetFloat(++g
->sp
, X
); \
292 SetFloat(++g
->sp
, Y
); \
293 SetFloat(++g
->sp
, (float)[theEvent pressure
]); \
295 tilt
= (NSPoint
)[theEvent tilt
]; \
296 SetFloat(++g
->sp
, tilt.x
); \
297 SetFloat(++g
->sp
, tilt.y
); \
298 SetInt(++g
->sp
,[theEvent deviceID
]); \
299 SetInt(++g
->sp
,[theEvent buttonNumber
]); \
300 SetInt(++g
->sp
,[theEvent clickCount
]); \
301 SetInt(++g
->sp
,[theEvent absoluteZ
]); \
302 SetFloat(++g
->sp
,[theEvent rotationInDegrees
]); \
303 runInterpreter(g
, METHOD
, 11); \
304 g
->canCallOS
= false; \
305 pthread_mutex_unlock (&gLangMutex
); \
313 : mMinWidth(0.
), mMaxWidth(10000.
), mMinHeight(0.
), mMaxHeight(10000.
), mWeight(1.
),
314 mShouldResize(true), mHResize(layout_FixedLeft
), mVResize(layout_FixedTop
) {
317 SCView
::SCView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
318 : mNext(0), mNextAnimatedView(0), mPrevAnimatedView(0),
319 mParent(0), mTop(0), mObj(inObj
), mBounds(inBounds
),
320 mBackground(0), mBackgroundImage(0), mVisible(true), mEnabled(true),
321 mCanFocus(true), mDragHilite(false),
322 mConstructionMode(-1), mDragLabel(0)
324 mFocusColor
= SCMakeColor(0.0,0.0,0.0, 0.5);
328 if(!(inParent
->isSubViewScroller())){
329 SCRect pbounds
= inParent
->getLayout().bounds
;
330 mLayout.bounds.x
= mBounds.x
+ pbounds.x
;
331 mLayout.bounds.y
= mBounds.y
+ pbounds.y
;
332 mLayout.bounds.width
= mBounds.width
;
333 mLayout.bounds.height
= mBounds.height
;
335 mLayout.bounds
= mBounds
;
339 // store myself into sc object.
340 if (mObj
) SetPtr(mObj
->slots
+0, this);
347 mTop
->forgetView(this);
348 if (mParent
) mParent
->remove(this);
349 if (mObj
) SetNil(mObj
->slots
+0);
352 delete mBackgroundImage
;
358 void SCView
::startAnimation()
360 mNextAnimatedView
= gAnimatedViews
;
361 if (mNextAnimatedView
) mNextAnimatedView
->mPrevAnimatedView
= this;
362 mPrevAnimatedView
= 0;
363 gAnimatedViews
= this;
366 void SCView
::stopAnimation()
368 SCView
*nextAnim
= mNextAnimatedView
;
369 SCView
*prevAnim
= mPrevAnimatedView
;
370 if (nextAnim
) nextAnim
->mPrevAnimatedView
= prevAnim
;
371 if (prevAnim
) prevAnim
->mNextAnimatedView
= nextAnim
;
372 else if (gAnimatedViews
== this) gAnimatedViews
= nextAnim
;
373 mPrevAnimatedView
= mNextAnimatedView
= 0;
377 bool SCView
::hit(SCPoint where
) const
379 SCRect bounds
= mLayout.bounds
;
380 return SCPointInRect(where
, bounds
);
383 void SCView
::keyDown(int character
, int modifiers
, unsigned short keycode
)
385 pthread_mutex_lock (&gLangMutex
);
386 PyrSymbol
*method
= getsym("keyDown");
388 VMGlobals
*g
= gMainVMGlobals
;
390 ++g
->sp
; SetObject(g
->sp
, mObj
);
391 ++g
->sp
; SetChar(g
->sp
, character
);
392 ++g
->sp
; SetInt(g
->sp
, modifiers
);
393 ++g
->sp
; SetInt(g
->sp
, character
);
394 ++g
->sp
; SetInt(g
->sp
, keycode
);
395 runInterpreter(g
, method
, 5);
396 g
->canCallOS
= false;
398 pthread_mutex_unlock (&gLangMutex
);
401 void SCView
::keyUp(int character
, int modifiers
, unsigned short keycode
)
403 pthread_mutex_lock (&gLangMutex
);
404 PyrSymbol
*method
= getsym("keyUp");
406 VMGlobals
*g
= gMainVMGlobals
;
408 ++g
->sp
; SetObject(g
->sp
, mObj
);
409 ++g
->sp
; SetChar(g
->sp
, character
);
410 ++g
->sp
; SetInt(g
->sp
, modifiers
);
411 ++g
->sp
; SetInt(g
->sp
, character
);
412 ++g
->sp
; SetInt(g
->sp
, keycode
);
413 runInterpreter(g
, method
, 5);
414 g
->canCallOS
= false;
416 pthread_mutex_unlock (&gLangMutex
);
419 void SCView
::keyModifiersChanged(int modifiers
)
421 pthread_mutex_lock (&gLangMutex
);
422 PyrSymbol
*method
= getsym("keyModifiersChanged");
424 VMGlobals
*g
= gMainVMGlobals
;
426 ++g
->sp
; SetObject(g
->sp
, mObj
);
427 ++g
->sp
; SetInt(g
->sp
, modifiers
);
428 runInterpreter(g
, method
, 2);
429 g
->canCallOS
= false;
431 pthread_mutex_unlock (&gLangMutex
);
435 void SCView
::mouseDownAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
437 pthread_mutex_lock (&gLangMutex
);
438 PyrSymbol
*method
= getsym("mouseDown");
439 int clickCount
= [theEvent clickCount
];
440 int buttonNum
= [theEvent buttonNumber
];
442 VMGlobals
*g
= gMainVMGlobals
;
444 SCRect tbounds
= getDrawBounds();
445 where.x
= where.x
- tbounds.x
;
446 where.y
= where.y
- tbounds.y
;
447 ++g
->sp
; SetObject(g
->sp
, mObj
);
448 ++g
->sp
; SetFloat(g
->sp
, where.x
);
449 ++g
->sp
; SetFloat(g
->sp
, where.y
);
450 ++g
->sp
; SetInt(g
->sp
, modifiers
);
451 ++g
->sp
; SetInt(g
->sp
,buttonNum
);
452 ++g
->sp
; SetInt(g
->sp
,clickCount
);
453 runInterpreter(g
, method
, 6);
454 g
->canCallOS
= false;
456 pthread_mutex_unlock (&gLangMutex
);
458 void SCView
::mouseMoveAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
460 pthread_mutex_lock (&gLangMutex
);
461 PyrSymbol
*method
= getsym("mouseMove");
463 VMGlobals
*g
= gMainVMGlobals
;
465 SCRect tbounds
= getDrawBounds();
466 where.x
= where.x
- tbounds.x
;
467 where.y
= where.y
- tbounds.y
;
468 ++g
->sp
; SetObject(g
->sp
, mObj
);
469 ++g
->sp
; SetFloat(g
->sp
, where.x
);
470 ++g
->sp
; SetFloat(g
->sp
, where.y
);
471 ++g
->sp
; SetInt(g
->sp
, modifiers
);
472 runInterpreter(g
, method
, 4);
473 g
->canCallOS
= false;
475 pthread_mutex_unlock (&gLangMutex
);
477 void SCView
::mouseUpAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
479 pthread_mutex_lock (&gLangMutex
);
480 PyrSymbol
*method
= getsym("mouseUp");
482 VMGlobals
*g
= gMainVMGlobals
;
484 SCRect tbounds
= getDrawBounds();
485 where.x
= where.x
- tbounds.x
;
486 where.y
= where.y
- tbounds.y
;
487 ++g
->sp
; SetObject(g
->sp
, mObj
);
488 ++g
->sp
; SetFloat(g
->sp
, where.x
);
489 ++g
->sp
; SetFloat(g
->sp
, where.y
);
490 ++g
->sp
; SetInt(g
->sp
, modifiers
);
491 runInterpreter(g
, method
, 4);
492 g
->canCallOS
= false;
494 pthread_mutex_unlock (&gLangMutex
);
497 void SCView
::setConstructionModeFromPoint(SCPoint where
)
500 bounds
= SCMakeRect(mBounds.x
, mBounds.y
, mBounds.width
*0.6, mBounds.height
*0.6);
501 // post("point: x: %f, y: %f, bounds: x: %f, y: %f\n", where.x, where.y, mBounds.x, mBounds.y);
502 if( SCPointInRect(where
, bounds
)){
503 mConstructionMode
= view_PositionConstructionMode
;
504 // [[NSCursor openHandCursor] set];
507 // [[NSCursor crosshairCursor] set];
508 mConstructionMode
= view_ResizeConstructionMode
;
512 void SCView
::doConstructionMove(SCPoint where
)
515 if( mConstructionMode
== view_ResizeConstructionMode
){
516 mBounds.width
= mBounds.width
+ (where.x
- (mBounds.width
+ mBounds.x
));
517 mBounds.height
= mBounds.height
+ (where.y
- (mBounds.height
+ mBounds.y
));
518 }else if (mConstructionMode
== view_PositionConstructionMode
) {
526 NSMenu
* SCView
::contextMenu(SCPoint inPoint
)
531 void SCView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
533 mouseTrack(where
, modifiers
,theEvent
);
536 void SCView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
540 void SCView
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
542 mouseTrack(where
, modifiers
,theEvent
);
545 void SCView
::mouseOver(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
547 pthread_mutex_lock (&gLangMutex
);
548 PyrSymbol
*method
= getsym("mouseOver");
550 VMGlobals
*g
= gMainVMGlobals
;
552 SCRect tbounds
= getDrawBounds();
553 where.x
= where.x
- tbounds.x
;
554 where.y
= where.y
- tbounds.y
;
555 ++g
->sp
; SetObject(g
->sp
, mObj
);
556 ++g
->sp
; SetInt(g
->sp
, (int) where.x
);
557 ++g
->sp
; SetInt(g
->sp
, (int) where.y
);
558 ++g
->sp
; SetInt(g
->sp
, modifiers
);
559 runInterpreter(g
, method
, 4);
560 g
->canCallOS
= false;
562 pthread_mutex_unlock (&gLangMutex
);
565 bool SCView
::canReceiveDrag()
570 void SCView
::receiveDrag()
574 void SCView
::draggingEntered (SCPoint where
)
576 mouseOver(where
, 0, NULL
);
578 void SCView
::draggingUpdated (SCPoint where
)
580 mouseOver(where
, 0, NULL
);
584 void SCView
::setDragHilite(bool inFlag
)
586 bool prevFlag
= mDragHilite
;
587 mDragHilite
= inFlag
;
588 if (mDragHilite
!= prevFlag
) refresh();
591 void hPaintGradient(CGContextRef cgc
, CGRect bounds
, SCColor startColor
, SCColor endColor
, int numSteps
);
593 void SCView
::draw(SCRect inDamage
)
597 if ( mBackground || mBackgroundImage
) {
599 bounds
= getDrawBounds();
600 // NSLog(@"back bounds: %f, %f, %f, %f", bounds.x, bounds.y, bounds.width, bounds.height);
601 cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
602 rect
= SCtoCGRect(bounds
);
606 mBackground
->draw(cgc
, rect
);
608 if (mBackgroundImage
)
609 mBackgroundImage
->draw(cgc
, rect
);
612 void SCView
::drawDisabled(SCRect inDamage
)
614 if (!mEnabled
&& shouldDim()) {
615 SCRect bounds
= getDrawBounds();
616 CGRect rect
= SCtoCGRect(bounds
);
617 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
618 CGContextSaveGState(cgc
);
619 CGContextSetRGBFillColor(cgc
, 1.
, 1.
, 1.
, 0.5);
620 CGContextFillRect(cgc
, rect
);
621 CGContextRestoreGState(cgc
);
625 void SCView
::drawFocus(SCRect inDamage
)
628 SCRect bounds
= getDrawBounds();
629 CGRect rect
= SCtoCGRect(bounds
);
632 rect.size.width
+= 4;
633 rect.size.height
+= 4;
634 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
635 CGContextSaveGState(cgc
);
636 CGContextSetLineWidth(cgc
, 2);
637 // CGContextSetRGBStrokeColor(cgc, 0., 0., 0., 0.5);
638 CGContextSetRGBStrokeColor(cgc
, mFocusColor.red
, mFocusColor.green
, mFocusColor.blue
, mFocusColor.alpha
);
640 CGContextStrokeRect(cgc
, rect
);
641 CGContextRestoreGState(cgc
);
646 void SCView
::drawDragHilite(SCRect inDamage
)
649 SCRect bounds
= getDrawBounds();
651 CGRect rect
= SCtoCGRect(bounds
);
654 rect.size.width
-= 4;
655 rect.size.height
-= 4;
656 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
657 CGContextSaveGState(cgc
);
658 CGContextSetLineWidth(cgc
, 4);
659 CGContextSetRGBStrokeColor(cgc
, 0.
, 0.
, 1.
, 0.4);
660 CGContextStrokeRect(cgc
, rect
);
661 CGContextRestoreGState(cgc
);
665 void SCView
::drawIfNecessary(SCRect inDamage
)
667 SCRect bounds
= getDrawBounds();
669 bounds.x
-= 4; bounds.y
-= 4;
670 bounds.width
+= 8; bounds.height
+= 8;
672 if (SCRectsDoIntersect(inDamage
, bounds
) && mVisible
) {
674 drawDisabled(inDamage
);
675 drawDragHilite(inDamage
);
680 SCView
* SCView
::findView(SCPoint where
)
682 if (hit(where
) && mEnabled
&& mVisible
) return this;
686 SCView
* SCView
::findViewByID(int32 inID
)
688 if (inID
== mID
) return this;
692 bool SCView
::shouldDim()
697 bool SCView
::canFocus()
699 bool flag
= mEnabled
&& mVisible
&& mCanFocus
;
700 if (mParent
) flag
= flag
&& mParent
->canFocus();
704 bool SCContainerView
::canFocus()
706 bool flag
= mEnabled
&& mVisible
;
707 if (mParent
) flag
= flag
&& mParent
->canFocus();
711 SCRect
NStoSCRect(NSRect nsrect
)
714 screct.x
= nsrect.origin.x
;
715 screct.y
= nsrect.origin.y
;
716 screct.width
= nsrect.size.width
;
717 screct.height
= nsrect.size.height
;
720 NSRect
SCtoNSRect(SCRect screct
);
722 void SCView
::setBounds(SCRect inBounds
)
725 if(!(mParent
->isSubViewScroller())){
726 SCRect pbounds
= mParent
->getLayout().bounds
;
727 mLayout.bounds.x
= mBounds.x
+ pbounds.x
;
728 mLayout.bounds.y
= mBounds.y
+ pbounds.y
;
729 mLayout.bounds.width
= mBounds.width
;
730 mLayout.bounds.height
= mBounds.height
;
732 mLayout.bounds
= mBounds
;
737 SCRect SCView
::getBounds()
743 SCRect SCView
::getDrawBounds() //relative to ContainerView
745 return mLayout.bounds
;
748 Layout SCView
::getLayout()
753 void SCView
::makeFocus(bool focus
)
756 if (canFocus() && !isFocus()) {
757 SCView
*prevFocus
= mTop
->focusView();
758 if (prevFocus
) prevFocus
->makeFocus(false);
761 NSView
* newFirstResponder
= focusResponder();
762 [[newFirstResponder window
] makeFirstResponder
:newFirstResponder
];
772 NSView
* SCView
::focusResponder() { return mTop
->GetNSView(); }
774 void SCContainerView
::makeFocus(bool focus
)
778 SCView
* SCView
::nextFocus(bool *foundFocus
, bool canFocus
)
784 canFocus
= canFocus
&& mEnabled
&& mVisible
&& mCanFocus
;
785 if (canFocus
&& *foundFocus
) return this;
789 SCView
* SCView
::prevFocus(SCView
**prevView
, bool canFocus
)
791 if (isFocus() && *prevView
) return *prevView
;
792 canFocus
= canFocus
&& mEnabled
&& mVisible
&& mCanFocus
;
793 if (canFocus
) *prevView
= this;
798 void SCView
::refresh()
800 mTop
->addDamage(mLayout.bounds
);
803 void SCView
::refreshInRect(SCRect b
)
805 if(SCRectsDoIntersect(b
, mLayout.bounds
)) {
808 sect.x
= sc_max(b.x
, mLayout.bounds.x
);
809 sect.y
= sc_max(b.y
, mLayout.bounds.y
);
810 sect.width
= sc_min(b.x
+ b.width
, mLayout.bounds.x
+ mLayout.bounds.width
);
811 sect.height
= sc_min(b.y
+ b.height
, mLayout.bounds.y
+ mLayout.bounds.height
);
812 sect.width
-= sect.x
; sect.height
-= sect.y
;
813 mTop
->addDamage(sect
);
817 // cannot call from primitives. i.e. new view, or get/set property
818 void SCView
::sendMessage(PyrSymbol
*method
, int numargs
, PyrSlot
*args
, PyrSlot
*result
)
820 //CGContextRef cgc = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
821 //CGContextSaveGState(cgc);
822 pthread_mutex_lock (&gLangMutex
);
824 VMGlobals
*g
= gMainVMGlobals
;
826 ++g
->sp
; SetObject(g
->sp
, mObj
);
827 for (int i
=0; i
<numargs
; ++i
) {
829 slotCopy(g
->sp
, &args
[i
]);
831 runInterpreter(g
, method
, numargs
+1);
832 g
->canCallOS
= false;
833 if (result
) slotCopy(result
, &g
->result
);
835 pthread_mutex_unlock (&gLangMutex
);
837 //CGContextRestoreGState(cgc);
840 bool SCView
::isDragSource() const
845 int SCView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
848 char *name
= symbol
->name
;
849 if (strcmp(name
, "bounds")==0) {
851 err
= slotGetSCRect(slot
, &screct
);
856 if(mTop
->isScroller()) {
857 ((SCScrollTopView
*)mTop
)->setInSetClipViewOrigin(true);
859 [(SCGraphView
*)mTop
->GetNSView() setFrameSizeToMinimum
];
860 ((SCScrollTopView
*)mTop
)->setInSetClipViewOrigin(false);
861 } else {setBounds(screct
);}
865 if (strcmp(name
, "visible")==0) {
866 bool visible
= IsTrue(slot
);
867 if (mVisible
!= visible
) {
869 if (!mVisible
) mTop
->resetFocus(); //
874 if (strcmp(name
, "enabled")==0) {
875 bool enabled
= IsTrue(slot
);
876 if (mEnabled
!= enabled
) {
878 if (!mEnabled
) mTop
->resetFocus();
883 if (strcmp(name
, "canFocus")==0) {
884 bool canFocus
= IsTrue(slot
);
885 if (mCanFocus
!= canFocus
) {
886 mCanFocus
= canFocus
;
887 if (!mCanFocus
) mTop
->resetFocus();
892 if (strcmp(name
, "resize")==0) {
897 err
= slotIntVal(slot
, &resize
);
899 if (resize
< 1 || resize
> 9) return errIndexOutOfRange
;
900 mLayout.mHResize
= ((resize
- 1) % 3) - 1;
901 mLayout.mVResize
= ((resize
- 1) / 3) - 1;
905 if(strcmp(name
,"id") ==0) {
906 return slotIntVal(slot
, &mID
);
908 if(strcmp(name
,"minWidth") ==0) {
909 err
= slotFloatVal(slot
, &mLayout.mMinWidth
);
913 if(strcmp(name
,"maxWidth") ==0) {
914 err
= slotFloatVal(slot
, &mLayout.mMaxWidth
);
918 if(strcmp(name
,"minHeight") ==0) {
919 err
= slotFloatVal(slot
, &mLayout.mMinHeight
);
923 if(strcmp(name
,"maxHeight") ==0) {
924 err
= slotFloatVal(slot
, &mLayout.mMaxHeight
);
928 if (strcmp(name
, "background")==0) {
929 err
= slotBackgroundVal(slot
, &mBackground
);
934 if (strcmp(name
, "backgroundImage")==0) {
935 err
= slotBackgroundImageVal(slot
, &mBackgroundImage
);
940 if (strcmp(name
, "focusColor")==0) {
941 err
= slotColorVal(slot
, &mFocusColor
);
946 if (strcmp(name
, "dragLabel")==0) {
947 if(isKindOfSlot(slot
, class_string
)) {
948 PyrString
* pstring
= slotRawString(slot
);
949 if(!pstring
) return errNone
;
950 if(mDragLabel
) [mDragLabel release
];
951 mDragLabel
= [[NSString alloc
] initWithCString
: pstring
->s length
: pstring
->size
];
953 } else if (IsNil(slot
)) {
954 if(mDragLabel
) [mDragLabel release
];
957 } else return errWrongType
;
959 return errPropertyNotFound
;
962 int SCView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
964 char *name
= symbol
->name
;
965 if (strcmp(name
, "bounds")==0) {
966 if (!(isKindOfSlot(slot
, s_rect
->u.classobj
))) {
969 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
970 SetFloat(slots
+0, mBounds.x
);
971 SetFloat(slots
+1, mBounds.y
);
972 SetFloat(slots
+2, mBounds.width
);
973 SetFloat(slots
+3, mBounds.height
);
976 if (strcmp(name
, "absoluteBounds")==0) {
978 if (!(isKindOfSlot(slot
, s_rect
->u.classobj
))) {
981 drawBounds
= mLayout.bounds
;
982 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
983 SetFloat(slots
+0, drawBounds.x
);
984 SetFloat(slots
+1, drawBounds.y
);
985 SetFloat(slots
+2, drawBounds.width
);
986 SetFloat(slots
+3, drawBounds.height
);
989 if (strcmp(name
, "visible")==0) {
990 SetBool(slot
, mVisible
);
993 if (strcmp(name
, "enabled")==0) {
994 SetBool(slot
, mEnabled
);
997 if (strcmp(name
, "resize")==0) {
998 int resize
= mLayout.mVResize
* 3 + mLayout.mHResize
+ 5;
999 SetInt(slot
, resize
);
1002 if (strcmp(name
, "id")==0) {
1006 /*if (strcmp(name, "background")==0) {
1007 int err = getBackgroundVal(slot, mBackground);
1010 /*if (strcmp(name, "backColor")==0) {
1011 return setSlotColor(slot, &mBackColor);
1014 if (strcmp(name
, "focusColor")==0) {
1015 return setSlotColor(slot
, &mFocusColor
);;
1017 return errPropertyNotFound
;
1020 void SCView
::beginDrag(SCPoint where
)
1022 sendMessage(s_beginDrag
, 0, 0, 0);
1026 NSString
*string
= 0;
1027 NSString
*label
= 0;
1028 pthread_mutex_lock (&gLangMutex
);
1030 VMGlobals
*g
= gMainVMGlobals
;
1031 int classVarIndex
= slotRawInt(&getsym("SCView")->u.classobj
->classVarIndex
);
1032 slotCopy(&slot
, &g
->classvars
->slots
[classVarIndex
]);
1033 slotCopy(&stringSlot
, &g
->classvars
->slots
[classVarIndex
+1]);
1034 if (isKindOfSlot(&stringSlot
, class_string
)) {
1035 string
= [NSString stringWithCString
: slotRawString(&stringSlot
)->s length
: slotRawString(&stringSlot
)->size
];
1037 if(mDragLabel
) label
= mDragLabel
;
1039 pthread_mutex_unlock (&gLangMutex
);
1041 mTop
->beginDragCallback(where
, &slot
, string
, label
);
1044 ////////////////////////////////////////////////////////////////////////////////////////////////
1046 SCContainerView
::SCContainerView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1047 : SCView(inParent
, inObj
, inBounds
), mChildren(0), mNumChildren(0)
1049 mLayout.bounds
= mBounds
;
1051 SCRect pBounds
= mParent
->getDrawBounds(); // or jsut absolute frame bounds ?
1052 mLayout.bounds.x
= inBounds.x
+ pBounds.x
;
1053 mLayout.bounds.y
= inBounds.y
+ pBounds.y
;
1057 SCContainerView
::~
SCContainerView()
1059 SCView
*child
= mChildren
;
1061 SCView
*next
= child
->mNext
;
1069 int SCContainerView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
1072 char *name
= symbol
->name
;
1074 if (strcmp(name
, "visible")==0) {
1075 bool visible
= IsTrue(slot
);
1076 if (mVisible
!= visible
) {
1078 // SCView *child = mChildren;
1080 // SCView *next = child->mNext;
1081 // child->setVisibleFromParent(visible && mParent->isVisible()); // needed for Cocoa views
1084 setVisibleFromParent();
1085 if (!mVisible
) mTop
->resetFocus(); //
1091 return SCView
::setProperty(symbol
, slot
);
1094 void SCContainerView
::setVisibleFromParent()
1096 SCView
*child
= mChildren
;
1098 SCView
*next
= child
->mNext
;
1099 child
->setVisibleFromParent(); // needed for Cocoa views
1104 void SCContainerView
::add(SCView
*inChild
)
1106 inChild
->mNext
= mChildren
;
1107 mChildren
= inChild
;
1109 inChild
->mParent
= this;
1110 inChild
->mTop
= mTop
;
1114 void SCContainerView
::remove(SCView
*inChild
)
1116 SCView
*child
= mChildren
;
1118 inChild
->makeFocus(false);
1120 SCView
*next
= child
->mNext
;
1121 if (child
== inChild
) {
1122 if (prev
) prev
->mNext
= child
->mNext
;
1123 else mChildren
= child
->mNext
;
1134 void SCContainerView
::drawIfNecessary(SCRect inDamage
)
1137 drawBounds
= getDrawBounds();
1138 if (SCRectsDoIntersect(inDamage
, drawBounds
) && mVisible
) {
1140 SCView
*child
= mChildren
;
1141 SCView
*children
[mNumChildren
];
1142 int k
= mNumChildren
;
1144 // child->drawIfNecessary(inDamage);
1145 children
[--k
] = child
;
1146 child
= child
->next();
1148 for(int i
=0; i
< mNumChildren
; i
++ ) {
1149 child
= children
[i
];
1150 child
->drawIfNecessary(inDamage
);
1152 drawDisabled(inDamage
);
1153 drawDragHilite(inDamage
);
1154 drawFocus(inDamage
);
1158 SCView
* SCContainerView
::findView(SCPoint where
)
1160 if (mEnabled
&& mVisible
) {
1161 SCView
*child
= mChildren
;
1163 if(!(child
->isScroller())) {
1164 SCView
*found
= child
->findView(where
);
1165 if (found
) return found
;
1167 child
= child
->mNext
;
1173 SCView
* SCContainerView
::findViewByID(int32 inID
)
1175 if (inID
== mID
) return this;
1176 SCView
*child
= mChildren
;
1178 SCView
*found
= child
->findViewByID(inID
);
1179 if (found
) return found
;
1180 child
= child
->mNext
;
1185 SCView
* SCContainerView
::nextFocus(bool *foundFocus
, bool canFocus
)
1187 canFocus
= canFocus
&& mEnabled
&& mVisible
;
1188 SCView
*child
= mChildren
;
1190 SCView
*view
= child
->nextFocus(foundFocus
, canFocus
);
1191 if (view
) return view
;
1192 child
= child
->mNext
;
1197 SCView
* SCContainerView
::prevFocus(SCView
**prevView
, bool canFocus
)
1199 canFocus
= canFocus
&& mEnabled
&& mVisible
;
1200 SCView
*child
= mChildren
;
1202 SCView
*view
= child
->prevFocus(prevView
, canFocus
);
1203 if (view
) return view
;
1204 child
= child
->mNext
;
1209 SCRect SCContainerView
::checkMinimumSize() {
1210 SCView
*child
= mChildren
;
1211 SCRect candidate
= mBounds
;
1212 // iterate through all the views and see if we need to be bigger (children may exceed the parent's bounds)
1214 SCRect bounds
= child
->checkMinimumSize();
1215 candidate
= SCRectUnion(bounds
, candidate
);
1216 child
= child
->next();
1222 SCView
* NewSCCompositeView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1224 return new SCCompositeView(inParent
, inObj
, inBounds
);
1227 SCCompositeView
::SCCompositeView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1228 : SCContainerView(inParent
, inObj
, inBounds
)
1232 SCCompositeView
::~
SCCompositeView()
1236 void SCCompositeView
::setBounds(SCRect inBounds
)
1238 SCView
*child
= mChildren
;
1239 SCView
*myTop
= mTop
;
1240 SCRect topBounds
= myTop
->getBounds();
1241 SCRect topPBounds
= myTop
->getLayout().bounds
;
1243 // float right = mBounds.x + mBounds.width;
1244 // float bottom = mBounds.y + mBounds.height;
1245 mLayout.bounds
= inBounds
;
1246 // if(isTopContainer()){
1247 // post("i'm my own parent ... \t");
1248 // post("in x:%f, y:%f\n", inBounds.x, inBounds.y);
1252 if(!(mParent
->isSubViewScroller())){
1253 SCRect pBounds
= mParent
->getDrawBounds();
1254 mLayout.bounds.x
= inBounds.x
+ pBounds.x
;
1255 mLayout.bounds.y
= inBounds.y
+ pBounds.y
;
1257 mLayout.bounds.x
= inBounds.x
;
1258 mLayout.bounds.y
= inBounds.y
;
1263 SCRect bounds
= child
->getBounds();
1264 Layout layout
= child
->getLayout();
1265 // SCRect bounds = layout.bounds;
1268 switch (layout.mHResize
) {
1269 case layout_FixedLeft
:
1272 case layout_FixedRight
:
1273 // if the parent is a top container, then relative or absolute are irrelevant.
1274 if(child
->parent()->isTopContainer() ||
(inBounds.width
!= child
->parent()->getBounds().width
)){
1275 offset
= (mBounds.x
+ mBounds.width
) - (bounds.x
+ bounds.width
);
1276 bounds.x
= (inBounds.x
+ inBounds.width
) - (bounds.width
+ offset
);
1281 case layout_HElastic
:
1282 offset
= (mBounds.x
+ mBounds.width
) - (bounds.x
+ bounds.width
);
1283 /* bounds.width = sc_clip(
1284 (inBounds.width) - (bounds.x + offset),
1286 sc_min(layout.mMaxWidth,right - bounds.x)
1288 bounds.width
= (inBounds.width
) - ((bounds.x
- mBounds.x
) + offset
);
1291 switch (layout.mVResize
) {
1292 case layout_FixedTop
:
1295 case layout_FixedBottom
:
1297 // if the parent is a top container, then relative or absolute are irrelevant.
1298 if(child
->parent()->isTopContainer() ||
(inBounds.height
!= child
->parent()->getBounds().height
)){
1299 offset
= (mBounds.y
+ mBounds.height
) - (bounds.y
+ bounds.height
);
1300 bounds.y
= (inBounds.y
+ inBounds.height
) - (bounds.height
+ offset
);
1305 case layout_VElastic
:
1307 offset
= (mBounds.y
+ mBounds.height
) - (bounds.y
+ bounds.height
);
1308 /*bounds.height = sc_clip(
1309 (inBounds.height) - (bounds.y + offset),
1311 sc_min(layout.mMaxHeight,bottom - bounds.y)
1313 bounds.height
= (inBounds.height
) - ((bounds.y
- mBounds.y
) + offset
);
1317 child
->setBounds(bounds
);
1318 child
= child
->next();
1320 // should be limited by the limitations of the contents
1324 /////////////////////////////////////////////////////////////////////////////////////
1327 SCView
* NewSCLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1329 return new SCLayoutView(inParent
, inObj
, inBounds
);
1332 SCLayoutView
::SCLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1333 : SCContainerView(inParent
, inObj
, inBounds
), mSpacing(4.
)
1337 SCLayoutView
::~
SCLayoutView()
1342 int SCLayoutView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
1345 char *name
= symbol
->name
;
1346 if (strcmp(name
, "spacing")==0) {
1347 err
= slotFloatVal(slot
, &mSpacing
);
1348 if (err
) return err
;
1352 if (strcmp(name
, "bounds")==0) {
1354 err
= slotGetSCRect(slot
, &screct
);
1355 if (err
) return err
;
1361 return SCView
::setProperty(symbol
, slot
);
1364 int SCLayoutView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
1366 char *name
= symbol
->name
;
1367 if (strcmp(name
, "spacing")==0) {
1368 SetFloat(slot
, mSpacing
);
1372 return SCView
::getProperty(symbol
, slot
);
1375 void SCLayoutView
::add(SCView
*inChild
)
1377 SCContainerView
::add(inChild
);
1378 setBounds(mBounds
); // re-layout
1381 /////////////////////////////////////////////////////////////////////////////////////
1383 SCView
* NewSCHLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1385 return new SCHLayoutView(inParent
, inObj
, inBounds
);
1388 SCHLayoutView
::SCHLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1389 : SCLayoutView(inParent
, inObj
, inBounds
)
1393 SCHLayoutView
::~
SCHLayoutView()
1397 void SCHLayoutView
::setBounds(SCRect inBounds
)
1399 SCView
*child
= mChildren
;
1400 float totalWeight
= 0.0;
1401 //if reativeOrigin is true, the inBounds need to be moved to absolute bounds
1403 if(!(mParent
->isSubViewScroller())){
1404 SCRect pbounds
= mParent
->getLayout().bounds
;
1405 mLayout.bounds.x
= mBounds.x
+ pbounds.x
;
1406 mLayout.bounds.y
= mBounds.y
+ pbounds.y
;
1407 mLayout.bounds.width
= mBounds.width
;
1408 mLayout.bounds.height
= mBounds.height
;
1410 mLayout.bounds
= mBounds
;
1412 SCRect absBounds
= mLayout.bounds
;
1414 Layout layout
= child
->getLayout();
1415 // could store this when child added
1416 totalWeight
+= layout.mWeight
;
1417 child
= child
->next();
1419 // subtract the spacers we will use
1420 float totalWidth
= absBounds.width
- (mSpacing
* (mNumChildren
- 1));
1422 // find views who are constrained by a minimum or maximum size
1423 // and remove them from the set of weights.
1424 float scaleWeight
= sc_max(totalWidth
,0.0) * (1.0 / sc_max(totalWeight
,0.01));
1426 float widths
[mNumChildren
];
1427 SCView
*children
[mNumChildren
];
1428 int ri
= mNumChildren
;
1432 children
[--ri
] = child
;
1433 Layout layout
= child
->getLayout();
1434 float weightedWidth
= scaleWeight
* layout.mWeight
;
1435 if(layout.mHResize
== 0) {// okay to resize
1436 if (weightedWidth
< layout.mMinWidth
) {
1437 width
= layout.mMinWidth
;
1439 totalWidth
-= width
;
1440 totalWeight
-= layout.mWeight
;
1442 if (weightedWidth
> layout.mMaxWidth
) {
1443 width
= layout.mMaxWidth
;
1445 totalWidth
-= width
;
1446 totalWeight
-= layout.mWeight
;
1452 SCRect rect
= child
->getBounds();
1453 widths
[ri
] = rect.width
;
1455 child
= child
->next();
1457 //totalWidth is now the remaining flexible width
1459 // now layout the views
1460 float left
= 0.f
; // subviews will automatically offset from window origin
1462 float height
= absBounds.height
;
1463 // NSLog(@"view bounds: %f, %f, %f, %f", absBounds.x, absBounds.y, absBounds.width, absBounds.height);
1464 scaleWeight
= totalWidth
* (1.0/totalWeight
);
1467 for(; i
< mNumChildren
; i
++ ) {
1468 child
= children
[i
];
1469 Layout layout
= child
->getLayout();
1471 if(widths
[i
] == -1.0) {
1472 width
= scaleWeight
* layout.mWeight
;
1473 } else { // was constrained
1476 child
->setBounds(SCMakeRect( left
, top
, width
, height
));
1477 left
+= (width
+ mSpacing
);
1478 child
= child
->next();
1483 /////////////////////////////////////////////////////////////////////////////////////
1485 SCView
* NewSCVLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1487 return new SCVLayoutView(inParent
, inObj
, inBounds
);
1490 SCVLayoutView
::SCVLayoutView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1491 : SCLayoutView(inParent
, inObj
, inBounds
)
1495 SCVLayoutView
::~
SCVLayoutView()
1499 void SCVLayoutView
::setBounds(SCRect inBounds
)
1501 SCView
*child
= mChildren
;
1502 float totalWeight
= 0.0;
1504 Layout layout
= child
->getLayout();
1505 // could store this when child added
1506 totalWeight
+= layout.mWeight
;
1507 child
= child
->next();
1509 //if reativeOrigin is true, the inBounds need to be moved to absolute bounds
1511 if(!(mParent
->isSubViewScroller())){
1512 SCRect pbounds
= mParent
->getLayout().bounds
;
1513 mLayout.bounds.x
= mBounds.x
+ pbounds.x
;
1514 mLayout.bounds.y
= mBounds.y
+ pbounds.y
;
1515 mLayout.bounds.width
= mBounds.width
;
1516 mLayout.bounds.height
= mBounds.height
;
1518 mLayout.bounds
= mBounds
;
1520 SCRect absBounds
= mLayout.bounds
;
1521 // subtract the spacers we will use
1522 float totalHeight
= absBounds.height
- (mSpacing
* (mNumChildren
- 1));
1524 // find views who are constrained by a minimum or maximum size
1525 // and remove them from the set of weights.
1526 float scaleWeight
= sc_max(totalHeight
,0.0) * (1.0 / sc_max(totalWeight
,0.01));
1528 float heights
[mNumChildren
];
1529 SCView
*children
[mNumChildren
];
1530 int ri
= mNumChildren
;
1534 children
[--ri
] = child
;
1535 Layout layout
= child
->getLayout();
1536 float weightedHeight
= scaleWeight
* layout.mWeight
;
1537 if(layout.mVResize
== 0) {// okay to resize
1538 if (weightedHeight
< layout.mMinHeight
) {
1539 height
= layout.mMinHeight
;
1540 heights
[ri
] = height
;
1541 totalHeight
-= height
;
1542 totalWeight
-= layout.mWeight
;
1544 if (weightedHeight
> layout.mMaxHeight
) {
1545 height
= layout.mMaxHeight
;
1546 heights
[ri
] = height
;
1547 totalHeight
-= height
;
1548 totalWeight
-= layout.mWeight
;
1554 SCRect rect
= child
->getBounds();
1555 heights
[ri
] = rect.height
;
1557 child
= child
->next();
1559 //totalHeight is now the remaining flexible height
1561 // now layout the views
1562 float left
= 0.f
; // subviews will automatically offset from window origin
1564 float width
= absBounds.width
;
1565 scaleWeight
= totalHeight
* (1.0/totalWeight
);
1568 for(; i
< mNumChildren
; i
++ ) {
1569 child
= children
[i
];
1570 Layout layout
= child
->getLayout();
1572 if(heights
[i
] == -1.0) {
1573 height
= scaleWeight
* layout.mWeight
;
1574 } else { // was constrained
1575 height
= heights
[i
];
1577 child
->setBounds(SCMakeRect( left
, top
, width
, height
));
1578 top
+= (height
+ mSpacing
);
1579 child
= child
->next();
1585 /////////////////////////////////////////////////////////////////////////////////////
1588 SCView
* NewSCTopView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1590 return new SCTopView(inObj
, inBounds
);
1593 SCTopView
::SCTopView(PyrObject
* inObj
, SCRect inBounds
)
1594 : SCCompositeView(0, inObj
, inBounds
), mFocusView(0), mDragView(0), mConstructionMode(false)
1597 //float ltgry = 0.8;
1598 //float dkgry = 0.5;
1599 //mBackground = new SolidColorBackground(
1600 // SCMakeColor(ltgry, ltgry, ltgry, 1.0));
1603 void SCTopView
::addDamage(SCRect inRect
)
1605 (*mDamageCallback
)(inRect
, mHostData
);
1606 //mDamage = SCRectUnion(mDamage, inRect);
1609 void SCTopView
::beginDragCallback(SCPoint where
, PyrSlot
* slot
, NSString
* string
, NSString
* label
)
1611 (*mDragCallback
)(where
, slot
, string
, label
, mHostData
);
1614 void SCView
::refreshFocus()
1616 SCRect focusBounds
= getDrawBounds();
1619 focusBounds.width
+= 8;
1620 focusBounds.height
+= 8;
1621 mTop
->addDamage(focusBounds
);
1624 void SCTopView
::resetFocus()
1626 SCView
*view
= focusView();
1627 if (view
&& !view
->canFocus()) {
1629 view
->refreshFocus();
1633 void SCTopView
::forgetView(SCView
*view
)
1635 if (view
== mFocusView
) mFocusView
= 0;
1636 if (view
== mDragView
) mDragView
= 0;
1639 void SCTopView
::tabNextFocus()
1641 bool foundFocus
= mFocusView ?
false : true;
1642 SCView
*view
= nextFocus(&foundFocus
, true);
1643 if (!view
&& foundFocus
) view
= nextFocus(&foundFocus
, true);
1644 if (view
) view
->makeFocus(true);
1647 void SCTopView
::tabPrevFocus()
1649 SCView
*prevView
= 0;
1650 SCView
*view
= prevFocus(&prevView
, true);
1651 if (!view
&& prevView
) view
= prevView
;
1652 if (view
) view
->makeFocus(true);
1655 void SCTopView
::setDragView(SCView
*inView
)
1657 if (inView
!= mDragView
) {
1658 if (mDragView
) mDragView
->setDragHilite(false);
1660 if (mDragView
) mDragView
->setDragHilite(true);
1664 void SCTopView
::drawFocus(SCRect inDamage
)
1666 if (ConstructionMode()) {
1667 CGRect rect
= SCtoCGRect(mBounds
);
1670 rect.size.width
-= 4;
1671 rect.size.height
-= 4;
1672 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
1673 CGContextSaveGState(cgc
);
1674 CGContextSetLineWidth(cgc
, 4);
1675 CGContextSetRGBStrokeColor(cgc
, 1.
, 1.
, 0.
, 1.
);
1676 CGContextStrokeRect(cgc
, rect
);
1677 CGContextRestoreGState(cgc
);
1681 bool SCTopView
::canReceiveDrag()
1684 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
1685 return IsTrue(&result
);
1688 void SCTopView
::receiveDrag()
1690 sendMessage(s_receiveDrag
, 0, 0, 0);
1693 void SCTopView
::setInternalBounds(SCRect internalBounds
)
1695 setBounds(internalBounds
);
1698 /////////////////////////////////////////////////////////////////////////////////////
1701 SCView
* NewSCScrollTopView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1703 return new SCScrollTopView(inObj
, inBounds
);
1706 SCScrollTopView
::SCScrollTopView(PyrObject
* inObj
, SCRect inBounds
)
1707 : SCTopView(inObj
, inBounds
), mInSetClipViewOrigin(false)
1712 SCRect SCScrollTopView
::checkMinimumSize()
1714 // size of SCGraphView must be at least large enough to hold any contained view for correct scrolling
1715 // so test against the NSClipView
1716 SCView
*child
= mChildren
;
1718 SCRect candidate
= SCMakeRect(0.f
, 0.f
, 1.f
, 1.f
); // smallest measureable at rect at origin
1720 // iterate through all the views and see if we need to be bigger
1722 SCRect bounds
= child
->checkMinimumSize();
1723 candidate
= SCRectUnion(bounds
, candidate
);
1724 child
= child
->next();
1730 SCRect SCScrollTopView
::getDrawBounds() //relative to ContainerView
1732 return SCRectUnion(mBounds
, checkMinimumSize());
1735 void SCScrollTopView
::setInternalBounds(SCRect inBounds
)
1737 // elasticity doesn't work with a scrolltopview
1741 int slotGetPoint(PyrSlot
* a
, NSPoint
*p
);
1743 int SCScrollTopView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
1746 char *name
= symbol
->name
;
1747 if (strcmp(name
, "setHasHorizontalScroller")==0) {
1748 bool hasScroller
= IsTrue(slot
);
1749 setInSetClipViewOrigin(true);
1750 [mNSScrollView setHasHorizontalScroller
:hasScroller
];
1751 [(SCGraphView
*)mNSView setFrameSizeToMinimum
];
1752 setInSetClipViewOrigin(false);
1757 if (strcmp(name
, "setHasVerticalScroller")==0) {
1758 bool hasScroller
= IsTrue(slot
);
1759 setInSetClipViewOrigin(true);
1760 [mNSScrollView setHasVerticalScroller
:hasScroller
];
1761 [(SCGraphView
*)mNSView setFrameSizeToMinimum
];
1762 setInSetClipViewOrigin(false);
1767 if (strcmp(name
, "setAutohidesScrollers")==0) {
1768 bool autoHides
= IsTrue(slot
);
1769 setInSetClipViewOrigin(true);
1770 [mNSScrollView setAutohidesScrollers
:autoHides
];
1771 [(SCGraphView
*)mNSView setFrameSizeToMinimum
];
1772 [mNSScrollView setNeedsDisplay
: YES
];
1774 // trick scrollview into redrawing
1775 NSRect frame
= [mNSScrollView frame
];
1776 [mNSScrollView setFrame
: NSInsetRect(frame
,1,1)];
1777 [mNSScrollView setFrame
: frame
];
1778 setInSetClipViewOrigin(false);
1783 if (strcmp(name
, "clipViewOrigin")==0) {
1785 err
= slotGetPoint(slot
, &origin
);
1786 if (err
) return err
;
1787 setInSetClipViewOrigin(true);
1788 [[mNSScrollView documentView
] scrollPoint
:origin
];
1789 setInSetClipViewOrigin(false);
1794 if (strcmp(name
, "setAutoScrolls")==0) {
1795 bool autoScrolls
= IsTrue(slot
);
1796 [(SCGraphView
*)mNSView setAutoScrolls
:autoScrolls
];
1800 if (strcmp(name
, "visible")==0) {
1801 bool visible
= IsTrue(slot
);
1804 [mNSScrollView setHidden
:NO
];
1808 [mNSScrollView setHidden
:YES
];
1811 setVisibleFromParent(); //SCContainerView
1816 return SCCompositeView
::setProperty(symbol
, slot
);
1819 int SCScrollTopView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
1821 char *name
= symbol
->name
;
1822 if (strcmp(name
, "absoluteBounds")==0) {
1823 if (!(isKindOfSlot(slot
, s_rect
->u.classobj
))) {
1824 return errWrongType
;
1826 SCRect bounds
= NStoSCRect([mNSScrollView frame
]);
1827 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
1828 SetFloat(slots
+0, bounds.x
);
1829 SetFloat(slots
+1, bounds.y
);
1830 SetFloat(slots
+2, bounds.width
);
1831 SetFloat(slots
+3, bounds.height
);
1835 if (strcmp(name
, "clipViewOrigin")==0) {
1836 if (!(isKindOfSlot(slot
, s_point
->u.classobj
))) {
1837 return errWrongType
;
1839 NSPoint origin
= [mNSScrollView documentVisibleRect
].origin
;
1840 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
1841 SetFloat(slots
+0, origin.x
);
1842 SetFloat(slots
+1, origin.y
);
1846 if (strcmp(name
, "innerBounds")==0) {
1847 if (!(isKindOfSlot(slot
, s_rect
->u.classobj
))) {
1848 return errWrongType
;
1850 SCRect bounds
= NStoSCRect([mNSView frame
]);
1851 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
1852 SetFloat(slots
+0, bounds.x
);
1853 SetFloat(slots
+1, bounds.y
);
1854 SetFloat(slots
+2, bounds.width
);
1855 SetFloat(slots
+3, bounds.height
);
1859 return SCCompositeView
::getProperty(symbol
, slot
);
1862 void SCScrollTopView
::add(SCView
*inChild
)
1864 setInSetClipViewOrigin(true);
1865 SCContainerView
::add(inChild
);
1866 [(SCGraphView
*)GetNSView() setFrameSizeToMinimum
];
1867 setInSetClipViewOrigin(false);
1870 void SCScrollTopView
::remove(SCView
*inChild
)
1872 setInSetClipViewOrigin(true);
1873 SCContainerView
::remove(inChild
);
1874 [(SCGraphView
*)GetNSView() setFrameSizeToMinimum
];
1875 setInSetClipViewOrigin(false);
1878 /////////////////////////////////////////////////////////////////////////////////////
1881 SCView
* NewSCScrollView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1883 return new SCScrollView(inParent
, inObj
, inBounds
);
1886 SCScrollView
::SCScrollView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
1887 : SCScrollTopView(inObj
, inBounds
)
1890 NSRect bounds
= SCtoNSRect(inBounds
);
1893 inParent
->add(this);
1894 if(!(inParent
->isSubViewScroller())){
1895 SCRect pbounds
= inParent
->getLayout().bounds
;
1896 mLayout.bounds.x
= mBounds.x
+ pbounds.x
;
1897 mLayout.bounds.y
= mBounds.y
+ pbounds.y
;
1898 mLayout.bounds.width
= mBounds.width
;
1899 mLayout.bounds.height
= mBounds.height
;
1901 mLayout.bounds
= mBounds
;
1906 NSView
*topGraphview
= mTop
->GetNSView();
1907 SCGraphView
* view
= [[SCGraphView alloc
] initWithFrame
: NSMakeRect(0, 0, bounds.size.width
, bounds.size.height
)];
1908 [view setSCObject
: [(SCGraphView
*)topGraphview getSCObject
]];
1910 [view setSCTopView
: this];
1911 NSScrollView
*scrollView
= [[NSScrollView alloc
] initWithFrame
: SCtoNSRect(mLayout.bounds
)];
1912 [scrollView setHasVerticalScroller
:YES
];
1913 [scrollView setHasHorizontalScroller
:YES
];
1914 [scrollView setAutohidesScrollers
:YES
];
1915 [[scrollView horizontalScroller
] setControlSize
:NSSmallControlSize
];
1916 [[scrollView verticalScroller
] setControlSize
:NSSmallControlSize
];
1917 [[scrollView horizontalScroller
] setControlTint
:NSGraphiteControlTint
];
1918 [[scrollView verticalScroller
] setControlTint
:NSGraphiteControlTint
];
1920 [scrollView setBackgroundColor
:[NSColor clearColor
]];
1921 [scrollView setDrawsBackground
:NO
];
1922 // configure the scroller to have no visible border
1923 [scrollView setBorderType
:NSNoBorder
];
1924 [scrollView setAutoresizingMask
:NSViewNotSizable
];
1925 [scrollView setDocumentView
:view
];
1927 [scrollView setPostsFrameChangedNotifications
: YES
]; // we need this to resize the SCGraphView if the scroll view exceeds its bounds
1928 [[NSNotificationCenter defaultCenter
] addObserver
:view
1929 selector
:@selector(scrollViewResized
:)
1930 name
:@
"NSViewFrameDidChangeNotification"
1933 NSClipView
*contentView
= [scrollView contentView
];
1934 [contentView setPostsBoundsChangedNotifications
:YES
];
1935 [[NSNotificationCenter defaultCenter
] addObserver
:view
1936 selector
:@selector(userScrolled
:)
1937 name
:@
"NSViewBoundsDidChangeNotification"
1938 object
:contentView
];
1940 SetNSScrollView(scrollView
);
1941 [topGraphview addSubview
: scrollView
];
1942 [view setFrameSizeToMinimum
];
1943 setBounds(mLayout.bounds
);
1944 setVisibleFromParent();
1948 void SCScrollView
::add(SCView
*inChild
)
1950 inChild
->mNext
= mChildren
;
1951 mChildren
= inChild
;
1953 inChild
->mParent
= this;
1954 inChild
->mTop
= this;
1956 [(SCGraphView
*)GetNSView() setFrameSizeToMinimum
];
1959 void SCScrollView
::drawIfNecessary(SCRect inDamage
)
1961 // only draw when our own SCGraphView wants it
1962 // not for the top level SCGraphView
1963 // so this returns nothing
1966 void SCScrollView
::drawSubViewIfNecessary(SCRect inDamage
)
1968 SCRect maxContentBounds
;
1969 // its not my mBounds nor my drawBounds that we want to test against
1970 // but rather my contents' total bounds
1971 maxContentBounds
= checkMinimumSize();
1972 // there might be a short cut to this
1974 if (SCRectsDoIntersect(inDamage
, maxContentBounds
) && mVisible
) {
1976 SCView
*child
= mChildren
;
1977 SCView
*children
[mNumChildren
];
1978 int k
= mNumChildren
;
1980 children
[--k
] = child
;
1981 child
= child
->next();
1983 for(int i
=0; i
< mNumChildren
; i
++ ) {
1984 child
= children
[i
];
1985 child
->drawIfNecessary(inDamage
);
1988 drawDisabled(inDamage
);
1989 drawDragHilite(inDamage
);
1990 drawFocus(inDamage
);
1994 void SCScrollView
::setBounds(SCRect inBounds
)
1996 [mNSScrollView setFrame
: SCtoNSRect(inBounds
)];
1999 SCRect SCScrollView
::getBounds()
2001 return NStoSCRect([mNSScrollView frame
]);
2004 int SCScrollView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2007 char *name
= symbol
->name
;
2008 if (strcmp(name
, "bounds")==0) {
2010 err
= slotGetSCRect(slot
, &screct
);
2011 if (err
) return err
;
2013 SCRect pbounds
= mParent
->getLayout().bounds
; // relative origin fix
2014 screct.x
+= pbounds.x
;
2015 screct.y
+= pbounds.y
;
2022 if (strcmp(name
, "border")==0) {
2023 bool hasBorder
= IsTrue(slot
);
2025 [mNSScrollView setBorderType
:NSLineBorder
];
2027 [mNSScrollView setBorderType
:NSNoBorder
];
2029 [(SCGraphView
*)mNSView setFrameSizeToMinimum
];
2034 if (strcmp(name
, "visible")==0) {
2035 bool visible
= IsTrue(slot
);
2037 setVisibleFromParent();
2041 return SCScrollTopView
::setProperty(symbol
, slot
);
2044 void SCScrollView
::setVisibleFromParent()
2046 if(mVisible
&& mParent
->isVisible()) {
2047 [mNSScrollView setHidden
:NO
];
2049 [mNSScrollView setHidden
:YES
];
2051 SCContainerView
::setVisibleFromParent();
2055 SCScrollView
::~
SCScrollView()
2057 [mNSScrollView removeFromSuperview
];
2058 [mNSScrollView release
];
2061 ///////////////////////////////////////////////////////////////////////////////////////
2063 SCView
* NewSCSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2065 return new SCSlider(inParent
, inObj
, inBounds
);
2068 SCSlider
::SCSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2069 : SCView(inParent
, inObj
, inBounds
), mStepSize(0.
), mStepScale(0.
), mKnob(0), mThumbSize(12.
)
2072 setValue(0.0, false);
2075 //int drawBevelRect(Rect r, int width, int inout, RGBColor color, int drawop);
2077 void SCSlider
::draw(SCRect inDamage
)
2079 SCRect bounds
= getDrawBounds();
2080 calcThumbRect(bounds
);
2082 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
2083 CGContextSaveGState(cgc
);
2084 CGRect rect
= SCtoCGRect(bounds
);
2085 if (mBackground
) mBackground
->draw(cgc
, rect
);
2087 if (mBackgroundImage
)
2088 mBackgroundImage
->draw(cgc
, rect
);
2091 QDDrawBevelRect(cgc
, rect
, 1, true);
2094 CGRect cgThumbRect
= SCtoCGRect(mThumbRect
);
2095 if (mKnob
) mKnob
->draw(cgc
, cgThumbRect
);
2096 QDDrawBevelRect(cgc
, cgThumbRect
, 2, false);
2097 CGContextRestoreGState(cgc
);
2099 //drawBevelRect(SCtoQDRect(mBounds), 1, 1, SCtoQDColor(mBackColor), 2);
2100 //drawBevelRect(SCtoQDRect(mThumbRect), 2, 0, SCtoQDColor(mKnobColor), 2);
2103 bool SCSlider
::setValue(double inValue
, bool send
)
2105 inValue
= sc_clip(inValue
, 0.
, 1.
);
2106 if (mStepSize
> 0.
) {
2107 inValue
= floor(inValue
* mStepScale
+ 0.5) * mStepSize
;
2109 bool changed
= inValue
!= mValue
;
2114 if (send
) sendMessage(s_doaction
, 0, 0, 0);
2119 void SCSlider
::setValueFromPoint(SCPoint point
)
2121 double moveableRange
, value
;
2122 SCRect bounds
= getDrawBounds();
2123 if (bounds.width
> bounds.height
) {
2124 moveableRange
= bounds.width
- mThumbSize
- 2;
2125 value
= (point.x
- bounds.x
- 1 - mThumbSize
/2) / moveableRange
;
2127 moveableRange
= bounds.height
- mThumbSize
- 2;
2128 value
= 1.
- (point.y
- bounds.y
- 1 - mThumbSize
/2) / moveableRange
;
2130 setValue(value
, true);
2133 void SCSlider
::calcThumbRect(SCRect bounds
)
2135 double moveableRange
;
2137 moveableRange
= (bounds.width
> bounds.height
)
2138 ? bounds.width
: bounds.height
;
2139 moveableRange
-= mThumbSize
+ 2;
2141 double offset
= mValue
* moveableRange
;
2143 if (bounds.width
> bounds.height
) {
2144 mThumbRect
= SCMakeRect(bounds.x
+ offset
+ 1, bounds.y
+ 1,
2145 mThumbSize
, bounds.height
- 2);
2147 mThumbRect
= SCMakeRect(bounds.x
+ 1, bounds.y
+ bounds.height
- offset
- 1 - mThumbSize
,
2148 bounds.width
- 2, mThumbSize
);
2152 void SCSlider
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
2154 if (modifiers
& NSCommandKeyMask
) {
2157 setValueFromPoint(where
);
2161 int SCSlider
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2164 if (symbol
== s_value
) {
2166 err
= slotDoubleVal(slot
, &value
);
2167 if (err
) return err
;
2168 bool changed
= setValue(value
, false);
2169 SetBool(slot
, changed
);
2172 char *name
= symbol
->name
;
2173 if (strcmp(name
, "knobColor")==0) {
2174 err
= slotBackgroundVal(slot
, &mKnob
);
2175 if (err
) return err
;
2179 if (strcmp(name
, "step")==0) {
2180 err
= slotDoubleVal(slot
, &mStepSize
);
2182 mStepScale
= 1.
/ mStepSize
;
2183 bool changed
= setValue(mValue
, false);
2184 SetBool(slot
, changed
);
2188 if (strcmp(name
, "thumbSize")==0) {
2189 err
= slotFloatVal(slot
, &mThumbSize
);
2190 if (err
) return err
;
2195 return SCView
::setProperty(symbol
, slot
);
2198 int SCSlider
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2200 if (symbol
== s_value
) {
2201 SetFloat(slot
, mValue
);
2204 char *name
= symbol
->name
;
2205 if (strcmp(name
, "step")==0) {
2206 SetFloat(slot
, mStepSize
);
2209 if (strcmp(name
, "thumbSize")==0) {
2210 SetFloat(slot
, mThumbSize
);
2214 return SCView
::getProperty(symbol
, slot
);
2219 bool SCSlider
::canReceiveDrag()
2222 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
2223 return IsTrue(&result
);
2226 void SCSlider
::receiveDrag()
2228 sendMessage(s_receiveDrag
, 0, 0, 0);
2231 ///////////////////////////////////////////////////////////////////////////////////////
2233 SCView
* NewSCRangeSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2235 return new SCRangeSlider(inParent
, inObj
, inBounds
);
2238 SCRangeSlider
::SCRangeSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2239 : SCView(inParent
, inObj
, inBounds
), mStepSize(0.
), mStepScale(0.
)
2241 mKnob
= new HiliteGradientBackground(SCMakeColor(0,0,0.5,1), SCMakeColor(0.5,0.5,1,1), grad_Narrow
, 24);
2244 setValue(0.0, 0.0, false);
2247 //int drawBevelRect(Rect r, int width, int inout, RGBColor color, int drawop);
2249 void SCRangeSlider
::draw(SCRect inDamage
)
2252 SCRect bounds
= getDrawBounds();
2254 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
2255 CGContextSaveGState(cgc
);
2257 CGRect cgBounds
= SCtoCGRect(bounds
);
2258 if (mBackground
) mBackground
->draw(cgc
, cgBounds
);
2260 if (mBackgroundImage
)
2261 mBackgroundImage
->draw(cgc
, cgBounds
);
2263 QDDrawBevelRect(cgc
, cgBounds
, 1, true);
2265 CGRect cgRangeRect
= SCtoCGRect(mRangeRect
);
2266 if (mKnob
) mKnob
->draw(cgc
, cgRangeRect
);
2267 QDDrawBevelRect(cgc
, cgRangeRect
, 1, false);
2268 CGContextRestoreGState(cgc
);
2270 //drawBevelRect(SCtoQDRect(mBounds), 2, 1, SCtoQDColor(mBackColor), 2);
2271 //drawBevelRect(SCtoQDRect(mRangeRect), 1, 0, SCtoQDColor(mKnobColor), 2);
2274 bool SCRangeSlider
::setValue(double inLo
, double inHi
, bool send
)
2276 inLo
= sc_clip(inLo
, 0.
, 1.
);
2277 inHi
= sc_clip(inHi
, 0.
, 1.
);
2279 if (mStepSize
> 0.
) {
2280 inLo
= floor(inLo
* mStepScale
+ 0.5) * mStepSize
;
2281 inHi
= floor(inHi
* mStepScale
+ 0.5) * mStepSize
;
2283 bool changed
= inLo
!= mLo || inHi
!= mHi
;
2289 if (send
) sendMessage(s_doaction
, 0, 0, 0);
2294 void SCRangeSlider
::setValueFromPoint(SCPoint where
)
2296 double moveableRange
, lo
, hi
;
2297 SCRect bounds
= getDrawBounds();
2299 if (bounds.width
> bounds.height
) {
2300 moveableRange
= bounds.width
- 5;
2301 lo
= (sc_min(mAnchor.x
, where.x
) - bounds.x
- 2) / moveableRange
;
2302 hi
= (sc_max(mAnchor.x
, where.x
) - bounds.x
- 2) / moveableRange
;
2304 moveableRange
= bounds.height
- 5;
2305 lo
= 1.
- (sc_max(mAnchor.y
, where.y
) - bounds.y
- 2) / moveableRange
;
2306 hi
= 1.
- (sc_min(mAnchor.y
, where.y
) - bounds.y
- 2) / moveableRange
;
2308 setValue(lo
, hi
, true);
2311 void SCRangeSlider
::calcRangeRect()
2313 double moveableRange
;
2314 SCRect bounds
= getDrawBounds();
2315 moveableRange
= (bounds.width
> bounds.height
)
2316 ? bounds.width
: bounds.height
;
2319 double lo
= mLo
* moveableRange
;
2320 double hi
= mHi
* moveableRange
+ 1;
2322 if (bounds.width
> bounds.height
) {
2323 mRangeRect
= SCMakeRect(bounds.x
+ lo
+ 2, bounds.y
+ 1,
2324 hi
- lo
, bounds.height
- 2);
2326 mRangeRect
= SCMakeRect(bounds.x
+ 1, bounds.y
+ bounds.height
- hi
- 2,
2327 bounds.width
- 2, hi
- lo
);
2331 void SCRangeSlider
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
2334 // sc.solar: allow drag
2335 //setValueFromPoint(where);
2338 void SCRangeSlider
::moveRangeFromPoint(SCPoint where
)
2340 double moveableRange
, lo
, hi
, pos
, range
;
2341 SCRect bounds
= getDrawBounds();
2342 if (bounds.width
> bounds.height
) {
2343 moveableRange
= bounds.width
- 5;
2344 pos
= (where.x
- bounds.x
- 2) / moveableRange
;
2346 if (pos
-(range
/2) < 0.0) {
2349 } else if (pos
+(range
/2) > 1.0) {
2357 moveableRange
= bounds.height
- 5;
2358 pos
= 1.0 - (where.y
- bounds.y
- 2) / moveableRange
;
2360 if (pos
-(range
/2) < 0.0) {
2363 } else if (pos
+(range
/2) > 1.0) {
2371 setValue(lo
, hi
, true);
2374 void SCRangeSlider
::adjustLoFromPoint(SCPoint where
)
2376 double moveableRange
, lo
, hi
, pos
;
2377 SCRect bounds
= getDrawBounds();
2378 if (bounds.width
> bounds.height
) {
2379 moveableRange
= bounds.width
- 5;
2380 pos
= (where.x
- bounds.x
- 2) / moveableRange
;
2384 moveableRange
= bounds.height
- 5;
2385 pos
= (where.y
- bounds.y
- 2) / moveableRange
;
2389 setValue(lo
, hi
, true);
2391 void SCRangeSlider
::adjustHiFromPoint(SCPoint where
)
2393 double moveableRange
, lo
, hi
, pos
;
2394 SCRect bounds
= getDrawBounds();
2395 if (bounds.width
> bounds.height
) {
2396 moveableRange
= bounds.width
- 5;
2397 pos
= (where.x
- bounds.x
- 2) / moveableRange
;
2401 moveableRange
= bounds.height
- 5;
2402 pos
= (where.y
- bounds.y
- 2) / moveableRange
;
2406 setValue(lo
, hi
, true);
2409 void SCRangeSlider
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
2411 if (modifiers
& NSCommandKeyMask
) {
2413 } else if (modifiers
& NSControlKeyMask
) {
2414 moveRangeFromPoint(where
);
2415 } else if (modifiers
& NSShiftKeyMask
) {
2416 adjustLoFromPoint(where
);
2417 } else if (modifiers
& NSAlternateKeyMask
) {
2418 adjustHiFromPoint(where
);
2420 setValueFromPoint(where
);
2424 int SCRangeSlider
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2427 if (symbol
== s_lo || symbol
== s_value
) {
2429 err
= slotDoubleVal(slot
, &lo
);
2430 if (err
) return err
;
2431 bool changed
= setValue(lo
, mHi
, false);
2432 SetBool(slot
, changed
);
2435 if (symbol
== s_hi
) {
2437 err
= slotDoubleVal(slot
, &hi
);
2438 if (err
) return err
;
2439 bool changed
= setValue(mLo
, hi
, false);
2440 SetBool(slot
, changed
);
2443 if (symbol
== s_range
) {
2445 err
= slotDoubleVal(slot
, &range
);
2446 if (err
) return err
;
2447 bool changed
= setValue(mLo
, mLo
+ range
, false);
2448 SetBool(slot
, changed
);
2451 char *name
= symbol
->name
;
2452 if (strcmp(name
, "step")==0) {
2453 err
= slotDoubleVal(slot
, &mStepSize
);
2455 mStepScale
= 1.
/ mStepSize
;
2456 bool changed
= setValue(mLo
, mHi
, false);
2457 SetBool(slot
, changed
);
2461 if (strcmp(name
, "knobColor")==0) {
2462 err
= slotBackgroundVal(slot
, &mKnob
);
2463 if (err
) return err
;
2468 return SCView
::setProperty(symbol
, slot
);
2471 int SCRangeSlider
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2473 if (symbol
== s_lo || symbol
== s_value
) {
2474 SetFloat(slot
, mLo
);
2477 if (symbol
== s_hi
) {
2478 SetFloat(slot
, mHi
);
2481 if (symbol
== s_range
) {
2482 SetFloat(slot
, mHi
- mLo
);
2485 char *name
= symbol
->name
;
2486 if (strcmp(name
, "step")==0) {
2487 SetFloat(slot
, mStepSize
);
2491 return SCView
::getProperty(symbol
, slot
);
2495 bool SCRangeSlider
::canReceiveDrag()
2498 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
2499 return IsTrue(&result
);
2502 void SCRangeSlider
::receiveDrag()
2504 sendMessage(s_receiveDrag
, 0, 0, 0);
2507 ///////////////////////////////////////////////////////////////////////////////////////
2509 SCView
* NewSC2DSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2511 return new SC2DSlider(inParent
, inObj
, inBounds
);
2514 SC2DSlider
::SC2DSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2515 : SCView(inParent
, inObj
, inBounds
), mStepSize(0.
), mStepScale(0.
), mKnob(0)
2519 setValue(0.0, 0.0, false);
2522 //int drawBevelRect(Rect r, int width, int inout, RGBColor color, int drawop);
2524 void SC2DSlider
::draw(SCRect inDamage
)
2528 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
2529 CGContextSaveGState(cgc
);
2530 CGRect rect
= SCtoCGRect(getDrawBounds());
2531 if (mBackground
) mBackground
->draw(cgc
, rect
);
2533 if (mBackgroundImage
)
2534 mBackgroundImage
->draw(cgc
, rect
);
2536 QDDrawBevelRect(cgc
, rect
, 1, true);
2538 CGRect cgThumbRect
= SCtoCGRect(mThumbRect
);
2539 if (mKnob
) mKnob
->draw(cgc
, cgThumbRect
);
2540 QDDrawBevelRect(cgc
, cgThumbRect
, 2, false);
2541 CGContextRestoreGState(cgc
);
2543 // drawBevelRect(SCtoQDRect(mBounds), 1, 1, SCtoQDColor(mBackColor), 2);
2544 // drawBevelRect(SCtoQDRect(mThumbRect), 2, 0, SCtoQDColor(mKnobColor), 2);
2547 bool SC2DSlider
::setValue(double inX
, double inY
, bool send
)
2549 inX
= sc_clip(inX
, 0.
, 1.
);
2550 inY
= sc_clip(inY
, 0.
, 1.
);
2551 if (mStepSize
> 0.
) {
2552 inX
= floor(inX
* mStepScale
+ 0.5) * mStepSize
;
2553 inY
= floor(inY
* mStepScale
+ 0.5) * mStepSize
;
2555 bool changed
= inX
!= mX || inY
!= mY
;
2561 if (send
) sendMessage(s_doaction
, 0, 0, 0);
2566 const int THUMBSIZE
= 12;
2568 void SC2DSlider
::setValueFromPoint(SCPoint where
)
2570 SCRect bounds
= getDrawBounds();
2571 double x
= (where.x
- bounds.x
- 1 - THUMBSIZE
/2) / (bounds.width
- THUMBSIZE
- 2);
2572 double y
= 1.
- (where.y
- bounds.y
- 1 - THUMBSIZE
/2) / (bounds.height
- THUMBSIZE
- 2);
2573 setValue(x
, y
, true);
2576 void SC2DSlider
::calcThumbRect()
2578 SCRect bounds
= getDrawBounds();
2579 double x
= mX
* (bounds.width
- THUMBSIZE
- 2);
2580 double y
= mY
* (bounds.height
- THUMBSIZE
- 2);
2582 mThumbRect
= SCMakeRect(bounds.x
+ x
+ 1, bounds.y
+ bounds.height
- y
- 1 - THUMBSIZE
, THUMBSIZE
, THUMBSIZE
);
2585 void SC2DSlider
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
2587 if (modifiers
& NSCommandKeyMask
) {
2590 setValueFromPoint(where
);
2594 int SC2DSlider
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2597 if (symbol
== s_x
) {
2599 err
= slotDoubleVal(slot
, &x
);
2600 if (err
) return err
;
2601 bool changed
= setValue(x
, mY
, false);
2602 SetBool(slot
, changed
);
2605 if (symbol
== s_y
) {
2607 err
= slotDoubleVal(slot
, &y
);
2608 if (err
) return err
;
2609 bool changed
= setValue(mX
, y
, false);
2610 SetBool(slot
, changed
);
2613 char *name
= symbol
->name
;
2614 if (strcmp(name
, "knobColor")==0) {
2615 err
= slotBackgroundVal(slot
, &mKnob
);
2616 if (err
) return err
;
2620 if (strcmp(name
, "step")==0) {
2621 err
= slotDoubleVal(slot
, &mStepSize
);
2623 mStepScale
= 1.
/ mStepSize
;
2624 bool changed
= setValue(mX
, mY
, false);
2625 SetBool(slot
, changed
);
2630 return SCView
::setProperty(symbol
, slot
);
2633 int SC2DSlider
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2635 if (symbol
== s_x
) {
2639 if (symbol
== s_y
) {
2643 char *name
= symbol
->name
;
2644 if (strcmp(name
, "step")==0) {
2645 SetFloat(slot
, mStepSize
);
2649 return SCView
::getProperty(symbol
, slot
);
2652 bool SC2DSlider
::canReceiveDrag()
2655 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
2656 return IsTrue(&result
);
2659 void SC2DSlider
::receiveDrag()
2661 sendMessage(s_receiveDrag
, 0, 0, 0);
2664 ///////////////////////////////////////////////////////////////////////////////////////
2665 ///////////////////////////////////////////////////////////////////////////////////////
2667 SCView
* NewSCScope(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2669 return new SCScope(inParent
, inObj
, inBounds
);
2672 SCScope
::SCScope(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
2673 : SCView(inParent
, inObj
, inBounds
), mBufNum(0), mStyle(0), mGridOn(true)
2675 mZoom
= mInvZoom
= SCMakePoint(1.
,1.
);
2676 mScroll
= SCMakePoint(0.
,0.
);
2677 memset(&mSndBuf
, 0, sizeof(SndBuf
));
2678 mGridColor
= SCMakeColor(0.2,0.2,1.0, 1.0);
2679 mBackground
= new SolidColorBackground(
2680 SCMakeColor(0.
,0.
,0.
, 1.0));
2681 SCColor waveColor
= SCMakeColor(1.0,1.0,0.0, 1.0);
2682 for (int i
=0; i
<kMaxScopeChannels
; ++i
) mWaveColors
[i
] = waveColor
;
2692 int getScopeBuf(uint32 index
, SndBuf
*buf
, bool& didChange
);
2694 void SCScope
::animate()
2697 /*int err =*/ getScopeBuf(mBufNum
, &mSndBuf
, didChange
);
2698 if (didChange
) refresh();
2701 void SCScope
::draw0(CGContextRef cgc
)
2703 float *data
= mSndBuf.data
;
2706 int samples
= mSndBuf.samples
;
2707 SCRect bounds
= getDrawBounds();
2709 CGRect rect
= SCtoCGRect(bounds
);
2710 int width
= (int)bounds.width
- 2;
2711 int channels
= sc_min(mSndBuf.channels
, kMaxScopeChannels
);
2712 //post("channels %d\n", channels);
2713 float chanHeight
= (bounds.height
- 2.
) / channels
;
2714 float chanHeight2
= 0.5 * chanHeight
;
2715 float yScale
= mZoom.y
* chanHeight2
;
2717 for (int j
=0; j
<channels
; ++j
)
2719 CGContextSetRGBFillColor(cgc
, mWaveColors
[j
].red
, mWaveColors
[j
].green
, mWaveColors
[j
].blue
, mWaveColors
[j
].alpha
);
2720 float fframe
= mScroll.x
;
2721 float hzoom
= mZoom.x
;
2722 int iframe
= (int)floor(fframe
);
2723 int isample
= iframe
* channels
;
2724 float val
= -data
[isample
+ j
];
2727 chanRect.origin.x
= rect.origin.x
+ 1.
;
2728 chanRect.origin.y
= rect.origin.y
+ 1.
+ chanHeight
* j
+ chanHeight2
;
2729 chanRect.size.width
= width
;
2730 chanRect.size.height
= chanHeight
;
2732 //post("width %d\n", width);
2733 for (int i
= 0; i
< width
&& isample
< samples
; i
++)
2737 float nextfframe
= fframe
+ hzoom
;
2738 int nextiframe
= (int)floor(nextfframe
);
2739 int nscan
= nextiframe
- iframe
;
2740 for (int k
=0; k
<nscan
&& isample
< samples
; ++k
)
2742 val
= -data
[isample
+ j
];
2743 if (val
< ymin
) ymin
= val
;
2744 else if (val
> ymax
) ymax
= val
;
2745 isample
+= channels
;
2747 iframe
= nextiframe
;
2748 fframe
= nextfframe
;
2751 wrect.origin.x
= rect.origin.x
+ 1.
+ i
;
2752 wrect.size.width
= 1.
;
2753 wrect.origin.y
= chanRect.origin.y
+ ymin
* yScale
;
2754 wrect.size.height
= (ymax
- ymin
) * yScale
+ 1.
;
2756 //if (i == 64) post("%g %g %g %g %g\n", ymin, ymin, wrect.origin.x, wrect.origin.y, wrect.size.height);
2758 CGContextFillRect(cgc
, wrect
);
2763 void SCScope
::draw1(CGContextRef cgc
)
2765 float *data
= mSndBuf.data
;
2768 int samples
= mSndBuf.samples
;
2769 SCRect bounds
= getDrawBounds();
2772 CGRect rect
= SCtoCGRect(bounds
);
2773 int width
= (int)bounds.width
- 2;
2774 int channels
= sc_min(mSndBuf.channels
, kMaxScopeChannels
);
2775 //post("channels %d\n", channels);
2776 float chanHeight
= bounds.height
- 2.
;
2777 float chanHeight2
= 0.5 * chanHeight
;
2778 float yScale
= mZoom.y
* chanHeight2
;
2780 for (int j
=0; j
< channels
; ++j
)
2782 CGContextSetRGBFillColor(cgc
, mWaveColors
[j
].red
, mWaveColors
[j
].green
, mWaveColors
[j
].blue
, mWaveColors
[j
].alpha
);
2783 float fframe
= mScroll.x
;
2784 float hzoom
= mZoom.x
;
2785 int iframe
= (int)floor(fframe
);
2786 int isample
= iframe
* channels
;
2787 float val
= -data
[isample
+ j
];
2790 chanRect.origin.x
= rect.origin.x
+ 1.
;
2791 chanRect.origin.y
= rect.origin.y
+ 1.
+ chanHeight2
;
2792 chanRect.size.width
= rect.size.width
- 2.
;
2793 chanRect.size.height
= chanHeight
;
2795 //post("width %d\n", width);
2796 for (int i
= 0; i
< width
&& isample
< samples
; i
++)
2800 float nextfframe
= fframe
+ hzoom
;
2801 int nextiframe
= (int)floor(nextfframe
);
2802 int nscan
= nextiframe
- iframe
;
2803 for (int k
=0; k
<nscan
; ++k
)
2805 val
= -data
[isample
+ j
];
2806 if (val
< ymin
) ymin
= val
;
2807 else if (val
> ymax
) ymax
= val
;
2808 isample
+= channels
;
2810 iframe
= nextiframe
;
2811 fframe
= nextfframe
;
2814 wrect.origin.x
= rect.origin.x
+ 1.
+ i
;
2815 wrect.size.width
= 1.
;
2816 wrect.origin.y
= chanRect.origin.y
+ ymin
* yScale
;
2817 wrect.size.height
= (ymax
- ymin
) * yScale
+ 1.
;
2819 //if (i == 64) post("%g %g %g %g %g\n", ymin, ymin, wrect.origin.x, wrect.origin.y, wrect.size.height);
2821 CGContextFillRect(cgc
, wrect
);
2826 void SCScope
::draw2(CGContextRef cgc
)
2828 float *data
= mSndBuf.data
;
2831 int samples
= mSndBuf.samples
;
2832 SCRect bounds
= getDrawBounds();
2835 CGRect rect
= SCtoCGRect(bounds
);
2836 int channels
= sc_min(mSndBuf.channels
, kMaxScopeChannels
);
2837 float height
= rect.size.height
- 2.
;
2838 float height2
= 0.5 * height
;
2839 float width
= mBounds.width
- 2.
;
2840 float width2
= 0.5 * width
;
2841 float yScale
= mZoom.y
* height2
;
2842 float xScale
= mZoom.x
* width2
;
2843 float xoff
= rect.origin.x
+ width2
+ 1.
;
2844 float yoff
= rect.origin.y
+ height2
+ 1.
;
2847 for (int k
=0, j
=0; j
<channels
; k
++, j
+=2)
2849 CGContextSetRGBStrokeColor(cgc
, mWaveColors
[k
].red
, mWaveColors
[k
].green
, mWaveColors
[k
].blue
, mWaveColors
[k
].alpha
);
2850 float x
= xoff
+ data
[j
] * xScale
;
2851 float y
= yoff
- data
[j
+1] * yScale
;
2852 CGContextMoveToPoint(cgc
, x
, y
);
2854 for (int i
=channels
; i
<samples
; i
+=channels
) {
2855 x
= xoff
+ data
[i
+j
] * xScale
;
2856 y
= yoff
- data
[i
+j
+1] * yScale
;
2857 CGContextAddLineToPoint(cgc
, x
, y
);
2859 CGContextStrokePath(cgc
);
2865 void SCScope
::draw(SCRect inDamage
)
2868 int err
= getScopeBuf(mBufNum
, &mSndBuf
, didChange
);
2870 SCRect bounds
= getDrawBounds();
2871 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
2872 CGContextSaveGState(cgc
);
2873 CGRect rect
= SCtoCGRect(bounds
);
2874 if (mBackground
) mBackground
->draw(cgc
, rect
);
2876 if (mBackgroundImage
)
2877 mBackgroundImage
->draw(cgc
, rect
);
2879 QDDrawBevelRect(cgc
, rect
, 1, true);
2884 case 0 : draw0(cgc
); break;
2885 case 1 : draw1(cgc
); break;
2886 case 2 : draw2(cgc
); break;
2889 CGContextRestoreGState(cgc
);
2893 void SCScope
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
2897 int SCScope
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2900 if (symbol
== s_x
) {
2902 err
= slotDoubleVal(slot
, &x
);
2903 if (err
) return err
;
2907 if (symbol
== s_y
) {
2909 err
= slotDoubleVal(slot
, &y
);
2910 if (err
) return err
;
2914 char *name
= symbol
->name
;
2915 if (strcmp(name
, "xZoom")==0) {
2917 err
= slotDoubleVal(slot
, &x
);
2918 if (err
) return err
;
2923 if (strcmp(name
, "yZoom")==0) {
2925 err
= slotDoubleVal(slot
, &y
);
2926 if (err
) return err
;
2932 if (strcmp(name
, "bufnum")==0) {
2933 err
= slotIntVal(slot
, &mBufNum
);
2934 if (err
) return err
;
2938 if (strcmp(name
, "gridColor")==0) {
2939 err
= slotColorVal(slot
, &mGridColor
);
2940 if (err
) return err
;
2944 if (strcmp(name
, "waveColors")==0) {
2945 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
2946 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
2947 for (int i
=0; i
<slotRawObject(slot
)->size
; ++i
)
2949 err
= slotColorVal(slots
+i
, mWaveColors
+i
);
2950 if (err
) return err
;
2955 if (strcmp(name
, "style")==0) {
2956 err
= slotIntVal(slot
, &mStyle
);
2957 if (err
) return err
;
2962 return SCView
::setProperty(symbol
, slot
);
2965 int SCScope
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
2967 if (symbol
== s_x
) {
2968 SetFloat(slot
, mScroll.x
);
2971 if (symbol
== s_y
) {
2972 SetFloat(slot
, mScroll.y
);
2976 char *name
= symbol
->name
;
2977 if (strcmp(name
, "xZoom")==0) {
2978 SetFloat(slot
, mZoom.x
);
2981 if (strcmp(name
, "yZoom")==0) {
2982 SetFloat(slot
, mZoom.y
);
2985 if (strcmp(name
, "bufnum")==0) {
2986 SetInt(slot
, mBufNum
);
2989 if (strcmp(name
, "gridColor")==0) {
2990 return setSlotColor(slot
, &mGridColor
);
2992 if (strcmp(name
, "waveColors")==0) {
2993 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
2994 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
2995 for (int i
=0; i
<slotRawObject(slot
)->size
; ++i
)
2997 int err
= setSlotColor(slots
+i
, mWaveColors
+i
);
2998 if (err
) return err
;
3004 return SCView
::getProperty(symbol
, slot
);
3007 ///////////////////////////////////////////////////////////////////////////////////////
3009 SCView
* NewSC2DTabletSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3011 return new SC2DTabletSlider(inParent
, inObj
, inBounds
);
3013 SC2DTabletSlider
::SC2DTabletSlider(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3014 : SC2DSlider(inParent
, inObj
, inBounds
), mClipInBounds(1)
3018 int SC2DTabletSlider
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3020 char *name
= symbol
->name
;
3021 if (strcmp(name
, "clipInBounds")==0) {
3022 slotIntVal(slot
, &mClipInBounds
);
3025 return SC2DSlider
::setProperty(symbol
, slot
);
3028 bool SC2DTabletSlider
::setValue(double inX
, double inY
,bool )
3031 inX
= sc_clip(inX
, 0.
, 1.
);
3032 inY
= sc_clip(inY
, 0.
, 1.
);
3034 if (mStepSize
> 0.
) {
3035 inX
= floor(inX
* mStepScale
+ 0.5) * mStepSize
;
3036 inY
= floor(inY
* mStepScale
+ 0.5) * mStepSize
;
3038 bool changed
= inX
!= mX || inY
!= mY
;
3047 void SC2DTabletSlider
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3049 if (modifiers
& NSCommandKeyMask
) {
3052 setValueFromPoint(where
);
3053 TABLETTRACK(s_mouseDown
,mX
,mY
)
3057 void SC2DTabletSlider
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3059 if (! (modifiers
& NSCommandKeyMask
)) {
3060 setValueFromPoint(where
);
3061 TABLETTRACK(s_doaction
,mX
,mY
)
3065 void SC2DTabletSlider
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3067 if (modifiers
& NSCommandKeyMask
) {
3070 setValueFromPoint(where
);
3071 TABLETTRACK(s_mouseUp
,mX
,mY
)
3074 void SC2DTabletSlider
::mouseDownAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3077 void SC2DTabletSlider
::mouseMoveAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3080 void SC2DTabletSlider
::mouseUpAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3085 ///////////////////////////////////////////////////////////////////////////////////////////////
3088 SCView
* NewSCButton(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3090 return new SCButton(inParent
, inObj
, inBounds
);
3093 SCButton
::SCButton(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3094 : SCView(inParent
, inObj
, inBounds
), mNumStates(0), mStates(0), mPushed(false)
3096 setValue(0, false, 0);
3097 strcpy(mFontName
, "Helvetica");
3101 SCButton
::~
SCButton()
3106 void SCButton
::draw(SCRect inDamage
)
3108 SCColor buttonColor
;
3109 SCRect bounds
= getDrawBounds();
3112 SCButtonState
*state
= mStates
+ mValue
;
3113 buttonColor
= state
->mButtonColor
;
3114 //drawBevelRect(SCtoQDRect(mBounds), 2, mPushed ? 1 : 0, SCtoQDColor(buttonColor), 2);
3116 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
3117 CGContextSaveGState(cgc
);
3119 CGRect cgrect
= SCtoCGRect(bounds
);
3120 if (buttonColor.alpha
> 0.0) {
3121 CGContextSetRGBFillColor(cgc
, buttonColor.red
, buttonColor.green
, buttonColor.blue
, buttonColor.alpha
);
3122 CGContextFillRect(cgc
, cgrect
);
3124 QDDrawBevelRect(cgc
, cgrect
, 2, mPushed
);
3125 CGContextRestoreGState(cgc
);
3127 SCRect innerBounds
= bounds
;
3129 int pushOffset
= mPushed ?
2 : 0;
3130 innerBounds.x
+= inset
+ pushOffset
;
3131 innerBounds.y
+= inset
+ pushOffset
;
3132 innerBounds.width
-= inset
* 2 + pushOffset
;
3133 innerBounds.height
-= inset
* 2 + pushOffset
;
3134 stringDrawCenteredInRect(state
->mLabel
, innerBounds
, mFontName
, mFontSize
, state
->mLabelColor
);
3138 bool SCButton
::setValue(int inValue
, bool send
, int modifiers
)
3140 bool changed
= inValue
!= mValue
;
3142 if (inValue
< 0 || inValue
>= mNumStates
) inValue
= 0;
3143 if (inValue
!= mValue || mNumStates
< 2) {
3146 SetInt(args
, modifiers
);
3147 if (send
) sendMessage(s_doaction
, 1, args
, 0);
3153 void SCButton
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3155 if (modifiers
& NSCommandKeyMask
) {
3158 bool inside
= hit(where
);
3159 if (inside
!= mPushed
) {
3166 void SCButton
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3168 bool inside
= hit(where
);
3169 if (inside
) setValue(mValue
+1, true, modifiers
);
3173 int SCMakeButtonState(SCButton
* view
, SCButtonState
*inState
, PyrSlot
*slot
)
3176 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
3177 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
3179 inState
->mLabel
[0] = 0;
3180 inState
->mLabelColor
= SCMakeColor(0,0,0,1); // black
3181 inState
->mButtonColor
= SCMakeColor(0.7,0.7,0.7,1);
3183 if (slotRawObject(slot
)->size
< 1) return errNone
;
3184 err
= slotStrVal(slots
+0, inState
->mLabel
, kLabelSize
);
3185 if (err
) return err
;
3187 if (slotRawObject(slot
)->size
< 2) return errNone
;
3188 err
= slotColorVal(slots
+1, &inState
->mLabelColor
);
3190 inState
->mLabelColor
= SCMakeColor(0,0,0,1); // black
3193 if (slotRawObject(slot
)->size
< 3) return errNone
;
3194 err
= slotColorVal(slots
+2, &inState
->mButtonColor
);
3196 //inState->mButtonColor = view->getBackColor();
3201 int SCButton
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3204 if (symbol
== s_value
) {
3206 err
= slotIntVal(slot
, &value
);
3207 if (err
) return err
;
3208 bool changed
= setValue(value
, false, 0);
3209 SetBool(slot
, changed
);
3212 char *name
= symbol
->name
;
3213 if (strcmp(name
, "font")==0) {
3214 if (!isKindOfSlot(slot
, getsym("SCFont")->u.classobj
)) return errWrongType
;
3215 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
3218 err
= slotFloatVal(slots
+1, &fontSize
);
3219 if (err
) return err
;
3221 err
= slotStrVal(slots
+0, mFontName
, kFontNameSize
);
3222 if (err
) return err
;
3224 mFontSize
= fontSize
;
3227 if (strcmp(name
, "states")==0) {
3228 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
3235 PyrObject
*array
= slotRawObject(slot
);
3236 int numStates
= array
->size
;
3237 SCButtonState
* states
= new SCButtonState
[numStates
];
3238 if (!states
) return errFailed
;
3239 for (int i
=0; i
<numStates
; ++i
) {
3240 SCButtonState
*state
= states
+ i
;
3241 PyrSlot
*slot
= array
->slots
+ i
;
3242 err
= SCMakeButtonState(this, state
, slot
);
3249 mNumStates
= numStates
;
3253 return SCView
::setProperty(symbol
, slot
);
3256 int SCButton
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3258 if (symbol
== s_value
) {
3259 SetInt(slot
, mValue
);
3262 //char *name = symbol->name;
3264 return SCView
::getProperty(symbol
, slot
);
3267 bool SCButton
::canReceiveDrag()
3270 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
3271 return IsTrue(&result
);
3274 void SCButton
::receiveDrag()
3276 sendMessage(s_receiveDrag
, 0, 0, 0);
3279 ///////////////////////////////////////////////////////////////////////////////////////////////
3281 @implementation SCNSMenu
3292 - (void) selectedItem
:(id)item
3294 NSMenuItem
*s
= (NSMenuItem
*) item
;
3304 SCView
* NewSCPopUpMenu(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3306 return new SCPopUpMenu(inParent
, inObj
, inBounds
);
3309 SCPopUpMenu
::SCPopUpMenu(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3310 : SCView(inParent
, inObj
, inBounds
), mValue(0), mMenu(0)
3312 mStringColor
= SCMakeColor(0,0,0,1);
3313 //mArrowColor = SCMakeColor(0,0,0,0);
3314 strcpy(mFontName
, "Helvetica");
3318 SCPopUpMenu
::~
SCPopUpMenu()
3320 if (mMenu
) [mMenu release
];
3323 void SCPopUpMenu
::draw(SCRect inDamage
)
3325 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
3326 CGContextSaveGState(cgc
);
3327 SCRect dbounds
= getDrawBounds();
3329 CGRect rect
= SCtoCGRect(dbounds
);
3330 if (mBackground
) mBackground
->draw(cgc
, rect
);
3332 if (mBackgroundImage
)
3333 mBackgroundImage
->draw(cgc
, rect
);
3335 CGRect bounds
= SCtoCGRect(dbounds
);
3336 QDDrawBevelRect(cgc
, bounds
, 1, false);
3338 CGContextSetRGBFillColor(cgc
, mStringColor.red
, mStringColor.green
, mStringColor.blue
, mStringColor.alpha
);
3340 int vc
= (int)(bounds.origin.y
+ bounds.size.height
/2);
3341 int hc
= (int)(bounds.origin.x
+ 7);
3342 CGContextMoveToPoint(cgc
, hc
-3, vc
-3);
3344 CGContextAddLineToPoint(cgc
, hc
+3, vc
-3);
3345 CGContextAddLineToPoint(cgc
, hc
, vc
+3);
3346 CGContextAddLineToPoint(cgc
, hc
-3, vc
-3);
3347 CGContextFillPath(cgc
);
3349 CGContextRestoreGState(cgc
);
3352 int numberOfItems
= [mMenu numberOfItems
];
3353 if (numberOfItems
) {
3354 char *cstring
= NULL
;
3355 NSMenuItem
*item
= [mMenu itemAtIndex
:mValue
];
3358 NSString
*title
= [item title
];
3361 int length
= [title lengthOfBytesUsingEncoding
:NSMacOSRomanStringEncoding
];
3362 cstring
= (char *) malloc(length
+1);
3363 [title getCString
:cstring maxLength
:length
+1 encoding
:NSMacOSRomanStringEncoding
];
3366 SCRect innerBounds
= dbounds
;
3368 innerBounds.x
+= inset
+ 10;
3369 innerBounds.y
+= inset
;
3370 innerBounds.width
-= inset
* 2 + 10;
3371 innerBounds.height
-= inset
* 2;
3372 stringDrawCenteredInRect((const char *) (cstring ? cstring
: "[text not retrieved]"), innerBounds
, mFontName
, mFontSize
, mStringColor
);
3373 if (cstring
) free(cstring
);
3378 bool SCPopUpMenu
::setValue(int inValue
, bool send
)
3380 if (!mMenu
) return false;
3382 bool changed
= inValue
!= mValue
;
3383 int numberOfItems
= [mMenu numberOfItems
];
3384 inValue
= sc_mod(inValue
, numberOfItems
);
3385 if (inValue
!= mValue || numberOfItems
< 2) {
3388 if (send
) sendMessage(s_doaction
, 0, 0, 0);
3394 void SCPopUpMenu
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3396 if (modifiers
& NSCommandKeyMask
) {
3400 SCRect bounds
= getDrawBounds();
3402 [(SCGraphView
*)mTop
->GetNSView() startMenuTracking
: this];
3404 int numberOfItems
= [mMenu numberOfItems
];
3405 for (int i
=0; i
<numberOfItems
; ++i
) {
3406 [[mMenu itemAtIndex
:i
] setState
:mValue
==i
];
3409 NSPoint p
= NSMakePoint(bounds.x
, bounds.y
);
3410 NSView
*view
= mTop
->GetNSView();
3411 [NSMenu popUpContextMenu
:mMenu withEvent
:theEvent forView
:view
];
3412 setValue([mMenu current
], true);
3416 int SCPopUpMenu
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3419 if (symbol
== s_value
) {
3421 err
= slotIntVal(slot
, &value
);
3422 if (err
) return err
;
3423 bool changed
= setValue(value
, false);
3424 SetBool(slot
, changed
);
3427 char *name
= symbol
->name
;
3428 if (strcmp(name
, "font")==0) {
3429 if (!isKindOfSlot(slot
, getsym("SCFont")->u.classobj
)) return errWrongType
;
3430 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
3433 err
= slotFloatVal(slots
+1, &fontSize
);
3434 if (err
) return err
;
3436 err
= slotStrVal(slots
+0, mFontName
, kFontNameSize
);
3437 if (err
) return err
;
3439 mFontSize
= fontSize
;
3442 if (strcmp(name
, "items")==0) {
3443 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
3446 if (mMenu
) [mMenu release
];
3448 PyrObject
*array
= slotRawObject(slot
);
3449 int numItems
= array
->size
;
3451 mMenu
= [[SCNSMenu alloc
] init
];
3453 for (int i
=0; i
<numItems
; ++i
) {
3454 PyrSlot
*slot
= array
->slots
+ i
;
3457 int err
= slotStrVal(slot
, title
, 255);
3458 if (err
) return err
;
3460 NSString
*t
= [NSString stringWithCString
:(const char *)title encoding
:NSMacOSRomanStringEncoding
];
3461 NSMenuItem
*item
= [mMenu addItemWithTitle
:t action
:@selector(selectedItem
:) keyEquivalent
:@
""];
3462 [item setTarget
:mMenu
];
3468 if (strcmp(name
, "stringColor")==0) {
3469 err
= slotColorVal(slot
, &mStringColor
);
3470 if (err
) return err
;
3475 return SCView
::setProperty(symbol
, slot
);
3478 int SCPopUpMenu
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3480 if (symbol
== s_value
) {
3481 SetInt(slot
, mValue
);
3484 char* name
= symbol
->name
;
3485 if (strcmp(name
, "stringColor")==0) {
3486 return setSlotColor(slot
, &mStringColor
);
3489 return SCView
::getProperty(symbol
, slot
);
3493 bool SCPopUpMenu
::canReceiveDrag()
3496 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
3497 return IsTrue(&result
);
3500 void SCPopUpMenu
::receiveDrag()
3502 sendMessage(s_receiveDrag
, 0, 0, 0);
3505 /////////////////////////////////////////////////////////////////
3506 //SCMultiSliderView by jan trutzschler jan.21.03 //jan.23.03 changed draw added more prop.//jan.28.03 debug
3507 //jan.29.03 value 1.0 up // draw . //feb.03.02 ..
3509 int allocSlotDoubleArrayVal(PyrSlot
*slot
, double **arr
);
3510 int allocSlotDoubleArrayVal(PyrSlot
*slot
, double **arr
)
3518 if (isKindOfSlot(slot
, class_array
)) {
3519 len
= slotRawObject(slot
)->size
;
3520 *arr
= new double[len
];
3521 // memcpy(*arr, slotRawObject(slot)->slots, len * sizeof(double));
3522 for(int i
=0; i
<len
; i
++){
3523 err
= slotDoubleVal(slotRawObject(slot
)->slots
+i
, *arr
+i
);
3524 if (err
) *(*arr
+i
) = 0.0;
3528 return errWrongType
;
3530 SCView
* NewSCMultiSliderView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3532 return new SCMultiSliderView(inParent
, inObj
, inBounds
);
3535 SCMultiSliderView
::SCMultiSliderView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
3536 : SCView(inParent
, inObj
, inBounds
), mThumbSize(12.
), mStepSize(0.
),
3537 mStepScale(0.
), mKnob(0), mXOffset(1)
3539 mTabSize
= (int) (inBounds.width
/ mThumbSize
);
3540 mCurrentIndex
= mStartIndex
= 0;
3541 mThumbSizeY
= mThumbSize
;
3545 mYValues
= new double [mTabSize
];
3546 memset(mYValues
, 0, mTabSize
* sizeof(double));
3547 mReadOnly
= mShowIndex
= false;
3548 mFillColor
= SCMakeColor(0,0,0,1); // black
3549 mStrokeColor
= SCMakeColor(0,0,0,1); // black
3550 mIsFilled
= mDrawLinesActive
= false;
3551 mDrawRectsActive
= true;
3553 mIsHorizontal
= true;
3557 SCMultiSliderView
::~
SCMultiSliderView()
3560 if(mSecYValues
) delete mSecYValues
;
3564 void SCMultiSliderView
::draw(SCRect inDamage
)
3566 SCRect bounds
= getDrawBounds();
3568 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
3569 CGContextSaveGState(cgc
);
3570 CGRect rect
= SCtoCGRect(bounds
);
3571 CGContextClipToRect(cgc
, rect
);
3572 double * vals
= mYValues
;
3573 int xpixels
= mTabSize
;
3574 int xstart
= mStartIndex
;
3576 if(mIsHorizontal
) mElasticIndexStep
= (bounds.width
- 2)/(mTabSize
-mStartIndex
);
3577 else mElasticIndexStep
= (bounds.height
- 2)/(mTabSize
-mStartIndex
);
3578 } else mElasticIndexStep
= 0.0;
3579 double step
= mElasticIndexStep
;
3581 if (mBackground
) mBackground
->draw(cgc
, rect
);
3583 if (mBackgroundImage
)
3584 mBackgroundImage
->draw(cgc
, rect
);
3586 QDDrawBevelRect(cgc
, rect
, 1, true);
3588 CGContextSetRGBFillColor(cgc
, mFillColor.red
, mFillColor.green
, mFillColor.blue
, mFillColor.alpha
);
3589 CGContextSetRGBStrokeColor(cgc
, mStrokeColor.red
, mStrokeColor.green
, mStrokeColor.blue
, mStrokeColor.alpha
);
3594 //draw dots for multislider
3595 if(mDrawRectsActive
)
3598 for(int i
= xstart
; i
< xpixels
; i
++, j
++){
3599 drawRect
= SCtoCGRect(calcThumbRect(j
, vals
[i
], step
));
3600 CGContextFillRect (cgc
, drawRect
);
3601 if (mThumbSize
> 1.
) CGContextStrokeRect(cgc
,drawRect
);
3602 if(mSecYValues
){ //draw the upper part of a wave view
3603 drawRect
= SCtoCGRect(calcThumbRect(j
, mSecYValues
[i
], step
));
3604 CGContextFillRect (cgc
, drawRect
);
3605 if (mThumbSize
> 1.
) CGContextStrokeRect(cgc
,drawRect
);
3610 if (mDrawLinesActive
) {
3611 float xadd
, gcx
, gcy
;
3613 xadd
= (step
> mThumbSize
) ?
(mThumbSize
* 0.5) : (step
>1.0) ?
(step
* 0.5) : 1;
3615 if(mThumbSize
> 1) xadd
= mThumbSize
* 0.5;
3619 for(int i
= xstart
; i
< xpixels
; i
++, j
++){
3621 drawRect
= SCtoCGRect(calcThumbRect(j
, yval
, step
));
3622 gcx
= drawRect.origin.x
+ xadd
;
3623 gcy
= drawRect.origin.y
;
3625 CGContextMoveToPoint(cgc
, gcx
, gcy
);
3627 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
3629 //these are fixed values: used for the max of soundfiles, need to go backwards to fill
3630 if (mSecYValues
!= NULL
) {
3631 int j
= xpixels
- 1 - xstart
;
3632 for(int i
= xpixels
- 1; i
>= xstart
; i
--, j
--){
3633 yval
= mSecYValues
[i
];
3634 drawRect
= SCtoCGRect(calcThumbRect(j
, yval
, step
));
3635 gcx
= drawRect.origin.x
+ xadd
;
3636 gcy
= drawRect.origin.y
+ xadd
;
3637 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
3640 if(mIsFilled
) CGContextEOFillPath(cgc
);
3641 else CGContextStrokePath(cgc
);
3645 if(mCurrentIndex
+ mSelectionSize
>= xstart
){
3646 int currentI
, selsize
;
3647 if(mCurrentIndex
< xstart
) {
3649 selsize
= sc_clip(mSelectionSize
, xstart
, mTabSize
);
3651 currentI
= mCurrentIndex
- xstart
;
3652 selsize
= mSelectionSize
;
3656 drawRect
= CGRectMake(bounds.x
+ 1 + (currentI
* mElasticIndexStep
),
3658 (selsize
* mElasticIndexStep
),
3661 drawRect
= CGRectMake(bounds.x
+ 1 + (currentI
* ( mXOffset
+ mThumbSize
)),
3663 (selsize
* ( mXOffset
+ mThumbSize
)) - mXOffset
,
3667 drawRect
= CGRectMake( bounds.x
+ 1,
3668 bounds.y
+ 1 + (currentI
* mElasticIndexStep
),
3670 (selsize
* mElasticIndexStep
));
3672 drawRect
= CGRectMake( bounds.x
+ 1,
3673 bounds.y
+ 1 + (currentI
* ( mXOffset
+ mThumbSize
)),
3675 (selsize
* ( mXOffset
+ mThumbSize
)) - mXOffset
);
3677 CGContextSetRGBFillColor(cgc
, mFillColor.red
, mFillColor.green
, mFillColor.blue
, 0.4);
3678 CGContextFillRect (cgc
, drawRect
);
3681 CGContextRestoreGState(cgc
);
3685 bool SCMultiSliderView
::setValue(int xIn
, double yIn
, bool send
)
3688 yIn
= sc_clip(yIn
, 0.
, 1.
);
3689 xIn
= sc_clip(xIn
, 0, mTabSize
- 1);
3691 if (mStepSize
> 0.
) {
3692 yIn
= floor(yIn
* mStepScale
+ 0.5) * mStepSize
;
3695 mCurrentIndex
= xIn
;
3696 changed
= mYValues
[xIn
] != yIn
;
3698 mYValues
[xIn
] = yIn
;
3700 if (send
) sendMessage(s_doaction
, 0, 0, 0);
3701 // post("new val: %f x: %d \n", (float) yIn, xIn);
3705 int xindx
, lastindx
, maxSize
;
3706 lastindx
= mCurrentIndex
;
3709 xindx
= sc_clip(xindx
, 0, mTabSize
- 1);
3710 mCurrentIndex
= xindx
;
3711 mCurrentY
= mYValues
[mCurrentIndex
];
3712 if(mCurrentIndex
> (lastindx
+ mSelectionSize
)) mSelectionSize
= 1;
3713 maxSize
= mTabSize
- mCurrentIndex
;
3714 if(mSelectionSize
> maxSize
) mSelectionSize
= maxSize
;
3716 if (send
) sendMessage(s_doaction
, 0, 0, 0);
3717 //post("readOnly: x: %d \n", mCurrentIndex);
3718 if(mShowIndex
) refresh();
3724 int SCMultiSliderView
::indexFromPoint(SCPoint where
)
3726 SCRect bounds
= getDrawBounds();
3730 return (int) ((where.x
- bounds.x
-1)/mElasticIndexStep
);
3732 return (int) ((where.x
- bounds.x
-1)/(mThumbSize
+ mXOffset
)) + mStartIndex
;
3734 return (int) ((where.y
- bounds.y
-1)/(mThumbSize
+ mXOffset
)) + mStartIndex
;
3738 double SCMultiSliderView
::valueFromPoint(SCPoint where
)
3740 SCRect bounds
= getDrawBounds();
3743 return 1.0 - (where.y
- bounds.y
- 1 - mThumbSizeY
/2) / (bounds.height
- mThumbSizeY
- 2);
3745 return (where.x
- bounds.x
- 1 - mThumbSizeY
/2) / (bounds.width
- mThumbSizeY
- 2);
3749 void SCMultiSliderView
::setValueFromPoint(SCPoint where
)
3751 double y
= valueFromPoint(where
);
3752 int xIndx
= indexFromPoint(where
);
3753 setValue(xIndx
, y
, true);
3756 SCRect SCMultiSliderView
::calcThumbRect(int indexIn
, double valIn
, double step
)
3758 double x
,y
, thumbx
, thumby
;
3759 float xoffset
= mXOffset
;
3760 SCRect bounds
= getDrawBounds();
3762 //post("step is: %f ", step);
3765 thumby
= mThumbSizeY
;
3767 thumbx
= (step
> mThumbSize
) ? mThumbSize
: (step
>1.0) ? step
: 1;
3768 x
= indexIn
* step
;
3770 x
= (double) indexIn
* ( xoffset
+ mThumbSize
);
3771 thumbx
= mThumbSize
;
3773 y
= valIn
* (bounds.height
- thumby
- 2);
3774 y
= bounds.y
+ bounds.height
- y
- 1 - thumby
;
3775 x
= bounds.x
+ x
+ 1;
3776 if(mIsFilled
) thumby
= bounds.height
;
3778 thumbx
= mThumbSizeY
;
3780 thumbx
= (step
> mThumbSize
) ? mThumbSize
: step
;
3781 y
= indexIn
* step
;
3783 y
= (double) indexIn
* ( xoffset
+ mThumbSize
);
3785 x
= valIn
* (bounds.width
- thumbx
- 2);
3786 //x = bounds.x + bounds.width - x - 1 - thumby;
3787 x
= bounds.x
+ x
+ 1;
3788 y
= bounds.y
+ y
+ 1;
3790 thumbx
+= x
- bounds.x
;
3793 thumby
= mThumbSize
;
3795 return SCMakeRect( x
, y
, thumbx
, thumby
);
3798 void SCMultiSliderView
::setSelection(SCPoint where
)
3801 int visiIn
= mCurrentIndex
- mStartIndex
;
3802 int maxSize
= mTabSize
- mCurrentIndex
;
3803 wx
= indexFromPoint(where
);
3804 if(wx
> visiIn
) mSelectionSize
= (int) wx
- visiIn
;
3806 setValueFromPoint(where
);
3807 mSelectionSize
= (int) mCurrentIndex
- wx
;
3809 if(mSelectionSize
> maxSize
) mSelectionSize
= maxSize
;
3813 void SCMultiSliderView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3816 mouseTrack(where
, modifiers
,theEvent
);
3818 void SCMultiSliderView
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
){
3819 // sendMessage(getsym("mouseEndTrack"), 0, 0, 0);
3820 mouseTrack(where
, modifiers
,theEvent
);
3822 void SCMultiSliderView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
3824 if (modifiers
& NSCommandKeyMask
) {
3826 } else if (modifiers
& NSShiftKeyMask
) {
3828 setSelection(where
);
3829 sendMessage(getsym("doAction"), 0, 0, 0);
3831 } else if (modifiers
& NSControlKeyMask
) {
3832 if(mIsHorizontal
) mCurrentX
= where.x
; //absolute y mouse position
3833 else mCurrentX
= where.y
;
3834 sendMessage(getsym("doMetaAction"), 0, 0, 0);
3836 int prevIndex
= indexFromPoint(mPrevPoint
);
3837 int index
= indexFromPoint(where
);
3838 double prevValue
= valueFromPoint(mPrevPoint
);
3839 double value
= valueFromPoint(where
);
3840 if (prevIndex
== index
) {
3841 setValue(index
, value
, true);
3842 } else if (prevIndex
< index
) {
3843 double val
= prevValue
;
3844 double delta
= (value
- prevValue
) / (index
- prevIndex
);
3845 for (int i
=prevIndex
; i
<=index
; ++i
) {
3846 setValue(i
, val
, true);
3851 double delta
= (prevValue
- value
) / (prevIndex
- index
);
3852 for (int i
=index
; i
<=prevIndex
; ++i
) {
3853 setValue(i
, val
, true);
3861 int SCMultiSliderView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
3864 char *name
= symbol
->name
;
3865 if (strcmp(name
, "step")==0) {
3866 err
= slotDoubleVal(slot
, &mStepSize
);
3868 mStepScale
= 1.
/ mStepSize
;
3869 bool changed
= false;
3870 bool changedout
= false;
3871 for(int i
=0; i
< mTabSize
; ++i
){
3872 changed
= setValue(i
, mYValues
[i
], false);
3873 if(changed
) changedout
= changed
;
3875 SetBool(slot
, changedout
);
3879 if (strcmp(name
, "thumbSize")==0) {
3880 err
= slotFloatVal(slot
, &mThumbSize
);
3885 if (strcmp(name
, "thumbWidth")==0) {
3886 err
= slotFloatVal(slot
, &mThumbSizeY
);
3891 if (strcmp(name
, "indexThumbSize")==0) {
3892 err
= slotFloatVal(slot
, &mThumbSize
);
3897 if (strcmp(name
, "valueThumbSize")==0) {
3898 err
= slotFloatVal(slot
, &mThumbSizeY
);
3903 if (strcmp(name
, "xOffset")==0) {
3904 err
= slotFloatVal(slot
, &mXOffset
);
3905 if(mXOffset
< 1.0) mXOffset
= 0.0; //mResamp = (int) 1.0 / mXOffset;
3910 if (strcmp(name
, "fillColor")==0) {
3911 err
= slotColorVal(slot
, &mFillColor
);
3915 if (strcmp(name
, "strokeColor")==0) {
3916 err
= slotColorVal(slot
, &mStrokeColor
);
3920 if (strcmp(name
, "startIndex")==0) {
3921 err
= slotIntVal(slot
, &mStartIndex
);
3926 if (strcmp(name
, "readOnly")==0) {
3927 mReadOnly
= IsTrue(slot
);
3931 if (strcmp(name
, "isHorizontal")==0) {
3932 mIsHorizontal
= IsTrue(slot
);
3936 if (strcmp(name
, "drawLines")==0) {
3937 mDrawLinesActive
= IsTrue(slot
);
3941 if (strcmp(name
, "drawRects")==0) {
3942 mDrawRectsActive
= IsTrue(slot
);
3946 if (strcmp(name
, "isFilled")==0) {
3947 mIsFilled
= IsTrue(slot
);
3951 if (strcmp(name
, "showIndex")==0) {
3952 mShowIndex
= IsTrue(slot
);
3956 if (symbol
== s_x
) {
3957 slotIntVal(slot
, &mCurrentIndex
);
3958 mCurrentIndex
= sc_clip(mCurrentIndex
, 0, mTabSize
- 1);
3959 int maxSize
= mTabSize
- mCurrentIndex
;
3960 if(mSelectionSize
> maxSize
) mSelectionSize
= maxSize
;
3964 if (symbol
== s_y
) {
3965 slotDoubleVal(slot
, &mCurrentY
);
3966 mCurrentY
= sc_clip(mCurrentY
, 0.0, 1.0);
3967 mYValues
[mCurrentIndex
] = mCurrentY
;
3971 if (symbol
== s_value
) {
3972 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
3973 if(slotRawObject(slot
)->size
!= mTabSize
) {
3974 err
= allocSlotDoubleArrayVal(slot
, &mYValues
);
3975 mTabSize
= slotRawObject(slot
)->size
;
3976 SetBool(slot
, true);
3979 int len
= slotRawObject(slot
)->size
;
3981 bool changed
= false;
3982 // memcpy(mYValues, slotRawObject(slot)->slots, len * sizeof(double));
3983 for(int i
=0; i
<len
; i
++){
3984 err
= slotDoubleVal(slotRawObject(slot
)->slots
+i
, &val
);
3985 if(mYValues
[i
] != val
) changed
= true;
3986 if (err
) mYValues
[i
] = 0.0; else mYValues
[i
] = val
;
3988 SetBool(slot
, changed
);
3995 if (strcmp(name
, "referenceValues")==0) {
3996 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
3997 if(slotRawObject(slot
)->size
== mTabSize
&& mSecYValues
!= NULL
) {
3998 err
= allocSlotDoubleArrayVal(slot
, &mSecYValues
);
4000 err
= allocSlotDoubleArrayVal(slot
, &mSecYValues
);
4005 if (strcmp(name
, "selectionSize")==0) {
4006 slotIntVal(slot
, &mSelectionSize
);
4011 if (strcmp(name
, "elasticResizeMode")==0) {
4012 slotIntVal(slot
, &mElasticMode
);
4019 return SCView
::setProperty(symbol
, slot
);
4022 int SCMultiSliderView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4025 char *name
= symbol
->name
;
4026 if (strcmp(name
, "step")==0) {
4027 SetFloat(slot
, mStepSize
);
4030 if (symbol
== s_x
) {
4031 SetInt(slot
, mCurrentIndex
);
4034 if (symbol
== s_y
) {
4035 SetFloat(slot
, mCurrentY
);
4038 if (symbol
== s_value
) {
4040 if (isKindOfSlot(slot
, class_array
)) {
4041 len
= slotRawObject(slot
)->size
;
4042 if(len
> mTabSize
) return errWrongType
;
4043 memcpy(slotRawObject(slot
)->slots
, mYValues
, len
* sizeof(double));
4047 if (strcmp(name
, "referenceValues")==0) {
4049 if (isKindOfSlot(slot
, class_array
)) {
4050 len
= slotRawObject(slot
)->size
;
4051 if(len
> mTabSize
) return errWrongType
;
4052 if (mSecYValues
!= NULL
)
4053 memcpy(slotRawObject(slot
)->slots
, mSecYValues
, len
* sizeof(double));
4058 if (strcmp(name
, "selectionSize")==0) {
4059 SetInt(slot
, mSelectionSize
);
4062 if (strcmp(name
, "absoluteX")==0) {
4063 SetInt(slot
, (int) mCurrentX
);
4068 return SCView
::getProperty(symbol
, slot
);
4071 bool SCMultiSliderView
::canReceiveDrag()
4074 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
4075 return IsTrue(&result
);
4078 void SCMultiSliderView
::receiveDrag()
4080 sendMessage(s_receiveDrag
, 0, 0, 0);
4082 //////////////////////////////////////////////////////////////////////////////////
4085 SCView
* NewSCUserView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4087 return new SCUserView(inParent
, inObj
, inBounds
);
4090 SCUserView
::SCUserView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4091 : SCView(inParent
, inObj
, inBounds
)
4093 mClearOnRefresh
= true;
4094 mDrawingEnabled
= true;
4095 mNSImageForLayering
= nil;
4096 for(char i
= 0; i
<kFrameLastTimes
; i
++) {
4097 mFrameLastTimes
[i
] = (float)i
;
4103 SCUserView
::~
SCUserView()
4105 if( mNSImageForLayering
)
4106 [ mNSImageForLayering release
];
4110 extern NSBitmapImageRep
* CreateBitmapContextRGBA(const int width
, const int height
);
4111 extern NSBitmapImageRep
* BitmapContextRGBAWithImage(const int width
, const int height
, id image
);
4113 void SCUserView
::draw(SCRect inDamage
)
4116 #define USE_BITMAPREP 0
4118 NSGraphicsContext
*lGCtx
= NULL
;
4119 CGContextRef mainGC
= NULL
;
4120 SCRect bounds
= getDrawBounds();
4121 CGRect cgBounds
= SCtoCGRect( bounds
);
4123 SCView
::draw(bounds
); // draw background
4125 lGCtx
= [NSGraphicsContext currentContext
];
4126 mainGC
= (CGContextRef
)[lGCtx graphicsPort
];
4128 if( !mDrawingEnabled ||
!mainGC
)
4131 if( bounds.width
<= 0 || bounds.height
<= 0)
4135 for( uint8_t i
= 1; i
< kFrameLastTimes
; ++i
)
4137 mFrameRate
= mFrameRate
+ ( mFrameLastTimes
[i
] - mFrameLastTimes
[i
-1] );
4138 mFrameLastTimes
[i
-1] = mFrameLastTimes
[i
];
4141 mFrameRate
= 1.f
/ ( mFrameRate
/ (kFrameLastTimes
-1) );
4145 gettimeofday(&tv
, 0);
4146 mFrameLastTimes
[kFrameLastTimes
-1] = (double)tv.tv_sec
+ 1.0e-6 * (double)tv.tv_usec
;
4148 CGContextSaveGState( mainGC
);
4149 if( !mClearOnRefresh
)
4152 !mNSImageForLayering ||
4153 [ mNSImageForLayering size
].width
!= bounds.width ||
4154 [ mNSImageForLayering size
].height
!= bounds.height
4157 if( mNSImageForLayering
)
4158 [ mNSImageForLayering release
];
4160 mNSImageForLayering
= [[NSImage alloc
]initWithSize
: *(NSSize
*)&cgBounds.size
];
4161 [mNSImageForLayering setFlipped
:YES
]; // important to provide compatibility with SC flipped view
4162 if( !mNSImageForLayering
)
4164 post( "Error: Failed creating valid NSBitmapImageRep for SCUserView" );
4169 mImageRep
= CreateBitmapContextRGBA((int)bounds.width
, (int)bounds.height
);
4172 post( "Error: Failed creating valid NSBitmapImageRep for SCUserView" );
4175 [mNSImageForLayering addRepresentation
: mImageRep
];
4176 [mImageRep release
];
4178 [mNSImageForLayering setCacheMode
: NSImageCacheBySize
]; // should be also bitmap based
4181 [mNSImageForLayering lockFocus
];
4186 CGContextClipToRect( mainGC
, cgBounds
);
4187 CGContextTranslateCTM( mainGC
, cgBounds.origin.x
, cgBounds.origin.y
);
4190 sendMessage(s_draw
, 0, 0, 0);
4192 if( !mClearOnRefresh
)
4194 [mNSImageForLayering unlockFocus
];
4195 NSAffineTransform
* trs
= [NSAffineTransform transform
];
4196 [trs translateXBy
:cgBounds.origin.x yBy
:cgBounds.origin.y
+ cgBounds.size.height
];
4197 [trs scaleXBy
:1.0 yBy
:-1.0];
4199 [mNSImageForLayering drawAtPoint
:NSZeroPoint fromRect
:NSZeroRect operation
:NSCompositeSourceOver fraction
:1.f
];
4201 CGContextRestoreGState( mainGC
);
4204 void SCUserView
::clearDrawing()
4206 if( mClearOnRefresh
)
4209 //SCRect bounds = getDrawBounds();
4210 //CGContextClearRect ( mNSImageForLayering , CGRectMake( 0, 0, bounds.width, bounds.height));
4211 [ mNSImageForLayering lockFocus
];
4212 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
]graphicsPort
];
4213 CGContextClearRect( cgc
, CGRectMake( 0.f
, 0.f
, [mNSImageForLayering size
].width
, [mNSImageForLayering size
].height
) );
4214 [ mNSImageForLayering unlockFocus
];
4218 void SCUserView
::mouseAction(PyrSymbol
*method
, SCPoint where
, int modifiers
)
4220 // SCRect bounds = getDrawBounds();
4222 // mRealtiveMousePoint.x = where.x - bounds.x;
4223 // mRealtiveMousePoint.y = where.y - bounds.y;
4226 // SetFloat(args+0, where.x);
4227 // SetFloat(args+1, where.y);
4228 // SetInt(args+2, modifiers);
4229 // sendMessage(method, 3, args, 0);
4232 void SCUserView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4234 SCRect bounds
= getDrawBounds();
4236 mRealtiveMousePoint.x
= where.x
- bounds.x
;
4237 mRealtiveMousePoint.y
= where.y
- bounds.y
;
4238 // mouseAction(getsym("mouseBeginTrack"), where, modifiers);
4241 void SCUserView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4243 // SCRect bounds = getDrawBounds();
4244 // mRealtiveMousePoint.x = where.x - bounds.x;
4245 // mRealtiveMousePoint.y = where.y - bounds.y;
4246 // if (modifiers & NSCommandKeyMask) {
4247 // beginDrag(where);
4251 // mouseAction(getsym("mouseTrack"), where, modifiers);
4255 void SCUserView
::mouseDownAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4257 SCRect bounds
= getDrawBounds();
4259 if(parent()->isTopContainer()) {
4260 mRealtiveMousePoint.x
= where.x
- bounds.x
;
4261 mRealtiveMousePoint.y
= where.y
- bounds.y
;
4263 mRealtiveMousePoint.x
= where.x
- mBounds.x
;
4264 mRealtiveMousePoint.y
= where.y
- mBounds.y
;
4267 SCView
::mouseDownAction(where
, modifiers
, theEvent
);
4269 if (modifiers
& NSCommandKeyMask
) {
4274 void SCUserView
::mouseMoveAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4276 SCRect bounds
= getDrawBounds();
4278 if(parent()->isTopContainer()) {
4279 mRealtiveMousePoint.x
= where.x
- bounds.x
;
4280 mRealtiveMousePoint.y
= where.y
- bounds.y
;
4282 mRealtiveMousePoint.x
= where.x
- mBounds.x
;
4283 mRealtiveMousePoint.y
= where.y
- mBounds.y
;
4286 SCView
::mouseMoveAction( where
, modifiers
, theEvent
);
4290 void SCUserView
::mouseUpAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4292 SCRect bounds
= getDrawBounds();
4294 if(parent()->isTopContainer()) {
4295 mRealtiveMousePoint.x
= where.x
- bounds.x
;
4296 mRealtiveMousePoint.y
= where.y
- bounds.y
;
4298 mRealtiveMousePoint.x
= where.x
- mBounds.x
;
4299 mRealtiveMousePoint.y
= where.y
- mBounds.y
;
4302 SCView
::mouseUpAction( where
, modifiers
, theEvent
);
4306 void SCUserView
::mouseOver(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4308 SCRect bounds
= getDrawBounds();
4310 if(parent()->isTopContainer()) {
4311 mRealtiveMousePoint.x
= where.x
- bounds.x
;
4312 mRealtiveMousePoint.y
= where.y
- bounds.y
;
4314 mRealtiveMousePoint.x
= where.x
- mBounds.x
;
4315 mRealtiveMousePoint.y
= where.y
- mBounds.y
;
4318 SCView
::mouseOver( where
, modifiers
, theEvent
);
4321 void SCUserView
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4323 // mouseAction(getsym("mouseEndTrack"), where, modifiers);
4326 void SCUserView
::keyDown(int character
, int modifiers
)
4330 void SCUserView
::keyUp(int character
, int modifiers
)
4334 bool SCUserView
::canReceiveDrag()
4337 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
4338 return IsTrue(&result
);
4341 void SCUserView
::receiveDrag()
4344 SetFloat(args
+0, mRealtiveMousePoint.x
);
4345 SetFloat(args
+1, mRealtiveMousePoint.y
);
4346 sendMessage(s_receiveDrag
, 2, args
, 0);
4349 int SCUserView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4351 char *name
= symbol
->name
;
4353 if (strcmp(name
, "clearOnRefresh")==0) {
4354 mClearOnRefresh
= IsTrue(slot
);
4357 if (strcmp(name
, "clearDrawing")==0) {
4361 if (strcmp(name
, "drawingEnabled")==0) {
4362 mDrawingEnabled
= IsTrue(slot
);
4365 if (strcmp(name
, "animate")==0) {
4374 return SCView
::setProperty(symbol
, slot
);
4377 int SCUserView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4379 char *name
= symbol
->name
;
4381 if (strcmp(name
, "mousePosition")==0) {
4382 if(isKindOfSlot(slot
, s_point
->u.classobj
)){
4384 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
4385 SetFloat(slots
+0, mRealtiveMousePoint.x
);
4386 SetFloat(slots
+1, mRealtiveMousePoint.y
);
4390 if (strcmp(name
, "frame")==0) {
4391 SetInt(slot
, mFrameCounter
);
4394 if (strcmp(name
, "frameRate")==0) {
4395 SetFloat(slot
, mFrameRate
);
4399 return SCView
::getProperty(symbol
, slot
);
4402 void SCUserView
::refreshInRect(SCRect b
)
4404 b.x
+= mLayout.bounds.x
;
4405 b.y
+= mLayout.bounds.y
;
4406 SCView
::refreshInRect(b
);
4410 ////////////////////////////////////////////////
4412 SCView
* NewSCStaticText(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4414 return new SCStaticText(inParent
, inObj
, inBounds
);
4417 SCStaticText
::SCStaticText(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4418 : SCView(inParent
, inObj
, inBounds
), mString(0), mAlignment(kSCAlignLeft
)
4420 strcpy(mFontName
, "Helvetica");
4422 mStringColor
= SCMakeColor(0,0,0,1);
4427 SCStaticText
::~
SCStaticText()
4432 bool SCStaticText
::shouldDim()
4437 void SCStaticText
::draw(SCRect inDamage
)
4439 SCView
::draw(inDamage
);
4440 SCRect bounds
= getDrawBounds();
4445 void SCStaticText
::drawString(SCRect bounds
)
4448 if (mAlignment
< 0) {
4449 stringDrawLeftInRect(mString
, bounds
, mFontName
, mFontSize
, mStringColor
);
4450 } else if (mAlignment
> 0) {
4451 stringDrawRightInRect(mString
, bounds
, mFontName
, mFontSize
, mStringColor
);
4453 stringDrawCenteredInRect(mString
, bounds
, mFontName
, mFontSize
, mStringColor
);
4458 int allocSlotStrVal(PyrSlot
*slot
, char **str
)
4466 len
= strlen(slotRawSymbol(slot
)->name
);
4467 *str
= new char[len
+1];
4468 strcpy(*str
, slotRawSymbol(slot
)->name
);
4470 } else if (isKindOfSlot(slot
, class_string
)) {
4471 len
= slotRawObject(slot
)->size
;
4472 *str
= new char[len
+1];
4473 memcpy(*str
, slotRawString(slot
)->s
, len
);
4477 return errWrongType
;
4480 int SCStaticText
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4483 char *name
= symbol
->name
;
4484 if (strcmp(name
, "string")==0) {
4485 err
= allocSlotStrVal(slot
, &mString
);
4486 if (err
) return err
;
4490 if (strcmp(name
, "font")==0) {
4491 if (!isKindOfSlot(slot
, getsym("SCFont")->u.classobj
)) return errWrongType
;
4492 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
4495 err
= slotFloatVal(slots
+1, &fontSize
);
4496 if (err
) return err
;
4498 err
= slotStrVal(slots
+0, mFontName
, kFontNameSize
);
4499 if (err
) return err
;
4501 mFontSize
= fontSize
;
4505 if (strcmp(name
, "stringColor")==0) {
4506 err
= slotColorVal(slot
, &mStringColor
);
4507 if (err
) return err
;
4511 if (strcmp(name
, "align")==0) {
4514 if (slotRawSymbol(slot
)->name
[0] == 'l') mAlignment
= -1;
4515 else if (slotRawSymbol(slot
)->name
[0] == 'r') mAlignment
= 1;
4516 else if (slotRawSymbol(slot
)->name
[0] == 'c') mAlignment
= 0;
4517 else return errFailed
;
4519 err
= slotIntVal(slot
, &align
);
4520 if (err
) return err
;
4526 return SCView
::setProperty(symbol
, slot
);
4529 int SCStaticText
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4531 char *name
= symbol
->name
;
4533 if (strcmp(name
, "stringColor")==0) {
4534 return setSlotColor(slot
, &mStringColor
);
4537 return SCView
::getProperty(symbol
, slot
);
4542 ////////////////////////////////////////////////
4544 SCView
* NewSCListView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4546 return new SCListView(inParent
, inObj
, inBounds
);
4549 SCListView
::SCListView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4550 : SCView(inParent
, inObj
, inBounds
), mArray(0), mScroll(0), mAlignment(kSCAlignLeft
)
4552 strcpy(mFontName
, "Helvetica");
4554 mStringColor
= SCMakeColor(0,0,0,1);
4555 mSelectedStringColor
= SCMakeColor(1,1,1,1);
4556 mHiliteColor
= SCMakeColor(0,0,0,1);
4558 mItemBackgroundColor
= NULL
;
4561 SCListView
::~
SCListView()
4563 if (mArray
) CFRelease(mArray
);
4566 NSSize
nsStringSize(NSString
*nsstring
, char *cFontName
, float fontSize
, SCColor sccolor
);
4567 NSRect
SCtoNSRect(SCRect screct
);
4569 void SCListView
::draw(SCRect inDamage
)
4571 SCView
::draw(inDamage
);
4572 SCRect bounds
= getDrawBounds();
4573 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
4574 CGContextSaveGState(cgc
);
4576 CGRect bevelRect
= SCtoCGRect(bounds
);
4577 QDDrawBevelRect(cgc
, bevelRect
, 1, true);
4579 int numItems
= mArray ?
CFArrayGetCount(mArray
) : 0;
4581 mStrSize
= nsStringSize((NSString
*)CFSTR("XWYjpgy"), mFontName
, mFontSize
, mStringColor
);
4583 float itemHeight
= mStrSize.height
+ 3.f
;
4584 //float totalHeight = itemHeight * numItems;
4585 float visibleItems
= bounds.height
/ itemHeight
;
4586 float fraction
= visibleItems
/ (float)numItems
;
4588 float totalHeight
= itemHeight
* numItems
;
4590 float maxScroll
= totalHeight
- bounds.height
;
4591 if (maxScroll
< 0) maxScroll
= 0;
4592 mScroll
= sc_clip(mScroll
, 0, maxScroll
);
4594 SCRect itemBounds
= bounds
;
4596 itemBounds.y
+= 2 - mScroll
;
4597 itemBounds.width
-= 6; itemBounds.height
-= 4;
4599 itemBounds.height
= itemHeight
;
4604 itemBounds.width
-= 16;
4607 SCRect sliderBounds
= bounds
;
4608 sliderBounds.x
= bounds.x
+ bounds.width
- 16;
4609 sliderBounds.width
= 15;
4610 sliderBounds.y
+= 1;
4611 sliderBounds.height
-= 2;
4612 bevelRect
= SCtoCGRect(sliderBounds
);
4613 QDDrawBevelRect(cgc
, bevelRect
, 1, true);
4615 float travel
= (1.f
- fraction
) * (bounds.height
- 4);
4616 SCRect thumbBounds
= sliderBounds
;
4617 thumbBounds.y
= 1.f
+ sliderBounds.y
+ travel
* (mScroll
/ maxScroll
);
4618 thumbBounds.height
= (sliderBounds.height
- 2) * fraction
;
4620 thumbBounds.width
-= 2;
4621 bevelRect
= SCtoCGRect(thumbBounds
);
4622 QDDrawBevelRect(cgc
, bevelRect
, 2, false);
4626 CGRect clipRect
= SCtoCGRect(bounds
);
4627 clipRect.origin.y
+= 1;
4628 clipRect.size.height
-= 2;
4629 CGContextClipToRect(cgc
, clipRect
);
4631 int minIndex
= (int)((mScroll
- itemHeight
+ 1) / itemHeight
);
4632 int maxIndex
= (int)(minIndex
+ 1 + (bounds.height
+ itemHeight
- 1) / itemHeight
);
4633 if (maxIndex
> numItems
- 1) maxIndex
= numItems
- 1;
4634 itemBounds.y
+= minIndex
* itemHeight
;
4637 for (int i
= minIndex
; i
<= maxIndex
; ++i
)
4639 NSString
* nsstring
= (NSString
*)CFArrayGetValueAtIndex(mArray
, i
);
4641 if(mItemBackgroundColor
){
4642 SCColor color
= mItemBackgroundColor
[i
];
4643 CGContextSetRGBFillColor(cgc
, color.red
, color.green
, color.blue
, color.alpha
);
4644 CGRect drawRect
= SCtoCGRect(itemBounds
);
4645 CGContextFillRect (cgc
, drawRect
);
4648 CGContextSetRGBFillColor(cgc
, mHiliteColor.red
, mHiliteColor.green
, mHiliteColor.blue
, mHiliteColor.alpha
);
4649 CGRect drawRect
= SCtoCGRect(itemBounds
);
4650 CGContextFillRect (cgc
, drawRect
);
4651 nsStringDrawInRectAlign(nsstring
, itemBounds
, mFontName
, mFontSize
, mSelectedStringColor
, mAlignment
, -1, &size
);
4653 nsStringDrawInRectAlign(nsstring
, itemBounds
, mFontName
, mFontSize
, mStringColor
, mAlignment
, -1, &size
);
4656 itemBounds.y
+= itemBounds.height
;
4658 CGContextRestoreGState(cgc
);
4662 void SCListView
::scrollToValue()
4664 int numItems
= mArray ?
CFArrayGetCount(mArray
) : 0;
4665 SCRect bounds
= getDrawBounds();
4667 float itemHeight
= mStrSize.height
+ 3.f
;
4668 //float visibleItems = mBounds.height / itemHeight;
4669 //float fraction = visibleItems / (float)numItems;
4670 float totalHeight
= itemHeight
* numItems
;
4672 float maxScroll
= totalHeight
- bounds.height
;
4673 if (maxScroll
< 0) maxScroll
= 0;
4675 SCRect itemBounds
= bounds
;
4677 itemBounds.y
+= 2 - mScroll
;
4678 itemBounds.width
-= 6; itemBounds.height
-= 4;
4679 itemBounds.height
= itemHeight
;
4681 itemBounds.y
+= mValue
* itemHeight
;
4683 if (itemBounds.y
< bounds.y
) mScroll
= mValue
* itemHeight
;
4684 else if (itemBounds.y
+ itemHeight
> bounds.y
+ bounds.height
) mScroll
= (mValue
+ 1) * itemHeight
- bounds.height
;
4687 bool SCListView
::setValue(int inValue
, bool send
)
4689 bool changed
= inValue
!= mValue
;
4690 int numItems
= mArray ?
CFArrayGetCount(mArray
) : 0;
4691 if (inValue
< 0) inValue
= numItems
- 1;
4692 else if (inValue
>= numItems
) inValue
= 0;
4693 if (inValue
!= mValue || numItems
< 2) {
4699 if (send
) sendMessage(s_doaction
, 0, 0, 0);
4704 int SCListView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4708 if (symbol
== s_value
) {
4710 err
= slotIntVal(slot
, &value
);
4711 if (err
) return err
;
4712 bool changed
= setValue(value
, false);
4713 SetBool(slot
, changed
);
4717 char *name
= symbol
->name
;
4718 if (strcmp(name
, "items")==0) {
4727 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
4735 PyrObject
*array
= slotRawObject(slot
);
4736 int numItems
= array
->size
;
4738 mArray
= (CFMutableArrayRef
)CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
4740 for (int i
=0; i
<numItems
; ++i
) {
4741 PyrSlot
*slot
= array
->slots
+ i
;
4745 int err
= slotStrVal(slot
, cstr
, 1023);
4746 if (err
) return err
;
4748 cfstr
= CFStringCreateWithCString(kCFAllocatorDefault
, cstr
, kCFStringEncodingUTF8
);
4750 CFArrayAppendValue(mArray
, cfstr
);
4756 if (strcmp(name
, "font")==0) {
4757 if (!isKindOfSlot(slot
, getsym("SCFont")->u.classobj
)) return errWrongType
;
4758 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
4761 err
= slotFloatVal(slots
+1, &fontSize
);
4762 if (err
) return err
;
4764 err
= slotStrVal(slots
+0, mFontName
, kFontNameSize
);
4765 if (err
) return err
;
4767 mFontSize
= fontSize
;
4771 if (strcmp(name
, "stringColor")==0) {
4772 err
= slotColorVal(slot
, &mStringColor
);
4773 if (err
) return err
;
4777 if (strcmp(name
, "itemColors")==0) {
4779 if (mItemBackgroundColor
) {
4780 // CFRelease(mItemBackgroundColor);
4781 delete(mItemBackgroundColor
);
4782 mItemBackgroundColor
= NULL
;
4787 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
4790 if (mItemBackgroundColor
) {
4791 // CFRelease(mItemBackgroundColor);
4792 delete(mItemBackgroundColor
);
4793 mItemBackgroundColor
= NULL
;
4796 PyrObject
*array
= slotRawObject(slot
);
4797 int numItems
= array
->size
;
4799 // mItemBackgroundColor = (CFMutableArrayRef)CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
4800 mItemBackgroundColor
= (SCColor
*) malloc(numItems
* sizeof(SCColor
));
4801 for (int i
=0; i
<numItems
; ++i
) {
4802 PyrSlot
*slot
= array
->slots
+ i
;
4805 int err
= slotColorVal(slot
, &color
);
4806 if (err
) return err
;
4807 mItemBackgroundColor
[i
] = color
;
4813 if (strcmp(name
, "selectedStringColor")==0) {
4814 err
= slotColorVal(slot
, &mSelectedStringColor
);
4815 if (err
) return err
;
4819 if (strcmp(name
, "hiliteColor")==0) {
4820 err
= slotColorVal(slot
, &mHiliteColor
);
4821 if (err
) return err
;
4825 if (strcmp(name
, "align")==0) {
4828 if (slotRawSymbol(slot
)->name
[0] == 'l') mAlignment
= -1;
4829 else if (slotRawSymbol(slot
)->name
[0] == 'r') mAlignment
= 1;
4830 else if (slotRawSymbol(slot
)->name
[0] == 'c') mAlignment
= 0;
4831 else return errFailed
;
4833 err
= slotIntVal(slot
, &align
);
4834 if (err
) return err
;
4840 return SCView
::setProperty(symbol
, slot
);
4843 int SCListView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
4845 if (symbol
== s_value
) {
4846 SetInt(slot
, mValue
);
4849 char *name
= symbol
->name
;
4851 if (strcmp(name
, "stringColor")==0) {
4852 return setSlotColor(slot
, &mStringColor
);
4855 if (strcmp(name
, "itemColors")==0) {
4858 slots
= slotRawObject(slot
)->slots
;
4859 size
= slotRawObject(slot
)->size
;
4860 for(int i
=0; i
<size
; i
++)
4862 err
= setSlotColor(slots
+i
, &mItemBackgroundColor
[i
]);
4868 return SCView
::getProperty(symbol
, slot
);
4872 bool SCListView
::canReceiveDrag()
4875 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
4876 return IsTrue(&result
);
4879 void SCListView
::receiveDrag()
4881 sendMessage(s_receiveDrag
, 0, 0, 0);
4884 void SCListView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4888 mAnchorScroll
= mScroll
;
4889 SCRect bounds
= getDrawBounds();
4891 mStrSize
= nsStringSize((NSString
*)CFSTR("XWYjpgy"), mFontName
, mFontSize
, mStringColor
);
4892 int numItems
= mArray ?
CFArrayGetCount(mArray
) : 0;
4894 float itemHeight
= mStrSize.height
+ 3.f
;
4895 float visibleItems
= bounds.height
/ itemHeight
;
4896 float fraction
= visibleItems
/ (float)numItems
;
4898 mScrolling
= fraction
< 1.f
&& where.x
>= bounds.x
+ bounds.width
- 16;
4900 int value
= (int)((where.y
- bounds.y
- 2 + mScroll
) / itemHeight
);
4901 setValue(value
, true);
4905 void SCListView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
4907 if (modifiers
& NSCommandKeyMask
) {
4911 SCRect bounds
= getDrawBounds();
4913 int numItems
= mArray ?
CFArrayGetCount(mArray
) : 0;
4915 float itemHeight
= mStrSize.height
+ 3.f
;
4916 float visibleItems
= bounds.height
/ itemHeight
;
4917 float fraction
= visibleItems
/ (float)numItems
;
4918 float totalHeight
= itemHeight
* numItems
;
4919 float travel
= (1.f
- fraction
) * (bounds.height
- 4);
4921 float maxScroll
= totalHeight
- bounds.height
;
4922 if (maxScroll
< 0) maxScroll
= 0;
4923 float sliderOffset
= travel
* (mAnchorScroll
/ maxScroll
);
4925 float change
= where.y
- mAnchor.y
;
4926 float newSliderOffset
= sliderOffset
+ change
;
4927 mScroll
= maxScroll
* newSliderOffset
/ travel
;
4929 mScroll
= sc_clip(mScroll
, 0, maxScroll
);
4936 ////////////////////////////////////////////////
4937 //////////////////////////////////////////////////////////////////////////////////
4939 ////////////////////////////////////////////////
4940 //////////////////////////////////////////////////////////////////////////////////
4941 //////////////////////////////////////////////////////////////////////////////////
4942 //SCEnvelopeView by jan trutzschler feb.02.03 // udated feb.22.03
4943 int allocSlot2DDoubleArrayPyrSlot (PyrSlot
*slot
, double **arr
, int position
);
4944 int allocSlot2DDoubleArrayPyrSlot(PyrSlot
*slot
, double **arr
, int position
)
4952 if (isKindOfSlot(slot
, class_array
)) {
4953 len
= slotRawObject(slotRawObject(slot
)->slots
+ position
)->size
;
4954 *arr
= new double[len
];
4955 memcpy(*arr
, ((PyrDoubleArray
*)slotRawObject(slotRawObject(slot
)->slots
+position
))->d
, len
* sizeof(double));
4958 return errWrongType
;
4960 int allocEnvArray (int size
, SCEnvObject
**arr
);
4961 int allocEnvArray (int size
, SCEnvObject
**arr
){
4963 * arr
= new SCEnvObject
[size
];
4967 //int allocSlotEnvObjArray(PyrSlot *slot, SCEnvObject **arr);
4970 SCView
* NewSCEnvelopeView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4972 return new SCEnvelopeView(inParent
, inObj
, inBounds
);
4975 SCEnvelopeView
::SCEnvelopeView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
4976 : SCView(inParent
, inObj
, inBounds
), mThumbSize(5), mStepSize(0.
),mStepScale(0.
)
4980 mActiveSize
= mTabSize
;
4981 mCurrentIndex
= mStartIndex
= 0;
4982 mThumbSizeY
= mThumbSize
;
4988 mIsTracking
= false;
4993 mFillColor
= mStrokeColor
= SCMakeColor(0,0,0,1); // black
4994 mSelectedColor
= SCMakeColor(1.f
,0,0,1);
4995 mIsFilled
= mDrawLinesActive
= true;
4996 mDrawRectsActive
= true;
4997 // setVisibleSize();
4998 mSelectedIndex
= -1;
5000 mIsFixedSelection
= false;
5002 strcpy(mFontName
, "Helvetica");
5004 mDrawCenteredConnection
= true;
5006 mGridColor
= SCMakeColor(0, 0, 0.8, 0.3);
5007 mGrid
= SCMakePoint(0.1, 0.1);
5009 SCEnvelopeView
::~
SCEnvelopeView()
5012 for(int i
= 0; i
< mTabSize
; i
++){
5013 if( (mEnvObj
+i
)->mString
)
5014 delete [] (mEnvObj
+i
)->mString
;
5015 if((mEnvObj
+i
)->mConnections
)
5016 delete [] (mEnvObj
+i
)->mConnections
;
5018 if((mEnvObj+i)->mConnectionOutputs)
5019 delete [] (mEnvObj+i)->mConnectionOutputs;
5020 if((mEnvObj+i)->mConnectionInputs)
5021 delete [] (mEnvObj+i)->mConnectionInputs;
5028 if(drawOrder
) delete [] drawOrder
;
5032 int SCEnvelopeView
::allocSlotEnvObjArray(PyrSlot
*slot
, SCEnvObject
**arr
)
5034 int size
= slotRawObject(&(slotRawObject(slot
)->slots
[0]))->size
;
5036 SCEnvObject
* scenv
= 0;
5037 int err
= allocEnvArray(size
, &scenv
);
5040 if(size
> mTabSize
){
5041 memcpy(scenv
, *arr
, mTabSize
* sizeof(SCEnvObject
));
5042 for(int i
=mTabSize
; i
< size
; i
++){
5043 (scenv
+i
)->mObjectColor
= mFillColor
;
5044 (scenv
+i
)->mString
= 0;
5045 (scenv
+i
)->mConnections
= 0;
5046 (scenv
+i
)->mColor
= mFillColor
;
5047 (scenv
+i
)->mEditable
= true;
5048 (scenv
+i
)->mIsSelected
= false;
5049 (scenv
+i
)->mNumConnection
= 0;
5050 (scenv
+i
)->mRect.height
= mThumbSizeY
;
5051 (scenv
+i
)->mRect.width
= mThumbSize
;
5052 (scenv
+i
)->shape
= 1;
5053 (scenv
+i
)->curve
= 1.0;
5056 } else { //meaning size < mTabSize
5057 memcpy(scenv
, *arr
, size
* sizeof(SCEnvObject
));
5063 for(int i
=0; i
< size
; i
++){
5064 (scenv
+i
)->mObjectColor
= mFillColor
;
5065 (scenv
+i
)->mString
= 0;
5066 (scenv
+i
)->mConnections
= 0;
5067 (scenv
+i
)->mColor
= mFillColor
;
5068 (scenv
+i
)->mEditable
= true;
5069 (scenv
+i
)->mIsSelected
= false;
5070 (scenv
+i
)->mNumConnection
= 0;
5071 (scenv
+i
)->mRect.height
= mThumbSizeY
;
5072 (scenv
+i
)->mRect.width
= mThumbSize
;
5073 (scenv
+i
)->shape
= 1;
5074 (scenv
+i
)->curve
= 1.0;
5078 err
= allocEnvArray(size
, arr
);
5080 memcpy(*arr
, scenv
, size
* sizeof(SCEnvObject
));
5085 // helper constants for shape calculation
5086 #define EXPM1 (float) exp(-1.f)
5087 #define EXPM1R (float) (1.f - exp(-1.f))
5089 inline double linlinNoClip(double x
, double a
, double b
, double c
, double d
)
5091 // if (x <= a) return c;
5092 // if (x >= b) return d;
5093 return (x
-a
)/(b
-a
) * (d
-c
) + c
;
5096 void SCEnvelopeView
::draw(SCRect inDamage
)
5098 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
5099 CGContextSaveGState(cgc
);
5100 SCRect bounds
= getDrawBounds();
5102 CGRect rect
= SCtoCGRect(bounds
);
5103 CGContextClipToRect(cgc
, rect
);
5105 int xpixels
= mActiveSize
;
5108 if (mBackground
) mBackground
->draw(cgc
, rect
);
5110 if (mBackgroundImage
)
5111 mBackgroundImage
->draw(cgc
, rect
);
5113 QDDrawBevelRect(cgc
, rect
, 1, true);
5119 SCEnvObject
* envobj
;
5123 float xgrid
, ygrid
, xgridpos
, ygridpos
;
5124 float maxwidth
= (bounds.width
+ bounds.x
) - 2.f
;
5125 float maxheight
= (bounds.height
+ bounds.y
) - 2.f
;
5130 CGContextSetRGBFillColor(cgc
, mGridColor.red
, mGridColor.green
, mGridColor.blue
, mGridColor.alpha
);
5131 xgrid
= xgrid
*bounds.width
;
5132 xgridpos
= bounds.x
+1.f
+ xgrid
;
5133 ygrid
= ygrid
*bounds.height
;
5134 ygridpos
= bounds.y
+1.f
+ ygrid
;
5135 while(xgridpos
< maxwidth
&& (xgrid
> 0.0))
5137 drawRect
= CGRectMake(xgridpos
,
5141 CGContextFillRect (cgc
, drawRect
);
5145 while(ygridpos
< maxheight
&& (ygrid
> 0.0))
5147 drawRect
= CGRectMake(bounds.x
+1.f
,
5151 CGContextFillRect (cgc
, drawRect
);
5156 CGContextSetRGBFillColor(cgc
, mFillColor.red
, mFillColor.green
, mFillColor.blue
, mFillColor.alpha
);
5157 CGContextSetRGBStrokeColor(cgc
, mStrokeColor.red
, mStrokeColor.green
, mStrokeColor.blue
, mStrokeColor.alpha
);
5160 if (mDrawLinesActive
) {
5162 int numConnection
, num
;
5164 for(int i
= xstart
; i
< xpixels
; i
++){
5166 envobj
= &mEnvObj
[i
];
5167 setEnvRect(envobj
->x
, envobj
->y
, envobj
);
5169 if(mIsEnvView
){ //straight connection
5171 CGContextMoveToPoint(cgc
, envobj
->mDrawPoint.x
, envobj
->mDrawPoint.y
);
5173 float gcx
, gcy
, gcox
, gcoy
;
5174 SCEnvObject
* conObj
= (mEnvObj
+ (i
-1));
5176 float dur
, numpointsY
, yLevel
, pos
;
5177 float begTime
, endTime
, begLevel
, endLevel
, stepsize
, ar
, br
, yrange
;
5179 float startPointX
, endPointX
, startPointY
, endPointY
;
5180 curve
= conObj
->curve
;
5181 gcox
= envobj
->mDrawPoint.x
;
5182 gcoy
= envobj
->mDrawPoint.y
;
5183 gcx
= conObj
->mDrawPoint.x
;
5184 gcy
= conObj
->mDrawPoint.y
;
5185 // post("shape at i: %i, is: %i\n", i, conObj->shape);
5186 switch(conObj
->shape
){
5188 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5189 CGContextAddLineToPoint(cgc
, gcox
, gcy
);
5190 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
5193 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5194 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
5197 case shape_Exponential
:
5199 if(conObj
->x
<= envobj
->x
)
5207 begTime
= conObj
->x
;
5208 begLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5210 endTime
= envobj
->x
;
5211 endLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5220 begTime
= envobj
->x
;
5221 begLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5223 endTime
= conObj
->x
;
5224 endLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5227 numsteps
= (int) endPointX
- startPointX
;
5228 dur
= endTime
- begTime
;
5229 stepsize
= dur
/numsteps
;
5230 CGContextMoveToPoint(cgc
, startPointX
, startPointY
);
5232 for(int i
=1; i
<=numsteps
+1; i
++){
5233 double step
= sc_clip((i
*stepsize
), 0.0, dur
); // need to clip when here when clipping endLevel or begLevel
5234 double pos
= step
/ dur
;
5235 yLevel
= begLevel
* pow(endLevel
/ begLevel
, pos
);
5236 CGContextAddLineToPoint(cgc
, linlinNoClip((i
*stepsize
), 0.f
, dur
, startPointX
, endPointX
), linlinNoClip(yLevel
, begLevel
, endLevel
, startPointY
, endPointY
));
5238 CGContextAddLineToPoint(cgc
, endPointX
, endPointY
);
5244 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5245 CGContextAddCurveToPoint(cgc
, gcox
* EXPM1R
+ gcx
* EXPM1
, gcoy
, gcox
* EXPM1
+ gcx
* EXPM1R
, gcy
, gcx
, gcy
);
5249 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5251 CGContextAddCurveToPoint(cgc
, gcox
* 0.556f
+ gcx
* 0.444f
, gcoy
* 0.278f
+ gcy
* 0.722f
, gcox
* 0.29f
+ gcx
* 0.71f
, gcy
, gcx
, gcy
);
5253 CGContextAddCurveToPoint(cgc
, gcx
* 0.29f
+ gcox
* 0.71f
, gcoy
, gcx
* 0.556f
+ gcox
* 0.444f
, gcy
* 0.278f
+ gcoy
* 0.722f
, gcx
, gcy
);
5258 if(conObj
->x
<= envobj
->x
)
5266 begTime
= conObj
->x
;
5267 begLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5269 endTime
= envobj
->x
;
5270 endLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5279 begTime
= envobj
->x
;
5280 begLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5282 endTime
= conObj
->x
;
5283 endLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5286 numsteps
= (int) endPointX
- startPointX
;
5287 dur
= endTime
- begTime
;
5288 stepsize
= dur
/numsteps
;
5289 CGContextMoveToPoint(cgc
, startPointX
, startPointY
);
5291 for(int i
=1; i
<=numsteps
+1; i
++){
5292 double step
= sc_clip((i
*stepsize
), 0.0, dur
); // need to clip when here when clipping endLevel or begLevel
5293 double pos
= step
/ dur
;
5294 if (fabs(curve
) < 0.0001) {
5295 yLevel
= pos
* (endLevel
- begLevel
) + begLevel
;
5297 double denom
= 1.
- exp(curve
);
5298 double numer
= 1.
- exp(pos
* curve
);
5299 yLevel
= begLevel
+ (endLevel
- begLevel
) * (numer
/denom
);
5302 CGContextAddLineToPoint(cgc
, linlinNoClip((i
*stepsize
), 0.f
, dur
, startPointX
, endPointX
), linlinNoClip(yLevel
, begLevel
, endLevel
, startPointY
, endPointY
));
5304 CGContextAddLineToPoint(cgc
, endPointX
, endPointY
);
5310 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5312 CGContextAddCurveToPoint(cgc
, gcox
* 0.9f
+ gcx
* 0.1f
, gcoy
, gcox
* 0.5f
+ gcx
* 0.5f
, gcoy
, gcx
, gcy
);
5314 CGContextAddCurveToPoint(cgc
, gcx
* 0.5f
+ gcox
* 0.5f
, gcy
, gcx
* 0.9f
+ gcox
* 0.1f
, gcy
, gcx
, gcy
);
5319 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5321 CGContextAddCurveToPoint(cgc
, gcox
* 0.6667f
+ gcx
* 0.3333f
, gcoy
, gcox
* 0.3333f
+ gcx
* 0.6667f
, gcoy
, gcx
, gcy
);
5323 CGContextAddCurveToPoint(cgc
, gcx
* 0.3333f
+ gcox
* 0.6667f
, gcy
, gcx
* 0.6667f
+ gcox
* 0.3333f
, gcy
, gcx
, gcy
);
5331 numConnection
= envobj
->mNumConnection
;
5333 for(int j
= 0; j
< numConnection
; j
++){
5334 float gcx
, gcy
, gcox
, gcoy
, curve
;
5335 num
= (int) (envobj
->mConnections
[j
]);
5336 SCEnvObject
* conObj
= (mEnvObj
+ num
);
5337 curve
= conObj
->curve
;
5338 // post("shape at num: %i, is: %i\n", num, conObj->shape);
5339 gcox
= envobj
->mDrawPoint.x
;
5340 gcoy
= envobj
->mDrawPoint.y
;
5341 gcx
= conObj
->mDrawPoint.x
;
5342 gcy
= conObj
->mDrawPoint.y
;
5344 switch(conObj
->shape
){
5346 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5347 CGContextAddLineToPoint(cgc
, gcox
, gcy
);
5348 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
5351 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5352 CGContextAddLineToPoint(cgc
, gcx
, gcy
);
5355 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5356 CGContextAddCurveToPoint(cgc
, gcox
* EXPM1R
+ gcx
* EXPM1
, gcox
, gcox
* EXPM1
+ gcx
* EXPM1R
, gcy
, gcx
, gcy
);
5359 case shape_Exponential
:
5360 float dur
, numpointsY
, yLevel
, pos
;
5361 float begTime
, endTime
, begLevel
, endLevel
, stepsize
, ar
, br
, yrange
;
5363 float startPointX
, endPointX
, startPointY
, endPointY
;
5365 if(conObj
->x
<= envobj
->x
)
5373 begTime
= conObj
->x
;
5374 begLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5376 endTime
= envobj
->x
;
5377 endLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5386 begTime
= envobj
->x
;
5387 begLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5389 endTime
= conObj
->x
;
5390 endLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5393 numsteps
= (int) endPointX
- startPointX
;
5394 dur
= endTime
- begTime
;
5395 stepsize
= dur
/numsteps
;
5396 CGContextMoveToPoint(cgc
, startPointX
, startPointY
);
5398 for(int i
=1; i
<=numsteps
+1; i
++){
5399 double step
= sc_clip((i
*stepsize
), 0.0, dur
); // need to clip when here when clipping endLevel or begLevel
5400 double pos
= step
/ dur
;
5401 yLevel
= begLevel
* pow(endLevel
/ begLevel
, pos
);
5402 CGContextAddLineToPoint(cgc
, linlinNoClip((i
*stepsize
), 0.f
, dur
, startPointX
, endPointX
), linlinNoClip(yLevel
, begLevel
, endLevel
, startPointY
, endPointY
));
5404 CGContextAddLineToPoint(cgc
, endPointX
, endPointY
);
5410 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5412 CGContextAddCurveToPoint(cgc
, gcox
* 0.556f
+ gcx
* 0.444f
, gcoy
* 0.278f
+ gcy
* 0.722f
, gcox
* 0.29f
+ gcx
* 0.71f
, gcy
, gcx
, gcy
);
5414 CGContextAddCurveToPoint(cgc
, gcx
* 0.29f
+ gcox
* 0.71f
, gcoy
, gcx
* 0.556f
+ gcox
* 0.444f
, gcy
* 0.278f
+ gcoy
* 0.722f
, gcx
, gcy
);
5419 if(conObj
->x
<= envobj
->x
)
5427 begTime
= conObj
->x
;
5428 begLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5430 endTime
= envobj
->x
;
5431 endLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5440 begTime
= envobj
->x
;
5441 begLevel
= sc_clip(envobj
->y
, 0.000001f
, 1.f
);
5443 endTime
= conObj
->x
;
5444 endLevel
= sc_clip(conObj
->y
, 0.000001f
, 1.f
);
5447 numsteps
= (int) endPointX
- startPointX
;
5448 dur
= endTime
- begTime
;
5449 stepsize
= dur
/numsteps
;
5450 CGContextMoveToPoint(cgc
, startPointX
, startPointY
);
5452 for(int i
=1; i
<=numsteps
+1; i
++){
5453 double step
= sc_clip((i
*stepsize
), 0.0, dur
); // need to clip when here when clipping endLevel or begLevel
5454 double pos
= step
/ dur
;
5455 if (fabs(curve
) < 0.0001) {
5456 yLevel
= pos
* (endLevel
- begLevel
) + begLevel
;
5458 double denom
= 1.
- exp(curve
);
5459 double numer
= 1.
- exp(pos
* curve
);
5460 yLevel
= begLevel
+ (endLevel
- begLevel
) * (numer
/denom
);
5463 CGContextAddLineToPoint(cgc
, linlinNoClip((i
*stepsize
), 0.f
, dur
, startPointX
, endPointX
), linlinNoClip(yLevel
, begLevel
, endLevel
, startPointY
, endPointY
));
5465 CGContextAddLineToPoint(cgc
, endPointX
, endPointY
);
5471 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5473 CGContextAddCurveToPoint(cgc
, gcox
* 0.9f
+ gcx
* 0.1f
, gcoy
, gcox
* 0.5f
+ gcx
* 0.5f
, gcoy
, gcx
, gcy
);
5475 CGContextAddCurveToPoint(cgc
, gcx
* 0.5f
+ gcox
* 0.5f
, gcy
, gcx
* 0.9f
+ gcox
* 0.1f
, gcy
, gcx
, gcy
);
5479 CGContextMoveToPoint(cgc
, gcox
, gcoy
);
5481 CGContextAddCurveToPoint(cgc
, gcox
* 0.6667f
+ gcx
* 0.3333f
, gcoy
, gcox
* 0.3333f
+ gcx
* 0.6667f
, gcoy
, gcx
, gcy
);
5483 CGContextAddCurveToPoint(cgc
, gcx
* 0.3333f
+ gcox
* 0.6667f
, gcy
, gcx
* 0.6667f
+ gcox
* 0.3333f
, gcy
, gcx
, gcy
);
5495 CGContextStrokePath(cgc
);
5497 ///////////////////////////draw rects
5498 if(mDrawRectsActive
)
5500 for(int i
= xstart
; i
< xpixels
; i
++){
5501 envobj
= &mEnvObj
[drawOrder
[i
]];
5502 drawRect
= SCtoCGRect(envobj
->mRect
);
5503 setEnvRect(envobj
->x
, envobj
->y
, envobj
);
5505 fillcolor
= envobj
->mColor
;
5506 CGContextSetRGBFillColor(cgc
, fillcolor.red
, fillcolor.green
, fillcolor.blue
, fillcolor.alpha
);
5507 CGContextFillRect (cgc
, drawRect
);
5508 if(envobj
->mRect.width
> 1.0 || envobj
->mRect.height
> 1.0)
5509 CGContextStrokeRect(cgc
,drawRect
);
5511 stringDrawCenteredInRect(envobj
->mString
, envobj
->mRect
, mFontName
, mFontSize
, mStrokeColor
);
5513 CGContextSetRGBFillColor(cgc
, mStrokeColor.red
, mStrokeColor.green
, mStrokeColor.blue
, mStrokeColor.alpha
);
5519 CGContextRestoreGState(cgc
);
5523 bool SCEnvelopeView
::setValue(SCEnvObject
* envob
, double xIn
, double yIn
, bool send
)
5525 bool changed
= true;
5526 // SCEnvObject * envob;
5527 //indx = sc_clip(indx, 0, mTabSize - 1);
5528 xIn
= sc_clip(xIn
, 0.
, 1.
);
5529 yIn
= sc_clip(yIn
, 0.
, 1.
);
5531 if(!envob
->mEditable
) return false;
5532 if (mStepSize
> 0.
) {
5533 xIn
= floor(xIn
* mStepScale
+ 0.5) * mStepSize
;
5534 yIn
= floor(yIn
* mStepScale
+ 0.5) * mStepSize
;
5536 //mCurrentIndex = indx;
5538 //envob = &mEnvObj[indx];
5539 //changed = valXIn != envob->x || valYIn != envob->y;
5540 setEnvRect(xIn
, yIn
, envob
);
5543 if (send
) sendMessage(s_doaction
, 0, 0, 0);
5548 void SCEnvelopeView
::setValueFromPoint(SCPoint where
)
5550 int indx
= mSelectedIndex
;
5551 float width
, height
;
5552 SCRect bounds
= getDrawBounds();
5554 width
= (mEnvObj
+ mSelectedIndex
)->mRect.width
;
5555 height
= (mEnvObj
+ mSelectedIndex
)->mRect.height
;
5556 double x
= (double) (where.x
- bounds.x
- 1 - width
/2) / (bounds.width
- width
- 2);
5557 double y
= (double) 1.0 - (where.y
- bounds.y
- 1 - height
/2) / (bounds.height
- height
- 2);
5559 setValue(mEnvObj
+ mSelectedIndex
, x
, y
, true);
5565 bool SCEnvelopeView
::setEnvRect(double valXIn
, double valYIn
, SCEnvObject
* envobIn
)
5567 double x
,y
, thumbx
, thumby
;
5568 SCEnvObject
* envob
= envobIn
;
5571 thumby
= envob
->mRect.height
;
5572 thumbx
= envob
->mRect.width
;
5573 SCRect bounds
= getDrawBounds();
5575 x
= valXIn
* (bounds.width
- thumbx
- 2);
5576 y
= valYIn
* (bounds.height
- thumby
- 2);
5577 y
= bounds.y
+ bounds.height
- y
- 1 - thumby
;
5578 x
= bounds.x
+ x
+ 1;
5580 envob
->mRect
= SCMakeRect( x
, y
, thumbx
, thumby
);
5581 envob
->mDrawPoint.x
= x
+ (envob
->mRect.width
* 0.5);
5582 envob
->mDrawPoint.y
= y
+ (envob
->mRect.height
* 0.5);
5583 //envob->mIsVisible = true;
5584 // if(! envob->mObjectColor == NULL) envob->mObjectColor = mFillColor;
5585 // envob->mColor = envob->mObjectColor;
5587 // return SCMakeRect( x, y, thumbx, thumby);
5590 void SCEnvelopeView
::setSelection(SCPoint where
, bool fixed
, bool checkForConnection
)
5595 mMousePoint
= where
;
5596 if(mSelectedIndex
>= 0 && !mIsFixedSelection
){
5597 (mEnvObj
+ mSelectedIndex
)->mIsSelected
= false;
5598 (mEnvObj
+ mSelectedIndex
)->mColor
=(&mEnvObj
[mSelectedIndex
])->mObjectColor
;
5599 mSelectedIndex
= -1;
5600 if(fixed
) mIsFixedSelection
= false;
5605 for(int count
=mActiveSize
- 1; count
>=0; count
--) {
5606 int i
= drawOrder
[count
];
5607 envo
= &mEnvObj
[i
]; // check in reverse drawOrder so that 'on top' gets selected first
5608 sel
= SCPointInRect(where
, envo
->mRect
);
5609 // post("in SCEnvelopeView::setSelection: where.x %f, where.y %f, sel %i\n", where.x, where.y, (int) sel);
5611 // toggle fixed selection
5612 if(envo
->mIsSelected
&& mIsFixedSelection
){
5613 // post("toggle\n");
5615 envo
->mIsSelected
= false;
5616 envo
->mColor
= envo
->mObjectColor
;
5617 mSelectedIndex
= -1;
5618 mIsFixedSelection
= false;
5621 envo
->mIsSelected
= true;
5622 envo
->mColor
= mSelectedColor
;
5625 if(fixed
) mIsFixedSelection
= true;
5626 int newdrawOrder
[mActiveSize
];
5628 newdrawOrder
[mActiveSize
- 1] = i
;
5630 while (j
< mActiveSize
) {
5631 if(drawOrder
[j
] != i
) {
5632 newdrawOrder
[k
] = drawOrder
[j
];
5637 memcpy(drawOrder
, newdrawOrder
, mActiveSize
* sizeof(int));
5645 (&mEnvObj[mSelectedIndex])->mIsSelected = false;
5646 (&mEnvObj[mSelectedIndex])->mColor = mFillColor;
5647 mSelectedIndex = -1;
5653 void SCEnvelopeView
::mouseDownAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
5655 mouseTrack(where
, modifiers
,theEvent
);
5656 SCView
::mouseDownAction(where
, modifiers
, theEvent
);
5659 void SCEnvelopeView
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
){
5660 // sendMessage(getsym("mouseEndTrack"), 0, 0, 0);
5661 // if (modifiers & NSShiftKeyMask) {
5662 // mouseTrack(where, modifiers,theEvent);
5664 if(!mIsFixedSelection
){
5665 if(mSelectedIndex
>= 0){
5666 (&mEnvObj
[mSelectedIndex
])->mIsSelected
= false;
5667 (&mEnvObj
[mSelectedIndex
])->mColor
= (&mEnvObj
[mSelectedIndex
])->mObjectColor
;
5668 mSelectedIndex
= -1;
5673 if(mSelectedIndex
>= 0)
5674 setValueFromPoint(where
);
5676 mIsTracking
= false;
5677 // mouseTrack(where, modifiers);
5679 void SCEnvelopeView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
5681 //mPrevPoint = where;
5682 //mouseTrack(where, modifiers,theEvent);
5686 void SCEnvelopeView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
5688 if (modifiers
& NSCommandKeyMask
) {
5690 } else if (modifiers
& NSShiftKeyMask
) {
5692 setSelection(where
, true, false);
5694 if(mActiveSize < mTabSize) {
5695 mSelectedIndex = mActiveSize - 1;
5696 mEnvObj[mSelectedIndex].mIsSelected = true;
5697 mEnvObj[mSelectedIndex].mIsStatic = false;
5699 mActiveSize = mTabSize;
5704 // setValueFromPoint(where);
5705 sendMessage(getsym("doAction"), 0, 0, 0);
5706 } else if (modifiers
& NSControlKeyMask
) {
5707 mAbsoluteX
= where.x
; //absolute y mouse position
5708 setSelection(where
, false, true);
5709 sendMessage(getsym("doMetaAction"), 0, 0, 0);
5712 if(!mIsFixedSelection
&& mSelectedIndex
< 0)
5713 setSelection(where
, false, false);
5715 if(mSelectedIndex
>= 0) {
5718 SCEnvObject selected
= mEnvObj
[mSelectedIndex
];
5719 trackOffset
= SCMakePoint(selected.mDrawPoint.x
- where.x
, selected.mDrawPoint.y
- where.y
);
5721 SCPoint location
= SCMakePoint(trackOffset.x
+ where.x
, trackOffset.y
+ where.y
);
5722 setValueFromPoint(location
);
5729 void SCEnvelopeView::setVisibleSize()
5735 if(mThumbSize > 0.0) {
5736 if(mXOffset < 1.0) offset = 0;
5737 else offset = mXOffset;
5738 scaledsize = (float) (mTabSize - mStartIndex) * mThumbSize;
5739 if (scaledsize <= mBounds.width) mVisibleSize = mTabSize;
5740 else mVisibleSize = (int) mBounds.width / mThumbSize;
5745 mVisibleSize = mActiveSize;
5749 int SCEnvelopeView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
5752 char *name
= symbol
->name
;
5753 if (strcmp(name
, "step")==0) {
5754 err
= slotDoubleVal(slot
, &mStepSize
);
5756 mStepScale
= 1.
/ mStepSize
;
5757 bool changed
= false;
5758 bool changedout
= false;
5760 SCEnvObject
* envob
;
5761 for(int i
=0; i
<mTabSize
; ++i
){
5763 changed
= setValue(envob
,envob
->x
,envob
->y
, false);
5764 if(changed
) changedout
= changed
;
5766 if(changedout
) refresh();
5767 SetBool(slot
, changedout
);
5772 if (strcmp(name
, "thumbSize")==0) {
5773 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5774 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5776 err
= slotIntVal(slots
+0, &idx
);
5777 if (err
) return err
;
5778 err
= slotIntVal(slots
+1, &mThumbSize
);
5779 mThumbSizeY
= mThumbSize
;
5780 if (err
) return err
;
5781 if(idx
>= mTabSize
) return errNone
;
5783 for(int i
=0; i
<mTabSize
; i
++){
5784 (mEnvObj
+i
)->mRect.width
= mThumbSize
;
5785 (mEnvObj
+i
)->mRect.height
= mThumbSize
;
5788 (mEnvObj
+idx
)->mRect.width
= mThumbSize
;
5789 (mEnvObj
+idx
)->mRect.height
= mThumbSize
;
5795 if (strcmp(name
, "thumbWidth")==0) {
5796 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5797 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5799 err
= slotIntVal(slots
+0, &idx
);
5800 if (err
) return err
;
5801 err
= slotIntVal(slots
+1, &mThumbSize
);
5802 if (err
) return err
;
5803 if(idx
>= mTabSize
) return errNone
;
5805 for(int i
=0; i
<mTabSize
; i
++){
5806 (mEnvObj
+i
)->mRect.width
= mThumbSize
;
5810 (&mEnvObj
[idx
])->mRect.width
= mThumbSize
;
5815 if (strcmp(name
, "thumbHeight")==0) {
5816 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5817 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5819 err
= slotIntVal(slots
+0, &idx
);
5820 if (err
) return err
;
5821 err
= slotIntVal(slots
+1, &mThumbSizeY
);
5822 if (err
) return err
;
5823 if(idx
>= mTabSize
) return errNone
;
5825 for(int i
=0; i
<mTabSize
; i
++){
5826 (mEnvObj
+i
)->mRect.height
= mThumbSizeY
;
5830 (&mEnvObj
[idx
])->mRect.height
= mThumbSizeY
;
5835 if (strcmp(name
, "selectedIndex")==0) {
5838 obj
= mEnvObj
+mSelectedIndex
;
5839 err
= slotIntVal(slot
, &newSelection
);
5841 if(mSelectedIndex
== newSelection
) return errNone
;
5843 if(mSelectedIndex
>= 0) obj
->mColor
= obj
->mObjectColor
;
5844 mSelectedIndex
= sc_clip(newSelection
, -1, mTabSize
-1);
5845 if(mSelectedIndex
>= 0)
5847 obj
= mEnvObj
+mSelectedIndex
;
5848 obj
->mColor
= mSelectedColor
;
5857 if (strcmp(name
, "setFixedSelection")==0) {
5858 mIsFixedSelection
= IsTrue(slot
);
5862 if (strcmp(name
, "setIndex")==0) { //index selection without refresh() and color change.
5863 err
= slotIntVal(slot
, &mSelectedIndex
);
5864 if(mSelectedIndex
>= 0)
5865 mSelectedIndex
= sc_clip(mSelectedIndex
, 0, mTabSize
-1);
5868 if (strcmp(name
, "connect")==0) { //if this is set all connection start in the middle of the rect
5870 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5871 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5874 err
= slotIntVal(slots
+0, &idx
);
5875 if (err
) return err
;
5876 if(idx
>= mTabSize || idx
< 0) return errIndexOutOfRange
;
5877 SCEnvObject
* envobj
;
5878 PyrSlot
*connections
;
5879 connections
= slots
+1;
5880 if (!isKindOfSlot(connections
, class_array
)) return errWrongType
;
5882 envobj
= (mEnvObj
+ idx
);
5883 err
= allocSlotDoubleArrayVal(connections
, &envobj
->mConnections
);
5884 //err = allocSlotIntArrayVal(slot, &(&mEnvObj[mSelectedIndex])->mConnections); //int array crashes sc
5885 envobj
->mNumConnection
= slotRawObject(connections
)->size
;
5886 // envobj->deltax = 0;
5887 // envobj->mConnectionInputs = 0;
5888 // envobj->mConnectionOutputs = 0;
5889 mDrawCenteredConnection
= true;
5895 if (strcmp(name
, "fillColor")==0) {
5896 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5897 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5900 err
= slotIntVal(slots
+0, &idx
);
5901 if (err
) return err
;
5902 if(idx
>= mTabSize
) return errIndexOutOfRange
;
5903 err
= slotColorVal(slot
+1, &mFillColor
);
5904 if (err
) return err
;
5907 for(int i
=0; i
<mTabSize
; i
++){
5908 (mEnvObj
+i
)->mColor
= (mEnvObj
+i
)->mObjectColor
= mFillColor
;
5912 (mEnvObj
+idx
)->mColor
= (mEnvObj
+idx
)->mObjectColor
= mFillColor
;
5917 if (strcmp(name
, "strokeColor")==0) {
5918 err
= slotColorVal(slot
, &mStrokeColor
);
5922 if (strcmp(name
, "selectionColor")==0) {
5923 err
= slotColorVal(slot
, &mSelectedColor
);
5928 if (strcmp(name
, "startIndex")==0) {
5929 err
= slotIntVal(slot
, &mStartIndex
);
5933 if (strcmp(name
, "editable")==0) {
5934 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5935 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5937 int err
, idx
, editable
;
5938 err
= slotIntVal(slots
+0, &idx
);
5939 if (err
) return err
;
5940 if(idx
>= mTabSize
) return errIndexOutOfRange
;
5941 editable
= IsTrue(slots
+1);
5943 for(int i
=0; i
<mTabSize
; i
++){
5944 (mEnvObj
+ i
)->mEditable
= editable
;
5948 (mEnvObj
+ idx
)->mEditable
= editable
;
5951 if (strcmp(name
, "drawLines")==0) {
5952 mDrawLinesActive
= IsTrue(slot
);
5956 if (strcmp(name
, "drawRects")==0) {
5957 mDrawRectsActive
= IsTrue(slot
);
5961 if (strcmp(name
, "string")==0) {
5962 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
5963 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
5966 err
= slotIntVal(slots
+0, &idx
);
5967 if (err
) return err
;
5968 if(idx
>= mTabSize || idx
< 0) return errIndexOutOfRange
;
5969 PyrSlot
*string
= slots
+1;
5971 err
= allocSlotStrVal(string
, &(&mEnvObj
[idx
])->mString
);
5972 if (err
) return err
;
5977 if (symbol
== s_x
) {
5979 slotDoubleVal(slot
, &mCurrentX
);
5980 mCurrentX
= sc_clip(mCurrentX
, 0.0, 1.0);
5981 if(mSelectedIndex
>= 0){
5982 y
= (&mEnvObj
[mSelectedIndex
])->y
;
5983 setEnvRect(mCurrentX
, y
,&mEnvObj
[mSelectedIndex
]);
5988 if (symbol
== s_y
) {
5990 slotDoubleVal(slot
, &mCurrentY
);
5991 mCurrentY
= sc_clip(mCurrentY
, 0.0, 1.0);
5992 if(mSelectedIndex
>= 0){
5993 x
= (&mEnvObj
[mSelectedIndex
])->x
;
5994 setEnvRect(x
, mCurrentY
, &mEnvObj
[mSelectedIndex
]);
5999 if (symbol
== s_value
) {
6000 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
6001 if (!isKindOfSlot(slotRawObject(slot
)->slots
+0, class_array
)) return errWrongType
;
6002 if (!isKindOfSlot(slotRawObject(slot
)->slots
+1, class_array
)) return errWrongType
;
6004 int size
= slotRawObject(&(slotRawObject(slot
)->slots
[0]))->size
;
6005 if(size
!= mTabSize
) {
6006 // initialise drawing order
6008 delete [] drawOrder
;
6012 drawOrder
= new int[size
];
6013 for(int i
=0; i
<size
; i
++){
6017 //this should keep the settings of the old ones ... maybe make a separate add action ...
6018 err
= allocSlotEnvObjArray(slot
, &mEnvObj
);
6022 //move this to allocslotEnvobjArray:
6024 PyrDoubleArray
* xarr
;
6025 PyrDoubleArray
* yarr
;
6026 xarr
= (PyrDoubleArray
*)(slotRawObject(&slotRawObject(slot
)->slots
[0]));
6027 yarr
= (PyrDoubleArray
*)(slotRawObject(&slotRawObject(slot
)->slots
[1]));
6028 SCEnvObject
* envob
;
6029 for(int i
=0; i
<size
; i
++){
6033 setValue(envob
,x
,y
, false);
6034 //post("set x: %f ,y: %f \n", x, y);
6045 if (strcmp(name, "connectFrom")==0) {
6046 err = slotIntVal(slot, &mConnectFrom);
6049 if (strcmp(name, "connectTo")==0) {
6050 err = slotIntVal(slot, &mConnectTo);
6054 if (strcmp(name
, "setGraphView")==0) {
6055 mDrawCenteredConnection
= false;
6059 // set curve for one segment or one curve type for all segments
6060 if (strcmp(name
, "setCurve")==0) {
6061 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
6062 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
6063 int err
, idx
, curve
, shape
;
6065 err
= slotIntVal(slots
+0, &idx
);
6066 if (err
) return err
;
6068 err
= slotIntVal(slots
+1, &shape
);
6069 if (err
) return err
;
6071 err
= slotIntVal(slots
+2, &curve
);
6072 if (err
) return err
;
6074 if(idx
>= mTabSize
) return errNone
;
6076 for(int i
=0; i
<mTabSize
; i
++){
6077 (mEnvObj
+i
)->shape
= shape
;
6078 (mEnvObj
+i
)->curve
= curve
;
6081 (mEnvObj
+idx
)->shape
= shape
;
6082 (mEnvObj
+idx
)->curve
= curve
;
6088 // set curves for all segments
6089 if (strcmp(name
, "setCurves")==0) {
6090 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
6091 int size
= slotRawObject(slot
)->size
;
6092 size
= sc_clip(size
, 0, mTabSize
);
6093 for(int i
=0; i
<size
; i
++)
6095 PyrSlot
* shapeCurveSlot
= slotRawObject(slot
)->slots
+i
;
6098 if(isKindOfSlot(shapeCurveSlot
, class_array
))
6100 int err
= slotIntVal(slotRawObject(shapeCurveSlot
)->slots
+0, &shape
);
6101 if (err
) return err
;
6102 err
= slotFloatVal(slotRawObject(shapeCurveSlot
)->slots
+1, &curve
);
6103 if (err
) return err
;
6104 (mEnvObj
+i
)->shape
= shape
;
6105 (mEnvObj
+i
)->curve
= curve
;
6112 if (strcmp(name
, "showGrid")==0) {
6113 mGridOn
= IsTrue(slot
);
6118 if (strcmp(name
, "setGrid")==0) {
6119 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
6120 err
= slotFloatVal(slotRawObject(slot
)->slots
+0, &mGrid.x
);
6121 if (err
) return err
;
6122 err
= slotFloatVal(slotRawObject(slot
)->slots
+1, &mGrid.y
);
6123 if(mGridOn
) refresh();
6127 if (strcmp(name
, "setGridColor")==0) {
6128 err
= slotColorVal(slot
, &mGridColor
);
6129 if(mGridOn
) refresh();
6133 if (strcmp(name, "selectionSize")==0) {
6134 slotIntVal(slot, &mSelectionSize);
6140 return SCView
::setProperty(symbol
, slot
);
6143 int SCEnvelopeView
::getProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
6146 char *name
= symbol
->name
;
6147 if (strcmp(name
, "step")==0) {
6148 SetFloat(slot
, mStepSize
);
6152 if (symbol
== s_x
) {
6153 if(mSelectedIndex
>= 0){
6154 SetFloat(slot
, mCurrentX
);
6160 if (symbol
== s_y
) {
6161 if(mSelectedIndex
>= 0){
6162 SetFloat(slot
, mCurrentY
);
6168 if (strcmp(name
, "selectedIndex")==0) {
6169 SetInt(slot
, (int) mSelectedIndex
);
6172 if (strcmp(name
, "lastIndex")==0) {
6173 SetInt(slot
, (int) mLastIndex
);
6177 if (symbol
== s_value
) {
6178 if (!isKindOfSlot(slot
, class_array
)) return errWrongType
;
6179 int size
= slotRawObject(&(slotRawObject(slot
)->slots
[0]))->size
;
6181 if(size
> mTabSize
) size
= mTabSize
;
6183 PyrDoubleArray
* xarr
;
6184 PyrDoubleArray
* yarr
;
6185 xarr
= (PyrDoubleArray
*)(slotRawObject(&slotRawObject(slot
)->slots
[0]));
6186 yarr
= (PyrDoubleArray
*)(slotRawObject(&slotRawObject(slot
)->slots
[1]));
6188 for(int i
=0; i
<size
; i
++){
6190 xarr
->d
[i
] = envo
->x
;
6191 yarr
->d
[i
] = envo
->y
;
6196 if (strcmp(name, "selectionSize")==0) {
6197 SetInt(slot, mSelectionSize);
6201 if (strcmp(name
, "absoluteX")==0) {
6202 SetInt(slot
, (int) mAbsoluteX
);
6206 if (strcmp(name, "connectFrom")==0) {
6207 SetInt(slot, (int) mConnectFrom);
6210 if (strcmp(name, "connectTo")==0) {
6211 SetInt(slot, (int) mConnectTo);
6215 return SCView
::getProperty(symbol
, slot
);
6218 bool SCEnvelopeView
::canReceiveDrag()
6221 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
6222 return IsTrue(&result
);
6225 void SCEnvelopeView
::receiveDrag()
6227 sendMessage(s_receiveDrag
, 0, 0, 0);
6231 ////////////////////////////////////////////////
6233 SCView
* NewSCNumberBoxOld(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6235 return new SCNumberBoxOld(inParent
, inObj
, inBounds
);
6238 SCNumberBoxOld
::SCNumberBoxOld(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6239 : SCStaticText(inParent
, inObj
, inBounds
)
6241 mBackground
= new SolidColorBackground(SCMakeColor(1.0,1.0,1.0, 1.0)); // default is white
6246 SCNumberBoxOld
::~
SCNumberBoxOld()
6250 bool SCNumberBoxOld
::shouldDim()
6255 void SCNumberBoxOld
::draw(SCRect inDamage
)
6257 SCView
::draw(inDamage
);
6258 SCRect bounds
= getDrawBounds();
6260 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
6261 CGContextSaveGState(cgc
);
6262 CGRect rect
= SCtoCGRect(bounds
);
6263 if (mBackground
) mBackground
->draw(cgc
, rect
);
6265 QDDrawBevelRect(cgc
, rect
, 1, true);
6266 CGContextRestoreGState(cgc
);
6268 //drawBevelRect(SCtoQDRect(mBounds), 1, 1, SCtoQDColor(mBackColor), 2);
6269 SCRect sbounds
= bounds
;
6273 drawString(sbounds
);
6276 //int SCNumberBoxOld::setProperty(PyrSymbol *symbol, PyrSlot *slot)
6279 // char *name = symbol->name;
6280 // if (strcmp(name, "boxColor")==0) {
6281 // err = slotColorVal(slot, &mBoxColor);
6282 // if (err) return err;
6286 // return SCStaticText::setProperty(symbol, slot);
6289 void SCNumberBoxOld
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6291 if (modifiers
& NSCommandKeyMask
) {
6296 //int SCNumberBoxOld::getProperty(PyrSymbol *symbol, PyrSlot *slot)
6298 // char *name = symbol->name;
6299 // if (strcmp(name, "boxColor")==0) {
6300 // return setSlotColor(slot, &mBoxColor);
6302 // return SCStaticText::getProperty(symbol, slot);
6305 bool SCNumberBoxOld
::canReceiveDrag()
6308 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
6309 return IsTrue(&result
);
6312 void SCNumberBoxOld
::receiveDrag()
6314 sendMessage(s_receiveDrag
, 0, 0, 0);
6317 ////////////////////////////////////////////////
6320 SCView
* NewSCDragSource(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6322 return new SCDragSource(inParent
, inObj
, inBounds
);
6325 SCDragSource
::SCDragSource(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6326 : SCStaticText(inParent
, inObj
, inBounds
)
6331 SCDragSource
::~
SCDragSource()
6335 void SCDragSource
::draw(SCRect inDamage
)
6337 SCView
::draw(inDamage
);
6338 SCRect bounds
= getDrawBounds();
6340 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
6341 CGContextSaveGState(cgc
);
6342 CGRect rect
= SCtoCGRect(bounds
);
6343 if (mBackground
) mBackground
->draw(cgc
, rect
);
6344 QDDrawBevelRect(cgc
, rect
, 1, false);
6345 CGContextRestoreGState(cgc
);
6347 //drawBevelRect(SCtoQDRect(mBounds), 1, 0, SCtoQDColor(mBackColor), 2);
6351 bool SCDragSource
::shouldDim()
6356 int ivxSCDragSource_object
;
6358 void SCDragSource
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6363 ////////////////////////////////////////////////
6366 SCView
* NewSCDragSink(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6368 return new SCDragSink(inParent
, inObj
, inBounds
);
6371 SCDragSink
::SCDragSink(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6372 : SCStaticText(inParent
, inObj
, inBounds
)
6377 SCDragSink
::~
SCDragSink()
6381 void SCDragSink
::draw(SCRect inDamage
)
6383 SCView
::draw(inDamage
);
6384 SCRect bounds
= getDrawBounds();
6386 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
6387 CGContextSaveGState(cgc
);
6388 CGRect rect
= SCtoCGRect(bounds
);
6389 if (mBackground
) mBackground
->draw(cgc
, rect
);
6390 QDDrawBevelRect(cgc
, rect
, 1, true);
6391 CGContextRestoreGState(cgc
);
6393 //drawBevelRect(SCtoQDRect(mBounds), 1, 1, SCtoQDColor(mBackColor), 2);
6397 bool SCDragSink
::shouldDim()
6402 bool SCDragSink
::canReceiveDrag()
6405 sendMessage(s_canReceiveDrag
, 0, 0, &result
);
6406 return IsTrue(&result
);
6409 void SCDragSink
::receiveDrag()
6411 sendMessage(s_receiveDrag
, 0, 0, 0);
6414 ////////////////////////////////////////////////
6415 ////////////////////////////////////////////////
6418 SCView
* NewSCDragBoth(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6420 return new SCDragBoth(inParent
, inObj
, inBounds
);
6423 SCDragBoth
::SCDragBoth(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6424 : SCDragSink(inParent
, inObj
, inBounds
)
6428 void SCDragBoth
::draw(SCRect inDamage
)
6430 SCView
::draw(inDamage
);
6432 CGContextRef cgc
= (CGContextRef
)[[NSGraphicsContext currentContext
] graphicsPort
];
6433 CGContextSaveGState(cgc
);
6434 SCRect dbounds
= getDrawBounds();
6436 CGRect rect
= SCtoCGRect(dbounds
);
6437 if (mBackground
) mBackground
->draw(cgc
, rect
);
6438 QDDrawBevelRect(cgc
, rect
, 1, true);
6439 SCRect bounds
= dbounds
;
6440 bounds.x
+= 2; bounds.y
+= 2; bounds.width
-= 4; bounds.height
-= 4;
6441 QDDrawBevelRect(cgc
, SCtoCGRect(bounds
), 1, false);
6442 CGContextRestoreGState(cgc
);
6444 //drawBevelRect(SCtoQDRect(bounds), 1, 1, SCtoQDColor(mBackColor), 2);
6445 //SCRect bounds = bounds;
6446 //bounds.x += 2; bounds.y += 2; bounds.width -= 4; bounds.height -= 4;
6447 //drawBevelRect(SCtoQDRect(bounds), 1, 0, SCtoQDColor(mBackColor), 2);
6451 int ivxSCDragBoth_object
;
6453 void SCDragBoth
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6459 ////////////////////////////////////////////////
6460 #import "TabletEvents.h"
6462 SCView
* NewSCTabletView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6464 return new SCTabletView(inParent
, inObj
, inBounds
);
6467 SCTabletView
::SCTabletView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
)
6468 : SCView(inParent
, inObj
, inBounds
), mClipToBounds(1)
6472 SCTabletView
::~
SCTabletView()
6476 int SCTabletView
::setProperty(PyrSymbol
*symbol
, PyrSlot
*slot
)
6478 char *name
= symbol
->name
;
6479 if (strcmp(name
, "clipToBounds")==0) {
6480 slotIntVal(slot
, &mClipToBounds
);
6483 return SCView
::setProperty(symbol
, slot
);
6486 void SCTabletView
::mouseBeginTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6489 SCRect bounds
= getDrawBounds();
6491 if (modifiers
& NSCommandKeyMask
) {
6494 x
= where.x
- bounds.x
;
6495 y
= where.y
- bounds.y
;
6497 x
= sc_clip(x
,0.
,bounds.width
);
6498 y
= sc_clip(y
,0.
,bounds.height
);
6500 TABLETTRACK(s_mouseDown
,x
,y
)
6504 void SCTabletView
::mouseTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6507 SCRect bounds
= getDrawBounds();
6509 if (! (modifiers
& NSCommandKeyMask
)) {
6510 x
= where.x
- bounds.x
;
6511 y
= where.y
- bounds.y
;
6513 x
= sc_clip(x
,0.
,bounds.width
);
6514 y
= sc_clip(y
,0.
,bounds.height
);
6516 TABLETTRACK(s_doaction
,x
,y
)
6520 void SCTabletView
::mouseEndTrack(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6523 if (modifiers
& NSCommandKeyMask
) {
6524 this->receiveDrag();
6526 SCRect bounds
= getDrawBounds();
6528 x
= where.x
- bounds.x
;
6529 y
= where.y
- bounds.y
;
6531 x
= sc_clip(x
,0.
,bounds.width
);
6532 y
= sc_clip(y
,0.
,bounds.height
);
6534 TABLETTRACK(s_mouseUp
,x
,y
)
6538 void SCTabletView
::mouseDownAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6542 void SCTabletView
::mouseMoveAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6546 void SCTabletView
::mouseUpAction(SCPoint where
, int modifiers
, NSEvent
*theEvent
)
6551 ////////////////////////////////////////////////
6553 SCViewMaker
::SCViewMaker(const char* inName
, SCViewCtor inCtor
)
6554 : mNext(gSCViewMakers
), mCtor(inCtor
), mName(inName
)
6556 gSCViewMakers
= this;
6559 SCView
* MakeSCView(PyrObject
* inObj
, SCContainerView
*inParent
, SCRect inBounds
,const char *classname
)
6561 SCViewMaker
* maker
= gSCViewMakers
;
6563 if (strcmp(classname
, maker
->mName
) == 0) {
6564 return (maker
->mCtor
)(inParent
, inObj
, inBounds
);
6566 maker
= maker
->mNext
;
6571 static bool sRegisteredSCViewClasses
= false;
6572 extern SCView
* NewSCSoundFileView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6573 extern SCView
* NewSCCocoaTextView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6574 extern SCView
* NewSCMovieView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6575 extern SCView
* NewSCQuartzComposerView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6576 extern SCView
* NewSCWebView(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6577 extern SCView
* NewSCTextField(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6578 extern SCView
* NewSCNumberBox(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6579 extern SCView
* NewSCLevelIndicator(SCContainerView
*inParent
, PyrObject
* inObj
, SCRect inBounds
);
6581 void registerSCViewClasses()
6583 if (sRegisteredSCViewClasses
) return;
6584 sRegisteredSCViewClasses
= true;
6586 new SCViewMaker("SCTopView", NewSCTopView
);
6587 new SCViewMaker("SCCompositeView", NewSCCompositeView
);
6588 new SCViewMaker("SCHLayoutView", NewSCHLayoutView
);
6589 new SCViewMaker("SCVLayoutView", NewSCVLayoutView
);
6590 new SCViewMaker("SCSlider", NewSCSlider
);
6591 new SCViewMaker("SCRangeSlider", NewSCRangeSlider
);
6592 new SCViewMaker("SC2DSlider", NewSC2DSlider
);
6593 new SCViewMaker("SC2DTabletSlider", NewSC2DTabletSlider
);
6594 new SCViewMaker("SCButton", NewSCButton
);
6595 new SCViewMaker("SCStaticText", NewSCStaticText
);
6596 new SCViewMaker("SCNumberBoxOld", NewSCNumberBoxOld
);
6597 new SCViewMaker("SCDragSource", NewSCDragSource
);
6598 new SCViewMaker("SCDragSink", NewSCDragSink
);
6599 new SCViewMaker("SCDragBoth", NewSCDragBoth
);
6600 new SCViewMaker("SCUserView", NewSCUserView
);
6601 new SCViewMaker("SCPopUpMenu", NewSCPopUpMenu
);
6602 new SCViewMaker("SCMultiSliderView", NewSCMultiSliderView
);
6603 new SCViewMaker("SCEnvelopeView", NewSCEnvelopeView
);
6604 new SCViewMaker("SCTabletView", NewSCTabletView
);
6605 new SCViewMaker("SCScope", NewSCScope
);
6606 new SCViewMaker("SCListView", NewSCListView
);
6607 new SCViewMaker("SCSoundFileView", NewSCSoundFileView
);
6608 //these can be found in SCCocoaView.M
6609 new SCViewMaker("SCTextView", NewSCCocoaTextView
);
6610 new SCViewMaker("SCMovieView", NewSCMovieView
);
6611 new SCViewMaker("SCQuartzComposerView", NewSCQuartzComposerView
);
6612 new SCViewMaker("SCWebView", NewSCWebView
);
6613 new SCViewMaker("SCTextField", NewSCTextField
);
6614 new SCViewMaker("SCNumberBox", NewSCNumberBox
);
6615 new SCViewMaker("SCScrollTopView", NewSCScrollTopView
);
6616 new SCViewMaker("SCScrollView", NewSCScrollView
);
6617 new SCViewMaker("SCLevelIndicator", NewSCLevelIndicator
);
6622 int prSCView_New(struct VMGlobals
*g
, int numArgsPushed
);
6623 int prSCView_New(struct VMGlobals
*g
, int numArgsPushed
)
6625 if (!g
->canCallOS
) return errCantCallOS
;
6627 PyrSlot
*args
= g
->sp
- 3;
6628 // view, parent, bounds, viewclass
6630 SCContainerView
*parent
;
6631 if (isKindOfSlot(args
, s_sctopview
->u.classobj
) && !isKindOfSlot(args
, s_scscrollview
->u.classobj
)) {
6634 if (!isKindOfSlot(args
+1, s_sccontview
->u.classobj
)) return errWrongType
;
6635 // check if it still has a dataptr
6636 parentSlot
= slotRawObject(&args
[1])->slots
[0];
6637 if(IsNil(&parentSlot
)) return errFailed
;
6638 parent
= (SCContainerView
*)slotRawPtr(&parentSlot
);
6640 if (!(isKindOfSlot(args
+2, s_rect
->u.classobj
))) return errWrongType
;
6643 int err
= slotGetSCRect(args
+2, &bounds
);
6644 if (err
) return err
;
6645 SCView
*view
= MakeSCView(slotRawObject(&args
[0]), parent
, bounds
, slotRawSymbol(&slotRawClass(&args
[3])->name
)->name
);
6646 if (!view
) return errFailed
;
6651 int prSCView_SetProperty(struct VMGlobals
*g
, int numArgsPushed
);
6652 int prSCView_SetProperty(struct VMGlobals
*g
, int numArgsPushed
)
6654 if (!g
->canCallOS
) return errCantCallOS
;
6656 PyrSlot
*args
= g
->sp
- 2;
6658 if (!IsSym(args
+1)) return errWrongType
;
6660 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(&args
[0])->slots
);
6661 if (!view
) return errFailed
;
6663 int err
= view
->setProperty(slotRawSymbol(&args
[1]), args
+2);
6664 if (err
) SetNil(args
+2);
6666 slotCopy(&args
[0], &args
[2]);
6671 int prSCView_GetProperty(struct VMGlobals
*g
, int numArgsPushed
);
6672 int prSCView_GetProperty(struct VMGlobals
*g
, int numArgsPushed
)
6674 if (!g
->canCallOS
) return errCantCallOS
;
6676 PyrSlot
*args
= g
->sp
- 2;
6678 if (!IsSym(args
+1)) return errWrongType
;
6680 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(&args
[0])->slots
);
6681 if (!view
) return errFailed
;
6683 int err
= view
->getProperty(slotRawSymbol(&args
[1]), args
+2);
6684 if (err
) SetNil(args
+2);
6686 slotCopy(&args
[0], &args
[2]);
6691 int prSCView_FindByID(struct VMGlobals
*g
, int numArgsPushed
);
6692 int prSCView_FindByID(struct VMGlobals
*g
, int numArgsPushed
)
6694 if (!g
->canCallOS
) return errCantCallOS
;
6696 PyrSlot
*a
= g
->sp
- 1;
6699 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(a
)->slots
);
6700 if (!view
) return errFailed
;
6703 int err
= slotIntVal(b
, &tag
);
6704 if (err
) return err
;
6706 view
= view
->findViewByID(tag
);
6710 SetObjectOrNil(a
, view
->GetSCObj());
6716 int prSCView_Focus(struct VMGlobals
*g
, int numArgsPushed
);
6717 int prSCView_Focus(struct VMGlobals
*g
, int numArgsPushed
)
6719 if (!g
->canCallOS
) return errCantCallOS
;
6721 PyrSlot
*viewObjSlot
= g
->sp
- 1;
6722 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(&viewObjSlot
[0])->slots
);
6723 PyrSlot
*boo
= g
->sp
;
6725 if (!view
) return errFailed
;
6726 view
->makeFocus(IsTrue(boo
));
6730 int prSCView_HasFocus(struct VMGlobals
*g
, int numArgsPushed
);
6731 int prSCView_HasFocus(struct VMGlobals
*g
, int numArgsPushed
)
6733 if (!g
->canCallOS
) return errCantCallOS
;
6735 PyrSlot
*viewObjSlot
= g
->sp
;
6736 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(&viewObjSlot
[0])->slots
);
6738 if (!view
) return errFailed
;
6739 SetBool(viewObjSlot
, view
->isFocus());
6743 int prSCView_Refresh(struct VMGlobals
*g
, int numArgsPushed
);
6744 int prSCView_Refresh(struct VMGlobals
*g
, int numArgsPushed
)
6746 if (!g
->canCallOS
) return errCantCallOS
;
6748 if(::IsNil( slotRawObject(g
->sp
)->slots
+0 ))
6751 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(g
->sp
)->slots
);
6752 if(!view
) return errNone
;
6757 int prSCView_RefreshInRect(struct VMGlobals
*g
, int numArgsPushed
);
6758 int prSCView_RefreshInRect(struct VMGlobals
*g
, int numArgsPushed
)
6760 if (!g
->canCallOS
) return errCantCallOS
;
6762 if(::IsNil( slotRawObject(g
->sp
- 1)->slots
+0 ))
6766 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(g
->sp
- 1)->slots
);
6768 if(slotGetSCRect(g
->sp
, &r
) != noErr
)
6771 view
->refreshInRect(r
);
6775 int prSCView_Remove(struct VMGlobals
*g
, int numArgsPushed
);
6776 int prSCView_Remove(struct VMGlobals
*g
, int numArgsPushed
)
6778 //if (!g->canCallOS) return errCantCallOS;
6780 PyrSlot
*viewObjSlot
= g
->sp
;
6781 SCView
*view
= (SCView
*)slotRawPtr(slotRawObject(viewObjSlot
)->slots
);
6782 if (!view
) return errFailed
;
6784 // removes from parent, set mObj to nil
6789 void initSCViewPrimitives()
6792 registerSCViewClasses();
6798 s_lo
= getsym("lo");
6799 s_hi
= getsym("hi");
6800 s_range
= getsym("range");
6801 s_scview
= getsym("SCView");
6802 s_sccontview
= getsym("SCContainerView");
6803 s_sctopview
= getsym("SCTopView");
6804 s_scscrollview
= getsym("SCScrollView");
6805 s_beginDrag
= getsym("beginDrag");
6806 s_receiveDrag
= getsym("receiveDrag");
6807 s_canReceiveDrag
= getsym("canReceiveDrag");
6808 s_mouseDown
= getsym("mouseDown");
6809 s_mouseUp
= getsym("mouseUp");
6810 s_callDrawFunc
= getsym("callDrawFunc");
6811 s_toggleEditMode
= getsym("toggleEditMode");
6813 base
= nextPrimitiveIndex();
6816 definePrimitive(base
, index
++, "_SCView_New", prSCView_New
, 4, 0);
6817 definePrimitive(base
, index
++, "_SCView_SetProperty", prSCView_SetProperty
, 3, 0);
6818 definePrimitive(base
, index
++, "_SCView_GetProperty", prSCView_GetProperty
, 3, 0);
6819 definePrimitive(base
, index
++, "_SCView_FindByID", prSCView_FindByID
, 2, 0);
6820 definePrimitive(base
, index
++, "_SCView_Focus", prSCView_Focus
, 2, 0);
6821 definePrimitive(base
, index
++, "_SCView_HasFocus", prSCView_HasFocus
, 1, 0);
6822 definePrimitive(base
, index
++, "_SCView_Refresh", prSCView_Refresh
, 1, 0);
6823 definePrimitive(base
, index
++, "_SCView_Remove", prSCView_Remove
, 1, 0);
6824 definePrimitive(base
, index
++, "_SCView_RefreshInRect", prSCView_RefreshInRect
, 2, 0);
6827 int ivxSCTextView_linkAction
;
6832 ivxSCDragSource_object
= instVarOffset("SCDragSource", "object");
6833 ivxSCDragBoth_object
= instVarOffset("SCDragBoth", "object");
6834 ivxSCTextView_linkAction
= instVarOffset("SCTextView", "linkAction");
6842 background color / pic