RE: How to make a drop shadow for View
(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}
}
|