summaryrefslogtreecommitdiff
path: root/ipl/gprocs/vcoupler.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/gprocs/vcoupler.icn')
-rw-r--r--ipl/gprocs/vcoupler.icn327
1 files changed, 327 insertions, 0 deletions
diff --git a/ipl/gprocs/vcoupler.icn b/ipl/gprocs/vcoupler.icn
new file mode 100644
index 0000000..c9172e9
--- /dev/null
+++ b/ipl/gprocs/vcoupler.icn
@@ -0,0 +1,327 @@
+############################################################################
+#
+# File: vcoupler.icn
+#
+# Subject: Procedures for coupler variables
+#
+# Author: Jon Lipp
+#
+# Date: April 1, 1997
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# Vidgets defined in this file:
+#
+# Vcoupler
+# Vrange_coupler
+# Vstrset_coupler
+# Vbool_coupler
+# Vtable_coupler
+# Vmenu_coupler
+#
+# Utility procedures in this file:
+#
+# add_clients_Vinit()
+#
+############################################################################
+#
+# Links: vidgets
+#
+############################################################################
+
+link vidgets
+
+record Vcoupler_rec(value, callers, clients, id, curr_id, old_id,
+ allowed, locked, uid, V)
+
+############################################################################
+# Vcoupler
+############################################################################
+
+procedure Vcoupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vcoupler, add_client_Vcoupler,
+ init_Vcoupler, null_proc, null_proc,
+ null_proc)
+
+ self := Vcoupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+
+procedure call_clients_Vcoupler(s, caller, val)
+ local i, c
+ static type
+
+ initial type := proc("type", 0) # protect attractive name
+
+ every i := 1 to *s.clients do {
+ c := s.clients[i]
+ if type(c) == "procedure" then c(s.callers[i], val)
+ else if type(c) ? find("coupler") then c.V.set(c, caller, val)
+ else if type(c) == !Vrecset then {
+ # don't call yourself
+ if (type(\caller) == type(c) & \caller["uid"] === c["uid"]) then
+ next
+ c.V.couplerset(c, caller, val)
+ }
+ }
+end
+
+procedure set_Vcoupler(s, caller, val, call_clients)
+ if \s.locked then fail
+ s.value := val
+ if /call_clients then
+ call_clients_Vcoupler(s, caller, val)
+ return val
+end
+
+#
+# Client is the client of course; caller is the vidget record to be passed
+# to this client if type(client) == "procedure".
+#
+procedure add_client_Vcoupler(s, client, caller)
+local pl
+static image
+
+ initial image := proc("image", 0) # protect attractive name
+
+ image(client) ? { if ="function" then
+ _Vbomb("Icon function" || tab(0) || "() not allowed as callback")
+ }
+ put (s.clients, client)
+ put (s.callers, caller)
+end
+
+procedure init_Vcoupler(s)
+ /s.clients := []
+ /s.callers := []
+ s.id := V_COUPLER
+end
+
+############################################################################
+# Vrange_coupler
+# Range couplers are Vcouplers whose values are limited to a
+# particular range of legal values. Presently they must be numeric.
+# The default increment is 0.1.
+############################################################################
+record Vrange_coupler_rec(min, max, value, inc, callers, clients, real, id,
+ locked, uid, V)
+
+procedure Vrange_coupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vrange_coupler,
+ add_client_Vcoupler,
+ init_Vrange_coupler, null_proc,
+ null_proc, null_proc)
+
+ self := Vrange_coupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+#
+# If the value passed is out of range, change caller
+procedure set_Vrange_coupler(s, caller, val, call_clients)
+ local theMax
+ static type
+
+ initial type := proc("type", 0) # protect attractive name
+
+ if \s.locked then fail
+ theMax := numeric(s.max) | (type(s.max) == !Vcoupler_recset, s.max.value) |
+ _Vbomb("illegal value in Vrange_coupler set")
+ val := (s.min > val, s.min) | (theMax < val, theMax)
+ s.value := val
+ if /s.real then val := integer(val)
+ if /call_clients then
+ call_clients_Vcoupler(s, caller, val)
+ return val
+end
+
+procedure init_Vrange_coupler(s)
+ static type
+
+ initial type := proc("type", 0) # protect attractive name
+
+ /s.min := 0; /s.max := 1.0
+ if \s.value < s.min | \s.value > s.max then s.value := s.min
+
+ /s.value := \ s.min
+ s.real := (type(s.min|s.max) == "real", 1)
+
+ /s.inc := 0.1*(s.max-s.min)
+ if /s.real then s.inc := integer(s.inc)
+ init_Vcoupler(s)
+end
+
+############################################################################
+# strset_coupler
+############################################################################
+
+procedure Vstrset_coupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vstrset_coupler,
+ add_client_Vcoupler,
+ init_Vstrset_coupler, null_proc,
+ null_proc, null_proc)
+
+ self := Vcoupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+procedure set_Vstrset_coupler(s, id, val)
+ if \s.locked then fail
+ if !s.allowed === val then
+ return set_Vcoupler(s, id, val)
+end
+
+procedure init_Vstrset_coupler(s)
+ /s.allowed := []
+ init_Vcoupler(s)
+end
+
+############################################################################
+# Vbool_coupler
+############################################################################
+
+procedure Vbool_coupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vbool_coupler,
+ add_client_Vcoupler,
+ init_Vcoupler, unset_Vbool_coupler,
+ toggle_Vbool_coupler, eval_Vbool_coupler)
+
+ self := Vcoupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+procedure eval_Vbool_coupler(s)
+ return \s.value
+end
+
+procedure set_Vbool_coupler(s, caller)
+ if \s.locked then fail
+ s.value := 1
+ call_clients_Vcoupler(s, caller, 1)
+ return s.value
+end
+
+procedure unset_Vbool_coupler(s, caller)
+ s.value := &null
+ call_clients_Vcoupler(s, caller, &null)
+ return s.value
+end
+
+procedure toggle_Vbool_coupler(s, caller)
+ local newstate
+
+ newstate := (/s.value, 1)
+ return set_Vcoupler(s, caller, newstate)
+end
+
+############################################################################
+# Vtable_coupler
+############################################################################
+
+procedure Vtable_coupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vtable_coupler,
+ add_client_Vcoupler,
+ init_Vtable_coupler, null_proc,
+ null_proc, null_proc)
+
+ self := Vcoupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+procedure set_Vtable_coupler(s, id, key, val)
+ s.value[key] := val
+ call_clients_Vcoupler(s, id, val)
+end
+
+procedure init_Vtable_coupler(s)
+ s.value := table()
+ init_Vcoupler(s)
+end
+
+############################################################################
+# Vmenu_coupler
+############################################################################
+
+procedure Vmenu_coupler(params[])
+ local self
+ static procs
+
+ initial procs := Vstd_coupler(set_Vmenu_coupler,
+ null_proc,
+ null_proc, null_proc,
+ null_proc, null_proc)
+
+ self := Vcoupler_rec ! params
+ self.uid := Vget_uid()
+ self.V := procs
+ self.V.init(self)
+ return self
+end
+
+
+procedure set_Vmenu_coupler(s, id, val)
+ if \s.locked then fail
+ s.old_id := s.curr_id
+ s.curr_id := id
+ s.value := val
+ (\s.old_id).V.couplerset(s.old_id, , val)
+ return val
+end
+
+
+############################################################################
+# Utilities
+############################################################################
+
+#
+# Takes the callback parameter passed in upon creation of a vidget and
+# adds them to the client list of the coupler variable, checking if it
+# is a list or not.
+#
+procedure add_clients_Vinit(cv, callbacks, vid)
+ local cb
+ static type
+
+ initial type := proc("type", 0) # protect attractive name
+
+ if type(\callbacks) == "list" then
+ every cb := !callbacks do cv.V.add_client(cv, \cb, vid)
+ else
+ cv.V.add_client(cv, \callbacks, vid)
+end
+