This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2010-08-30 07:46:01

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

New Block Type Drawing Method

How would I make a drawing method for a block like this: https://sites.google.com/site/slashproj/CostumeBlock.gif?attredirects=0

Last edited by Billybob-Mario (2010-08-30 10:04:54)

Offline

 

#3 2010-08-30 09:22:41

Jwosty
Scratcher
Registered: 2009-12-19
Posts: 500+

Re: New Block Type Drawing Method

Sorry, I'm not sure what you mean. Could you explain a little better?


http://i39.tinypic.com/18ert5.png Google it.  smile

Offline

 

#4 2010-08-30 09:40:37

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: New Block Type Drawing Method

Just take reporterBlockMorph's and add another circle using the same algorithm it does.


nXIII

Offline

 

#5 2010-08-30 10:05:21

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

I'll try, but I'm not really sure how.

Edit: I looked, and it doesn't make much sense. To save time, I'll post it here.

Code:

 drawNumericOn: aCanvas 

    | right topY bottomY radius xInset c l t cArgs relevant |
    self computeHighlightColors.

    l _ OrderedCollection new.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self addHLineFrom: xInset to: right - xInset y: topY color: c to: l.
        (xInset > 0) & (topY > 1) ifTrue: [
            self addPoint: xInset@topY color: highlightColor1 to: l.
            self addPoint: (right - xInset - 1)@topY color: highlightColor1 to: l].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
        self addHLineFrom: xInset to: right - xInset y: bottomY color: c to: l.
        xInset > 0 ifTrue: [
            self addPoint: xInset@bottomY color: shadowColor to: l.
            self addPoint: (right - xInset - 1)@bottomY color: shadowColor to: l].

        bottomY _ bottomY + 1.
        topY _ topY - 1].
    
    cArgs _ self nonControlFlowSubmorphs select: [:s | 
        (s isKindOf: CArgSlotMorph) 
        or: [(s isKindOf: CReporterSlotMorph)
        or: [(s isKindOf: MultiArgMorph) 
            and: [#(loop reporterSlot) includes: s type]]]].

    cArgs isEmpty 
        ifFalse: [
            cArgs do: [:ca |
                relevant _ ca bounds.
                (ca isKindOf: MultiArgMorph) ifTrue: [
                    relevant _ ca transparentRect].
                t _ OrderedCollection new.
                l do: [:pair |
                    self addAreasOf: pair first outside: (relevant insetBy: 3) color: pair second to: t].
            l _ t]].
    
    l do: [:pair |
        aCanvas fillRectangle: pair first color: pair second ].

Last edited by Billybob-Mario (2010-08-30 10:10:28)

Offline

 

#6 2010-08-30 10:34:33

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: New Block Type Drawing Method

Billybob-Mario wrote:

I'll try, but I'm not really sure how.

Edit: I looked, and it doesn't make much sense. To save time, I'll post it here.

Code:

 drawNumericOn: aCanvas 

    | right topY bottomY radius xInset c l t cArgs relevant |
    self computeHighlightColors.

    l _ OrderedCollection new.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self addHLineFrom: xInset to: right - xInset y: topY color: c to: l.
        (xInset > 0) & (topY > 1) ifTrue: [
            self addPoint: xInset@topY color: highlightColor1 to: l.
            self addPoint: (right - xInset - 1)@topY color: highlightColor1 to: l].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
        self addHLineFrom: xInset to: right - xInset y: bottomY color: c to: l.
        xInset > 0 ifTrue: [
            self addPoint: xInset@bottomY color: shadowColor to: l.
            self addPoint: (right - xInset - 1)@bottomY color: shadowColor to: l].

        bottomY _ bottomY + 1.
        topY _ topY - 1].
    
    cArgs _ self nonControlFlowSubmorphs select: [:s | 
        (s isKindOf: CArgSlotMorph) 
        or: [(s isKindOf: CReporterSlotMorph)
        or: [(s isKindOf: MultiArgMorph) 
            and: [#(loop reporterSlot) includes: s type]]]].

    cArgs isEmpty 
        ifFalse: [
            cArgs do: [:ca |
                relevant _ ca bounds.
                (ca isKindOf: MultiArgMorph) ifTrue: [
                    relevant _ ca transparentRect].
                t _ OrderedCollection new.
                l do: [:pair |
                    self addAreasOf: pair first outside: (relevant insetBy: 3) color: pair second to: t].
            l _ t]].
    
    l do: [:pair |
        aCanvas fillRectangle: pair first color: pair second ].

It's made complicated by cArgs requiring their spaced to be filled.


nXIII

Offline

 

#7 2010-09-01 07:11:46

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

bump

Offline

 

#8 2010-09-01 15:32:37

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: New Block Type Drawing Method

nXIII wrote:

It's made complicated by cArgs requiring their spaced to be filled.

Er, rather, emptied...


nXIII

Offline

 

#9 2010-09-01 17:05:03

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

nXIII wrote:

nXIII wrote:

It's made complicated by cArgs requiring their spaced to be filled.

Er, rather, emptied...

So can I just get rid of the cArgs parts like this: (to make it simpler)

Code:

 drawNumericOn: aCanvas 

    | right topY bottomY radius xInset c l t relevant |
    self computeHighlightColors.

    l _ OrderedCollection new.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self addHLineFrom: xInset to: right - xInset y: topY color: c to: l.
        (xInset > 0) & (topY > 1) ifTrue: [
            self addPoint: xInset@topY color: highlightColor1 to: l.
            self addPoint: (right - xInset - 1)@topY color: highlightColor1 to: l].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
        self addHLineFrom: xInset to: right - xInset y: bottomY color: c to: l.
        xInset > 0 ifTrue: [
            self addPoint: xInset@bottomY color: shadowColor to: l.
            self addPoint: (right - xInset - 1)@bottomY color: shadowColor to: l].

        bottomY _ bottomY + 1.
        topY _ topY - 1].
    

            l _ t]].
    
    l do: [:pair |
        aCanvas fillRectangle: pair first color: pair second ].

Last edited by Billybob-Mario (2010-09-01 17:05:38)

Offline

 

#10 2010-09-01 17:11:09

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: New Block Type Drawing Method

Billybob-Mario wrote:

nXIII wrote:

nXIII wrote:

It's made complicated by cArgs requiring their spaced to be filled.

Er, rather, emptied...

So can I just get rid of the cArgs parts like this: (to make it simpler)

Code:

 drawNumericOn: aCanvas 

    | right topY bottomY radius xInset c l t relevant |
    self computeHighlightColors.

    l _ OrderedCollection new.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self addHLineFrom: xInset to: right - xInset y: topY color: c to: l.
        (xInset > 0) & (topY > 1) ifTrue: [
            self addPoint: xInset@topY color: highlightColor1 to: l.
            self addPoint: (right - xInset - 1)@topY color: highlightColor1 to: l].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
        self addHLineFrom: xInset to: right - xInset y: bottomY color: c to: l.
        xInset > 0 ifTrue: [
            self addPoint: xInset@bottomY color: shadowColor to: l.
            self addPoint: (right - xInset - 1)@bottomY color: shadowColor to: l].

        bottomY _ bottomY + 1.
        topY _ topY - 1].
    

            l _ t]].
    
    l do: [:pair |
        aCanvas fillRectangle: pair first color: pair second ].

no....


nXIII

Offline

 

#11 2010-09-01 17:15:16

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

I just can't figure out where to start.

Offline

 

#12 2010-09-02 05:35:28

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: New Block Type Drawing Method

Drawing method:

Code:

drawCostumeOn: aCanvas 

    | right topY bottomY radius xInset c knobbleInset |
    self computeHighlightColors.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    knobbleInset _ self height.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self drawHLineFrom: xInset to: knobbleInset - xInset y: topY color: c on: aCanvas.
        self drawHLineFrom: knobbleInset + xInset to: right - knobbleInset - xInset y: topY color: c on: aCanvas.
        self drawHLineFrom: right - knobbleInset + xInset to: right - xInset y: topY color: c on: aCanvas.
        (xInset > 0) & (topY > 1) ifTrue: [
            self drawPoint: xInset@topY color: highlightColor1 on: aCanvas.
            self drawPoint: (right - xInset - 1)@topY color: highlightColor1 on: aCanvas].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
self drawHLineFrom: xInset to: knobbleInset - xInset y: bottomY color: c on: aCanvas.
        self drawHLineFrom: knobbleInset + xInset to: right - knobbleInset - xInset y: bottomY color: c on: aCanvas.
        self drawHLineFrom: right - knobbleInset + xInset to: right - xInset y: bottomY color: c on: aCanvas.
        xInset > 0 ifTrue: [
            self drawPoint: xInset@bottomY color: shadowColor on: aCanvas.
            self drawPoint: (right - xInset - 1)@bottomY color: shadowColor on: aCanvas].

        bottomY _ bottomY + 1.
        topY _ topY - 1].

fixBlockLayout code:

Code:

fixBlockLayout
    "Update the positions of my submorphs."

    | mList maxH h x y |
    blockLayoutNeeded ifFalse: [^ self].
    cachedForm _ nil.
    cachedFeedbackForm _ nil.

    mList _ self nonControlFlowSubmorphs.
    maxH _ 0.
    mList do: [:m |
        (m isKindOf: ArgMorph) ifTrue: [m fixArgLayout].
        (m isKindOf: BlockMorph) ifTrue: [m fixBlockLayout].
        maxH _ maxH max: m height].
    h _ (maxH + 4) max: 17.

    x _ 22.
    (mList size > 0 and: [mList first isKindOf: StringMorph]) ifTrue: [x _ x + 2].

    mList do: [:m |
        (m isKindOf: StringMorph) ifTrue: [m color: self labelColor].
        y _ (h - m height) // 2.
        m position: self position + (x@y).
        x _ x + m width + 3].

    self extent: (x + 19) @ h.
    (self ownerThatIsA: ScratchBlockPaletteMorph) ifNotNil: [
        (self ownerThatIsA: ScratchBlockPaletteMorph) fixLayout].

You'll need to fix the highlighting/shadowing though. I haven't done that yet.

Last edited by TheSuccessor (2010-09-02 05:36:58)


/* No comment */

Offline

 

#13 2010-09-02 07:05:31

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

TheSuccessor wrote:

Drawing method:

Code:

drawCostumeOn: aCanvas 

    | right topY bottomY radius xInset c knobbleInset |
    self computeHighlightColors.

    right _ self width.
    topY _ bottomY _ radius _ self height // 2.
    knobbleInset _ self height.
    self height even ifTrue: [topY _ bottomY - 1].
    [topY >= 0] whileTrue: [
        xInset _ radius - (radius squared - (radius - topY - 1) squared) sqrt rounded.

        topY = 0 ifTrue: [c _ highlightColor1].
        topY = 1 ifTrue: [c _ highlightColor2].
        topY > 1 ifTrue: [c _ color].
        self drawHLineFrom: xInset to: knobbleInset - xInset y: topY color: c on: aCanvas.
        self drawHLineFrom: knobbleInset + xInset to: right - knobbleInset - xInset y: topY color: c on: aCanvas.
        self drawHLineFrom: right - knobbleInset + xInset to: right - xInset y: topY color: c on: aCanvas.
        (xInset > 0) & (topY > 1) ifTrue: [
            self drawPoint: xInset@topY color: highlightColor1 on: aCanvas.
            self drawPoint: (right - xInset - 1)@topY color: highlightColor1 on: aCanvas].

        c _ bottomY = (self height - 1) ifTrue: [shadowColor] ifFalse: [color].
self drawHLineFrom: xInset to: knobbleInset - xInset y: bottomY color: c on: aCanvas.
        self drawHLineFrom: knobbleInset + xInset to: right - knobbleInset - xInset y: bottomY color: c on: aCanvas.
        self drawHLineFrom: right - knobbleInset + xInset to: right - xInset y: bottomY color: c on: aCanvas.
        xInset > 0 ifTrue: [
            self drawPoint: xInset@bottomY color: shadowColor on: aCanvas.
            self drawPoint: (right - xInset - 1)@bottomY color: shadowColor on: aCanvas].

        bottomY _ bottomY + 1.
        topY _ topY - 1].

fixBlockLayout code:

Code:

fixBlockLayout
    "Update the positions of my submorphs."

    | mList maxH h x y |
    blockLayoutNeeded ifFalse: [^ self].
    cachedForm _ nil.
    cachedFeedbackForm _ nil.

    mList _ self nonControlFlowSubmorphs.
    maxH _ 0.
    mList do: [:m |
        (m isKindOf: ArgMorph) ifTrue: [m fixArgLayout].
        (m isKindOf: BlockMorph) ifTrue: [m fixBlockLayout].
        maxH _ maxH max: m height].
    h _ (maxH + 4) max: 17.

    x _ 22.
    (mList size > 0 and: [mList first isKindOf: StringMorph]) ifTrue: [x _ x + 2].

    mList do: [:m |
        (m isKindOf: StringMorph) ifTrue: [m color: self labelColor].
        y _ (h - m height) // 2.
        m position: self position + (x@y).
        x _ x + m width + 3].

    self extent: (x + 19) @ h.
    (self ownerThatIsA: ScratchBlockPaletteMorph) ifNotNil: [
        (self ownerThatIsA: ScratchBlockPaletteMorph) fixLayout].

You'll need to fix the highlighting/shadowing though. I haven't done that yet.

That looks good! How can I put the circles a bit closer to the main block?

Offline

 

#14 2010-09-03 12:10:51

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: New Block Type Drawing Method

In drawOn:...

Change: "knobbleInset _ self height" to: "knobbleInset _ self height - (an amount)"

Change: "self drawHLineFrom: xInset to: knobbleInset - xInset" to: "self drawHLineFrom: xInset to: knobbleInset - xInset + (the same amount)" (both occurences)

Change: "self drawHLineFrom: right - knobbleInset + xInset"  to: "self drawHLineFrom: right - knobbleInset + xInset - (the same amount again)" (both occurences)

In fixBlockLayout...

Change: "x _ 22" to: "x _ (whatever 22 - the same amount is)"

Change: "self extent: (x + 17) @ h" to: "self extent: (x + (whatever 17 - the same amount is)) @ h"

Last edited by TheSuccessor (2010-09-03 12:19:17)


/* No comment */

Offline

 

#15 2010-09-03 13:44:15

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

TheSuccessor wrote:

In drawOn:...

Change: "knobbleInset _ self height" to: "knobbleInset _ self height - (an amount)"

Change: "self drawHLineFrom: xInset to: knobbleInset - xInset" to: "self drawHLineFrom: xInset to: knobbleInset - xInset + (the same amount)" (both occurences)

Change: "self drawHLineFrom: right - knobbleInset + xInset"  to: "self drawHLineFrom: right - knobbleInset + xInset - (the same amount again)" (both occurences)

In fixBlockLayout...

Change: "x _ 22" to: "x _ (whatever 22 - the same amount is)"

Change: "self extent: (x + 17) @ h" to: "self extent: (x + (whatever 17 - the same amount is)) @ h"

I used 3 and it works. Thanks!

Offline

 

#16 2010-09-03 15:30:41

midnightleopard
Scratcher
Registered: 2007-09-13
Posts: 1000+

Re: New Block Type Drawing Method

woa! People actually have methods for drawing morphs? Wow I thought it was just changing a skin or something.


http://pwp.wizards.com/5103673563/Scorecards/Landscape.png

Offline

 

#17 2010-09-03 18:47:39

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: New Block Type Drawing Method

midnightleopard wrote:

woa! People actually have methods for drawing morphs? Wow I thought it was just changing a skin or something.

I think skin items are slightly too slow because they have to repeat images in ImageFrameMorphs a lot. Multiply that by the number of blocks on the screen and that a lot of images being drawn.


nXIII

Offline

 

#18 2010-09-03 19:10:32

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

How should I modify it for the slot?

Offline

 

#19 2010-09-14 16:26:39

Billybob-Mario
Scratcher
Registered: 2008-01-05
Posts: 500+

Re: New Block Type Drawing Method

I tried making the CoustumeArgMorph's drawing method based on the CostumeBlockMorph's, but it didn't work. How would I make it work? I changed the names of the methods and deleted things that caused small errors, but it still didn't work.

Offline

 

Board footer