More: How to make a square topped, round rect bottomed graphic?

Jan Schenkel janschenkel at yahoo.com
Thu Dec 2 11:08:37 EST 2010


--- On Thu, 12/2/10, Jan Schenkel <janschenkel at yahoo.com> wrote:
> In theory, if you have two inner 'rectangle' groups, you
> have enough to cover all situations, including diagonally
> opposing round corners, simply by changing the rect of their
> clipping groups.
> Beacause all inner overlay graphics have the same rect, you
> can set the same gradient on each, and the same graphic
> effects; and all transitions remain smooth, through the
> clipping mechanism.
> The beauty of this approach is that it's relatively
> straightforward to implement - it sure beats trying to
> calculate the corner points for a single 'curve' graphic
> :-)
> 

And because I just couldn't help myself, I continued to develop this idea - any excuse is good to spend some time in LiveCode!

Create a new stack, and drop two buttons onto it.
Name the first "CombinedGraphicBehavior" and set its script to:
##
on resizeControl
   cgReshapeControl
end resizeControl

private command cgReshapeControl pCorners
   if the paramCount = 0 then
      put the cgRoundCorners of me into pCorners
   end if
   --> load some essentials into local variables
   local tRectangle, tWidth, tHeight, tRoundRadius
   put the rectangle of me into tRectangle
   put (item 3 of tRectangle) - (item 1 of tRectangle) \
          into tWidth
   put (item 4 of tRectangle) - (item 2 of tRectangle) \
          into tHeight
   put the roundRadius of graphic "RoundRectGraphic" of me \
          into tRoundRadius
   --> get ready to update the cover rectangles
   lock screen
   local tCoverRectangle
   --> see which part of the top we need to cover
   put tRectangle into tCoverRectangle
   subtract tHeight div 2 from item 4 of tCoverRectangle
   if "topleft" is among the items of pCorners then
      add tRoundRadius to item 1 of tCoverRectangle
   end if
   if "topright" is among the items of pCorners then
      subtract tRoundRadius from item 3 of tCoverRectangle
   end if
   set the rectangle of group "RectangleClipGroupTop" of me \
          to tCoverRectangle
   --> see which part of the bottom we need to cover
   put tRectangle into tCoverRectangle
   add tHeight div 2 to item 2 of tCoverRectangle
   if "bottomleft" is among the items of pCorners then
      add tRoundRadius to item 1 of tCoverRectangle
   end if
   if "bottomright" is among the items of pCorners then
      subtract tRoundRadius from item 3 of tCoverRectangle
   end if
   set the rectangle of group "RectangleClipGroupBtm" of me \
          to tCoverRectangle
   --> all done
   set the rectangle of graphic "RectangleGraphic" \
          of group "RectangleClipGroupTop" of me \
          to tRectangle
   set the rectangle of graphic "RectangleGraphic" \
          of group "RectangleClipGroupBtm" of me \
          to tRectangle
   set the rectangle of graphic "RoundRectGraphic" of me \
          to tRectangle
   unlock screen
end cgReshapeControl

setProp cgRoundRadius pRoundRadius
   set the roundRadius of graphic "RoundRectGraphic" of me to pRoundRadius
   cgReshapeControl  -- no params
end cgRoundRadius

getProp cgRoundRadius
   return the roundRadius of graphic "RoundRectGraphic" of me
end cgRoundRadius

setProp cgLineSize pBorderWidth
   set the lineSize of graphic "RoundRectGraphic" of me \
          to pBorderWidth
   set the lineSize of graphic "RectangleGraphic" \
          of group "RectangleClipGroupTop" of me \
          to pBorderWidth
   set the lineSize of graphic "RectangleGraphic" \
          of group "RectangleClipGroupBtm" of me \
          to pBorderWidth
end cgLineSize

getProp cgLineSize
   return the lineSize of graphic "RoundRectGraphic" of me
end cgLineSize

setProp cgFillGradient pFillGradientA
   set the fillGradient of graphic "RoundRectGraphic" of me \
          to pFillGradientA
   set the fillGradient of graphic "RectangleGraphic" \
          of group "RectangleClipGroupTop" of me \
          to pFillGradientA
   set the fillGradient of graphic "RectangleGraphic" \
          of group "RectangleClipGroupBtm" of me \
          to pFillGradientA
end cgFillGradient

getProp cgFillGradient
   return the fillGradient of graphic "RoundRectGraphic" of me
end cgFillGradient

setProp cgRoundCorners pCorners
   cgReshapeControl pCorners
   pass cgRoundCorners
end cgRoundCorners
##

Give the second button a descriptive name like "Create" and set its script to:
##
constant kRectangle = "50,50,250,100"
constant kRoundCorners = "topleft,bottomright"

on mouseUp
   lock screen
   --> load the fillGradient array
   local tFillGradientA
   put "linear" into tFillGradientA["type"]
   put (item 1 of kRectangle),(item 2 of kRectangle) \
          into tFillGradientA["from"]
   put (item 3 of kRectangle),(item 2 of kRectangle) \
          into tFillGradientA["to"]
   put (item 1 of kRectangle),(item 4 of kRectangle) \
          into tFillGradientA["via"]
   put "0.00000,192,192,192" & return & \
          "1.00000,128,128,128" \
          into tFillGradientA["ramp"]
   --> create the customcontrol group
   local tControlGroup
   CreateCombinedGraphic "CombinedGraphicControl", kRectangle, kRoundCorners
   put the result into tControlGroup
   --> set additional properties
   set the cgRoundRadius of tControlGroup to 20
   set the cgLineSize of tControlGroup to 5
   set the cgFillGradient of tControlGroup to tFillGradientA
   --> all done
   unlock screen
end mouseUp

constant kNoMargins = "0,0,0,0"

private command CreateCombinedGraphic pName, pRectangle, pRoundCorners
   --> prepare by resetting the templateControls
   reset the templateGroup
   reset the templateGraphic
   --> start by creating the control group
   local tControlGroup, tRectangleGroup
   set the rectangle of the templateGroup to pRectangle
   set the margins of the templateGroup to kNoMargins
   set the selectGroupedControls of the templateGroup to false
   set the behavior of the templateGroup to \
          the long id of button "CombinedGraphicBehavior"
   create group pName
   put it into tControlGroup
   --> create the roundrect in the control group
   set the style of the templateGraphic to "RoundRect"
   set the rectangle of the templateGraphic to pRectangle
   set the opaque of the templateGraphic to true
   set the antiAliased of the templateGraphic to true
   create graphic "RoundRectGraphic" in tControlGroup
   --> create the rectangle inner groups
   CreateRectangleGroup tControlGroup, "Top"
   CreateRectangleGroup tControlGroup, "Btm"
   --> cleanup by resetting the templateControls
   reset the templateGroup
   reset the templateGraphic
   --> now reshape the control innards
   set the cgRoundCorners of tControlGroup to pRoundCorners
   --> let the caller use the reference if it wants
   return tControlGroup
end CreateCombinedGraphic

private command CreateRectangleGroup pControlGroup, pSuffix
   --> create the rectangle clipping group
   local tRectangleGroup
   reset the templateGroup
   set the rectangle of the templateGroup to \
          the rectangle of pControlGroup
   set the lockLocation of the templateGroup to true
   set the margins of the templateGroup to kNoMargins
   create group ("RectangleClipGroup" & pSuffix) in pControlGroup
   put it into tRectangleGroup
   --> create the rectangle in the bottom inner group
   reset the templateGraphic
   set the style of the templateGraphic to "Rectangle"
   set the rectangle of the templateGraphic \
          to the rectangle of pControlGroup
   set the opaque of the templateGraphic to true
   set the antiAliased of the templateGraphic to true
   create graphic "RectangleGraphic" in tRectangleGroup
   --> let the caller use the reference if it wants
   return tRectangleGroup
end CreateRectangleGroup
##

Click the button, and you get a combined graphic custom control that has a bunch of handy properties and resizes nicely - as long as you don't make it too small anyway ;-)
You can extend the behavior script for graphic effects, but I'll leave that as an exercise to the reader.

Cheers,

Jan Schenkel.
=====
Quartam Reports & PDF Library for LiveCode
www.quartam.com

=====
"As we grow older, we grow both wiser and more foolish at the same time."  (La Rochefoucauld)



      




More information about the use-livecode mailing list