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