Curl Global Community
How to make a drop shadow for View - Printable Version

+- Curl Global Community (http://communities.curl.com)
+-- Forum: Discussions (http://communities.curl.com/forumdisplay.php?fid=1)
+--- Forum: General Curl questions (http://communities.curl.com/forumdisplay.php?fid=2)
+--- Thread: How to make a drop shadow for View (/showthread.php?tid=210)



How to make a drop shadow for View - alchimiste - 08-15-2011

Hi~

I want to make a drop shadow for View object of which option decorations is set to false.

I passed shadow-spec option to View construtor, but I found it was useless.

How to make a drop shadow for View?

If decorations? is set to false, is it impossible to throw a shadow?



RE: How to make a drop shadow for View - c-s - 08-16-2011

(08-15-2011, 04:24 PM)alchimiste Wrote: Hi~

I want to make a drop shadow for View object of which option decorations is set to false.

I passed shadow-spec option to View construtor, but I found it was useless.

How to make a drop shadow for View?

If decorations? is set to false, is it impossible to throw a shadow?

The shadow-spec option is only for within Curl layouts; it does not apply outside of windows. There's no option to be set to show a drop show for Views, since it's dependent on the OS or window manager.

However, you can do something like the following to produce a drop-shadow-like effect.

Code:
{curl 7.0 applet}

{do
    
    def outer-view =
        {View
            decorations? = false,
            width = 5.3cm,
            height = 3.3cm,
            {Fill background =
                {LinearGradientFillPattern
                    {Fraction2d 0.2, 0},
                    {Fraction2d 0.8, 1},
                    {Spectrum.from-endpoints
                        {FillPattern.from-rgb 0, 0, 0, opacity = 0.2},
                        {FillPattern.from-rgb 0.2, 0.2, 0.2, opacity = 1}
                    }
                }
            }
        }
    {outer-view.set-opacity 0.2}
    
    def inner-view =
        {View
            decorations? = false,
            owner = outer-view,
            width = 5cm,
            height = 3cm,
            {TextFlowBox
                width = {add-stretch},
                height = {add-stretch},
                margin = 8px,
                {paragraph here is some text}
            }
        }
        
    {inner-view.set-position 2cm, 2cm}
    {outer-view.set-position 1.9cm, 1.9cm}
    
    {outer-view.show}
    {inner-view.show}
    
}

Or, to be fancier, apply a window shape too, as below. (The upper procs are just designed to create a rounded rectangle shape, and are taken from the styled controls package, which in the open controls is COM.CURL.OPEN.GUI.STYLED-CONTROLS.)

Code:
{curl 7.0 applet}

{let package constant machine-epsilon-distance:Distance =
    ({pow 2, -23} asa float) * 1m
}

{define-proc package {points-within-epsilon?
                         point-1:Distance2d,
                         point-2:Distance2d
                     }:bool
    {return
        ({abs point-1.x - point-2.x} < machine-epsilon-distance)
        and ({abs point-1.y - point-2.y} < machine-epsilon-distance)
    }
}

{define-proc package {create-rounded-rectangle-path
                         x:Distance,
                         y:Distance,
                         width:Distance,
                         height:Distance,
                         x-radius:Distance,
                         y-radius:Distance,
                         ul-round?:bool = true,
                         ur-round?:bool = true,
                         ll-round?:bool = true,
                         lr-round?:bool = true
                     }:Path
    
    {if width < 0m then
        {inc x, width}
        set width = -width
    }
    {if height < 0m then
        {inc y, height}
        set height = -height
    }
    set x-radius = {max 0m, {min 0.5 * width, x-radius}}
    set y-radius = {max 0m, {min 0.5 * height, y-radius}}
    
    def path = {Path}
    {if x-radius == 0m and y-radius == 0m then
        {path.move-to {Distance2d x, y}}
        {path.line-to {Distance2d x, y + height}}
        {path.line-to {Distance2d x + width, y + height}}
        {path.line-to {Distance2d x + width, y}}
        {path.line-to {Distance2d x, y}}
        {return path}
    }
    
    || We want to ensure only one curve, usually, because a high
    || degree of accuracy really isn't important.  However, you *can*
    || see the difference for rounded rectangles that are really close
    || to ellipses, so use the normal algorithm in that case.
    def max-angle =
        {if x-radius >= .4 * width or y-radius >= 0.4 * height then
            45deg
         else
            || Ensure only one division
            90deg
        }
    
    || Nomenclature:
    || yu == y upper == topmost y coord of vertical flat edge
    || yl == y lower == bottommost y coord of vertical flat edge
    || xl == x left == leftmost x coord of horizontal flat edge
    || xr == x right == rightmost x coord of horizontal flat edge
    def yu = y + y-radius
    def yl = y + height - y-radius
    def xl = x + x-radius
    def xr = x + width - x-radius
    
    {path.move-to {Distance2d x, yu}}
    
    let pre-arc:Distance2d = {Distance2d x, yl}
    let post-arc:Distance2d = {Distance2d xl, y + height}
    {path.line-to pre-arc}
    {if ll-round? and
        not {points-within-epsilon? pre-arc, post-arc}
    then
        {path.arc-to
            x-radius,
            y-radius,
            0deg,
            false,
            false,
            post-arc,
            max-angle = max-angle
        }
    else
        {path.line-to {Distance2d x, y + height}}
        {path.line-to post-arc}
    }
    
    || Either go to the next corner or take a loop detour.
    set pre-arc = {Distance2d xr, y + height}
    set post-arc = {Distance2d x + width, yl}
    {path.line-to pre-arc}
    {if lr-round? and
        not {points-within-epsilon? pre-arc, post-arc}
    then
        {path.arc-to
            x-radius,
            y-radius,
            0deg,
            false,
            false,
            post-arc,
            max-angle = max-angle
        }
    else
        {path.line-to {Distance2d x + width, y + height}}
        {path.line-to post-arc}
    }
    
    set pre-arc = {Distance2d x + width, yu}
    set post-arc = {Distance2d xr, y}
    {path.line-to pre-arc}
    {if ur-round? and
        not {points-within-epsilon? pre-arc, post-arc}
    then
        {path.arc-to
            x-radius,
            y-radius,
            0deg,
            false,
            false,
            post-arc,
            max-angle = max-angle
        }
    else
        {path.line-to {Distance2d x + width, y}}
        {path.line-to post-arc}
    }
    
    set pre-arc = {Distance2d xl, y}
    set post-arc = {Distance2d x, yu}
    {path.line-to pre-arc}
    {if ul-round? and
        not {points-within-epsilon? pre-arc, post-arc}
    then
        {path.arc-to
            x-radius,
            y-radius,
            0deg,
            false,
            false,
            post-arc,
            max-angle = max-angle
        }
    else
        {path.line-to {Distance2d x, y}}
        {path.line-to post-arc}
    }
    
    {return path}
}


{do
    
    def outer-view =
        {View
            decorations? = false,
            width = 5.3cm,
            height = 3.3cm,
            {Fill background =
                {LinearGradientFillPattern
                    {Fraction2d 0.2, 0},
                    {Fraction2d 0.8, 1},
                    {Spectrum.from-endpoints
                        {FillPattern.from-rgb 0, 0, 0, opacity = 0.2},
                        {FillPattern.from-rgb 0.2, 0.2, 0.2, opacity = 1}
                    }
                }
            }
        }
    {outer-view.set-opacity 0.2}
    {outer-view.set-window-shape
        {Region.from-path
            {create-rounded-rectangle-path
                0m,
                0m,
                5.3cm,
                3.3cm,
                2mm,
                2mm
            }
        }
    }
    
    def inner-view =
        {View
            decorations? = false,
            owner = outer-view,
            width = 5cm,
            height = 3cm,
            {TextFlowBox
                width = {add-stretch},
                height = {add-stretch},
                margin = 8px,
                {paragraph here is some text}
            }
        }
    
    {inner-view.set-window-shape
        {Region.from-path
            {create-rounded-rectangle-path
                0m,
                0m,
                5cm,
                3cm,
                1.9mm,
                1.9mm
            }
        }
    }
    
    {inner-view.set-position 2cm, 2cm}
    {outer-view.set-position 1.9cm, 1.9cm}
    
    {outer-view.show}
    {inner-view.show}
    
}



RE: How to make a drop shadow for View - alchimiste - 08-16-2011

Oh, very very great!!

Thank you!!