home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
gprocs
/
vslider.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
11KB
|
388 lines
############################################################################
#
# File: vslider.icn
#
# Subject: Procedures for sliders
#
# Authors: Jon Lipp and Gregg M. Townsend
#
# Date: April 1, 1997
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Vidgets defined in this file:
# Vvslider
# Vhslider
#
# Utility procedures in this file:
# Vvert_slider()
# Vhoriz_slider()
#
############################################################################
#
# Includes: vdefns.icn
#
############################################################################
#
# Links: vidgets
#
############################################################################
link vidgets
$include "vdefns.icn"
record Vslider_rec (win, callback, id, aw, ah, discont,
ax, ay, data, pad, ws, cv_range, rev, pos, uid, drawn, P, V)
############################################################################
# Vvslider
############################################################################
procedure procs_Vvslider()
static procs
initial procs := Vstd(event_Vvslider, draw_Vvslider, outline_Vslider,
resize_Vvslider, inrange_Vpane, init_Vvslider,
couplerset_Vvslider,,,,,set_value_Vvslider)
return procs
end
procedure Vvslider(params[])
local self
self := Vslider_rec ! params[1:7|0]
Vwin_check(self.win, "Vvert_slider()")
if (\self.aw, not numeric(self.aw) ) then
_Vbomb("invalid width parameter to Vvert_slider()")
if (\self.ah, not numeric(self.ah) ) then
_Vbomb("invalid length parameter to Vvert_slider()")
self.uid := Vget_uid()
self.V := procs_Vvslider()
self.P := Vstd_pos()
self.V.init(self)
return self
end
procedure draw_Vvslider(s)
local val
s.drawn := 1
s.V.outline(s)
val := (s.callback.value - s.callback.min) * s.ws / s.cv_range
if \s.rev then
val := s.ws - val + s.pad
else
val +:= s.pad
s.pos := val
draw_Vvslider_bar(s)
end
procedure event_Vvslider(s, e)
local value
if \s.callback.locked then fail
if e === (&lpress|&mpress|&rpress) then
until e === (&lrelease|&mrelease|&rrelease) do {
value := ((&y - s.ay - s.pad) / s.ws) * s.cv_range
if \s.rev then
s.callback.V.set(s.callback, s, s.callback.max - value, s.discont)
else
s.callback.V.set(s.callback, s, s.callback.min + value, s.discont)
s.data := s.callback.value
update_Vvslider(s, 1)
e := Event(s.win)
}
else
fail # not our event
if \s.discont then
s.callback.V.set(s.callback, s, s.callback.value)
update_Vvslider(s)
return s.callback.value
end
procedure update_Vvslider(s, active)
local val
val := (s.callback.value - s.callback.min) * s.ws / s.cv_range
if \s.rev then
val := s.ws - val + s.pad
else
val +:= s.pad
s.pos := val
draw_Vvslider_bar(s, active)
return s.callback.value
end
procedure draw_Vvslider_bar(s, active)
local ww, d
ww := s.aw - 4
EraseArea(s.win, s.ax + 2, s.ay + 2, ww, s.ah - 4)
if \active then {
d := -1
FillRectangle(s.win, s.ax + 4, s.ay + s.pos - ww + 2, ww - 4, 2 * ww - 4)
}
else
d := 1
BevelRectangle(s.win, s.ax + 2, s.ay + s.pos - ww, ww, 2 * ww, d)
BevelRectangle(s.win, s.ax + 3, s.ay + s.pos, ww - 2, 1 - ww, d)
BevelRectangle(s.win, s.ax + 3, s.ay + s.pos, ww - 2, ww - 1, d)
end
procedure set_value_Vvslider(s, value)
couplerset_Vvslider(s, , value)
return
end
procedure couplerset_Vvslider(s, caller, value)
value := numeric(value) | s.callback.min
if s.callback.value === value then fail
s.callback.V.set(s.callback, caller, value)
s.data := s.callback.value
if \s.drawn then
update_Vvslider(s)
end
procedure init_Vvslider(s)
static type
initial type := proc("type", 0) # protect attractive name
/s.aw := VSlider_DefWidth
/s.ah := VSlider_DefLength
s.aw <:= VSlider_MinWidth
s.ah <:= VSlider_MinAspect * s.aw
if /s.callback | type(s.callback) == "procedure" then
_Vbomb("Vvslider requires a coupler variable callback")
s.pad := s.aw - 2
s.ws := real(s.ah - 2 * s.pad)
s.cv_range := s.callback.max - s.callback.min
init_Vpane(s)
end
procedure resize_Vvslider(s, x, y, w, h)
resize_Vidget(s, x, y, w, h)
if s.aw > s.ah then {
s.V := procs_Vhslider()
return s.V.resize(s, x, y, w, h)
}
s.pad := s.aw - 2
s.ws := real(s.ah - 2 * s.pad)
s.cv_range := s.callback.max - s.callback.min
end
############################################################################
# Vhslider
############################################################################
procedure procs_Vhslider()
static procs
initial procs := Vstd(event_Vhslider, draw_Vhslider, outline_Vslider,
resize_Vhslider, inrange_Vpane, init_Vhslider,
couplerset_Vhslider,,,,,set_value_Vhslider)
return procs
end
procedure Vhslider(params[])
local self
self := Vslider_rec ! params[1:7|0]
self.aw :=: self.ah
Vwin_check(self.win, "Vhoriz_slider()")
if (\self.ah, not numeric(self.ah) ) then
_Vbomb("invalid width parameter to Vhoriz_slider()")
if (\self.aw, not numeric(self.aw) ) then
_Vbomb("invalid length parameter to Vhoriz_slider()")
self.uid := Vget_uid()
self.V := procs_Vhslider()
self.P := Vstd_pos()
self.V.init(self)
return self
end
procedure draw_Vhslider(s)
local val
s.drawn := 1
s.V.outline(s)
val := (s.callback.value - s.callback.min) * s.ws / s.cv_range
if \s.rev then
val := s.ws - val + s.pad
else
val +:= s.pad
s.pos := val
draw_Vhslider_bar(s)
end
procedure event_Vhslider(s, e)
local value
if \s.callback.locked then fail
if e === (&lpress|&mpress|&rpress) then
until e === (&lrelease|&mrelease|&rrelease) do {
value := ((&x - s.ax - s.pad) / s.ws) * s.cv_range
if \s.rev then
s.callback.V.set(s.callback, s, s.callback.max - value, s.discont)
else
s.callback.V.set(s.callback, s, s.callback.min + value, s.discont)
s.data := s.callback.value
update_Vhslider(s, 1)
e := Event(s.win)
}
else
fail # not our event
if \s.discont then
s.callback.V.set(s.callback, s, s.callback.value)
update_Vhslider(s)
return s.callback.value
end
procedure update_Vhslider(s, active)
local val
val := (s.callback.value - s.callback.min) * s.ws / s.cv_range
if \s.rev then
val := s.ws - val + s.pad
else
val +:= s.pad
s.pos := val
draw_Vhslider_bar(s, active)
return s.callback.value
end
procedure draw_Vhslider_bar(s, active)
local hh, d
hh := s.ah - 4
EraseArea(s.win, s.ax + 2, s.ay + 2, s.aw - 4, hh)
if \active then {
d := -1
FillRectangle(s.win, s.ax + s.pos - hh + 2, s.ay + 4, 2 * hh - 4, hh - 4)
}
else
d := 1
BevelRectangle(s.win, s.ax + s.pos - hh, s.ay + 2, 2 * hh, hh, d)
BevelRectangle(s.win, s.ax + s.pos, s.ay + 3, 1 - hh, hh - 2, d)
BevelRectangle(s.win, s.ax + s.pos, s.ay + 3, hh - 1, hh - 2, d)
end
procedure set_value_Vhslider(s, value)
couplerset_Vhslider(s, , value)
return
end
procedure couplerset_Vhslider(s, caller, value)
## break a cycle in callbacks by checking value.
value := numeric(value) | s.callback.min
if s.callback.value === value then fail
s.callback.V.set(s.callback, caller, value)
s.data := s.callback.value
if \s.drawn then
update_Vhslider(s)
end
procedure init_Vhslider(s)
static type
initial type := proc("type", 0) # protect attractive name
/s.ah := VSlider_DefWidth
/s.aw := VSlider_DefLength
s.ah <:= VSlider_MinWidth
s.aw <:= VSlider_MinAspect * s.ah
if /s.callback | type(s.callback) == "procedure" then
_Vbomb("Vhslider requires a coupler variable callback")
s.pad := s.ah - 2
s.ws := real(s.aw - 2 * s.pad)
s.cv_range := s.callback.max - s.callback.min
init_Vpane(s)
end
procedure resize_Vhslider(s, x, y, w, h)
resize_Vidget(s, x, y, w, h)
if s.aw < s.ah then {
s.V := procs_Vvslider()
return s.V.resize(s, x, y, w, h)
}
s.pad := s.ah - 2
s.ws := real(s.aw - 2 * s.pad)
s.cv_range := s.callback.max - s.callback.min
end
############################################################################
# Utilities - slider wrapper procedures.
############################################################################
procedure outline_Vslider(s)
BevelRectangle(s.win, s.ax, s.ay, s.aw, s.ah, -2) # draw trough
end
procedure Vmake_slider(slider_type, w, callback, id, length, width,
min, max, init, discontinuous)
local cv, sl, cb, t
static type
initial type := proc("type", 0) # protect attractive name
/min := 0
/max := 1.0
if not numeric(min) | not numeric(max) | (\init, not numeric(init)) then
_Vbomb("non-numeric min, max, or init parameter passed to Vxxxxx_slider()")
if max < min then { min :=: max; t := 1 }
cv := Vrange_coupler(min, max, init)
sl := slider_type(w, cv, id, width, length, discontinuous)
sl.rev := t
add_clients_Vinit(cv, callback, sl)
return sl
end
############################################################################
# Vvert_slider(w, callback, id, width, length, lower_bound, upper_bound,
# initial_value)
############################################################################
procedure Vvert_slider(params[])
local frame, x, y, ins, t, self
if ins := Vinsert_check(params) then {
frame := pop(params); x := pop(params); y:= pop(params)
}
params[6] :=: params[7]
push(params, Vvslider)
self := Vmake_slider ! params
if \ins then VInsert(frame, self, x, y)
return self
end
############################################################################
# Vhoriz_slider(w, callback, id, width, length, left_bound, right_bound,
# initial_value)
############################################################################
procedure Vhoriz_slider(params[])
local frame, x, y, ins, self
if ins := Vinsert_check(params) then {
frame := pop(params); x := pop(params); y:= pop(params)
}
push(params, Vhslider)
self := Vmake_slider ! params
if \ins then VInsert(frame, self, x, y)
return self
end