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 / vradio.icn < prev    next >
Text File  |  2000-07-29  |  8KB  |  323 lines

  1. ############################################################################
  2. #
  3. #    File:     vradio.icn
  4. #
  5. #    Subject:  Procedures for radio buttons
  6. #
  7. #    Authors:  Jon Lipp and Gregg M. Townsend
  8. #
  9. #    Date:     August 14, 1996
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  Vidgets defined in this file:
  18. #    Vradio_entry
  19. #    Vradio_frame
  20. #
  21. #  Utility procedures in this file:
  22. #    Vradio_buttons()
  23. #    Vvert_radio_buttons()
  24. #    Vhoriz_radio_buttons()
  25. #    init_format_Vrb()
  26. #    format_Vradio_frame()    
  27. #
  28. ############################################################################
  29.  
  30. link vstyle
  31.  
  32. ############################################################################
  33. # Vradio - the radio button.
  34. ############################################################################
  35.  
  36. record Vradio_entry_rec (win, s, callback, id, style, aw, ah, don, ax, ay, uid, P, D, V)
  37.  
  38. #
  39. # Creation procedure.
  40. #
  41. procedure Vradio_entry(params[])
  42.    local self
  43.    static procs
  44.  
  45.    initial procs := Vstd(event_Vradio_entry, draw_Vradio_entry,
  46.       outline_radio_pane, resize_Vidget, inrange_Vpane, init_Vradio_entry,
  47.                         couplerset_Vradio_entry)
  48.    self := Vradio_entry_rec ! params
  49.    self.uid := Vget_uid()
  50.    Vset_style(self, self.style)
  51.    self.V := procs
  52.    self.P := Vstd_pos()
  53.    self.V.init(self)
  54.    return self
  55. end
  56.  
  57. procedure init_Vradio_entry (self)
  58.    local p
  59.  
  60.    if /self.callback then 
  61.       _Vbomb("must pass a coupler variable to a Vradio_entry button")
  62.    self.D.init(self)
  63. end
  64.  
  65.  
  66. #
  67. #  Draw the frame around the radio buttons.
  68. #
  69. procedure outline_radio_pane(self)
  70.    GrooveRectangle(self.win, self.ax, self.ay, self.aw, self.ah)
  71. end
  72.  
  73.  
  74. #
  75. #  Draw the radio button.  If coupler's value is this id, draw "on".
  76. #
  77. procedure draw_Vradio_entry(self)
  78.    if self.callback.value === self.id then {
  79.       self.D.draw_on(self)
  80.       self.don := 1
  81.       }
  82.    else {
  83.       self.D.draw_off(self)
  84.       self.don := &null
  85.       }
  86. end
  87.  
  88. #
  89. #  The coupler notified us, turn "off".
  90. #
  91. procedure couplerset_Vradio_entry(self)
  92.    self.D.draw_off(self)
  93.    self.don := &null
  94. end
  95.  
  96. #
  97. #  If first time in this button, set coupler, draw "on".
  98. #  If mouse releases on me, return my own record structure.
  99. #
  100. procedure event_Vradio_entry(self, e)
  101.  
  102.    if self.callback.value ~=== self.id | /self.don then {
  103.       self.callback.V.set(self.callback, self, self.id)
  104.       self.D.draw_on(self)
  105.       self.don := 1
  106.       }
  107.    if \e === (&lrelease|&mrelease|&rrelease) then 
  108.       return self
  109. end
  110.  
  111.  
  112. ############################################################################
  113. # Vradio_frame
  114. ############################################################################
  115.  
  116. record Vradio_frame_rec(win, cv, callback, id, aw, ah, data,
  117.    lookup, draw, ax, ay, uid, P, V)
  118.  
  119. #
  120. # Creation procedure.
  121. #
  122. procedure Vradio_frame(params[])
  123.    local self, p
  124.    static procs
  125.  
  126.    initial {
  127.       procs := Vstd(event_Vradio_frame, draw_Vframe, outline_radio_pane,
  128.                    resize_Vframe, inrange_Vpane, init_Vframe,
  129.                    couplerset_Vpane, insert_Vframe, null_proc,
  130.                    lookup_Vframe, set_abs_Vframe, set_value_Vradio_frame)
  131.    }
  132.  
  133.    self := Vradio_frame_rec ! params
  134.    self.uid := Vget_uid()
  135.    self.V := procs
  136.    self.P := Vstd_pos()
  137.    self.V.init(self)
  138.    p := \self.callback
  139.    self.callback := Vcoupler()
  140.    add_clients_Vinit(self.callback, p, self)
  141.    
  142.    return self
  143. end
  144.  
  145. #
  146. #  Distribute mouse event to proper radio button.  If returns
  147. #  a value, (mouse released) notify callbacks, return text label
  148. #  of radio button selected.
  149. #
  150. procedure event_Vradio_frame(self, e, x, y)
  151.    local focus, rv
  152.  
  153.    if \self.callback.locked then fail
  154.    if e ~=== &lpress & e ~=== &mpress & e ~=== &rpress then fail
  155.    focus := self.V.lookup(self, x, y)
  156.    (\focus).V.event(focus, e)
  157.    repeat {
  158.       e := Event(self.win)
  159.       if e === "\^s" then
  160.          until Event(self.win) === (&lpress|&mpress|&rpress) ;
  161.       if self.V.inrange(self, &x, &y) then 
  162.          focus := self.V.lookup(self, &x, &y)
  163.       if rv := (\focus).V.event(focus, e) then {
  164.          self.data := rv.s
  165.          self.callback.V.set(self.callback, rv, rv.s)
  166.          return rv.s
  167.       }
  168.    }
  169. end
  170.  
  171. #
  172. #  Set the radio frame according to string label passed in.  Match with
  173. #  string label of a button.  Null sets to no button.
  174. #
  175. procedure set_value_Vradio_frame(self, value)
  176.    local old, kid, id, s, k
  177.  
  178.    if (/value | *value = 0 | value === V_DUMMY_ID) then {
  179.       kid := &null
  180.       id := V_DUMMY_ID
  181.       s := ""
  182.       }
  183.    else {
  184.       kid := self.cv.curr_id
  185.       id := self.cv.value
  186.       s := self.data
  187.       every (k := !self.lookup | fail) do 
  188.          if value === k.s then {
  189.             id := k.id
  190.             kid := k
  191.             s := value
  192.             break
  193.             }
  194.       }
  195.  
  196.    old := self.cv.curr_id
  197.    self.cv.curr_id := kid
  198.    self.cv.value := id
  199.    self.data := s
  200.  
  201.    self.callback.V.set(self.callback, self, self.data)
  202.  
  203.    (\old).D.draw_off(old)    # clear current button
  204.    (\kid).D.draw_on(kid)    # set new button
  205.  
  206.    return
  207. end
  208.  
  209. ############################################################################
  210. # Vradio_buttons -
  211. # Construct radio buttons. Parameters:
  212. #     w - window, proc - the callback procedure,
  213. #    s[] - a list of button labels. 
  214. ############################################################################
  215. procedure Vradio_buttons(params[])
  216.    return Vvert_radio_buttons ! params
  217. end
  218.  
  219.  
  220. #
  221. # params: (w, s, callback, id, style)
  222. #
  223. procedure Vvert_radio_buttons(params[])
  224.    local frame, x, y, ins, win, s, callback, id, style
  225.    local rb_frame, max, cv, i, rb, first, uncentered
  226.    static type
  227.  
  228.    initial type := proc("type", 0)    # protect attractive name
  229.  
  230.    if ins := Vinsert_check(params) then {
  231.       frame := pop(params); x := pop(params); y:= pop(params)
  232.       }
  233.    win := params[1]
  234.    s := params[2]
  235.    callback := params[3]
  236.    id := params[4]
  237.    style := params[5]
  238.    uncentered := params[6]
  239.  
  240.    Vwin_check(win, "Vradio_buttons()")
  241.    if type(s) ~== "list" then 
  242.       _Vbomb("data parameter to Vradio_buttons must be a list of strings") 
  243.    cv := Vmenu_coupler()
  244.    rb_frame := Vradio_frame(win, cv, callback, id)
  245.    if /uncentered then {
  246.       max := 0
  247.       every i := !s do max <:= TextWidth(win, i)
  248.       max +:= 8
  249.       }
  250.    if \style == (V_CIRCLE | V_CHECK | V_DIAMOND | 
  251.      V_CHECK_NO | V_CIRCLE_NO | V_DIAMOND_NO) then
  252.       max +:= 4 + WAttrib(win, "fheight")
  253.    every i := 1 to *s do {
  254.       rb := Vradio_entry(win, s[i], cv, i, style, max)
  255.       VInsert(rb_frame, rb, 0, (i-1)*rb.ah)
  256.    }
  257.  
  258.    init_format_Vrb(rb_frame)
  259.    format_Vradio_frame(rb_frame)
  260.  
  261.    if \ins then VInsert(frame, rb_frame, x, y)
  262.    return rb_frame
  263. end
  264.  
  265. procedure Vhoriz_radio_buttons(params[])
  266.    local frame, x, y, ins, win, s, callback, id, style, hpos
  267.    local rb_frame, max, cv, i, rb, first
  268.    static type
  269.  
  270.    initial type := proc("type", 0)    # protect attractive name
  271.  
  272.    if ins := Vinsert_check(params) then {
  273.       frame := pop(params); x := pop(params); y:= pop(params)
  274.       }
  275.    win := params[1]
  276.    s := params[2]
  277.    callback := params[3]
  278.    id := params[4]
  279.    style := params[5]
  280.  
  281.    Vwin_check(win, "Vradio_buttons()")
  282.    if type(s) ~== "list" then
  283.       _Vbomb("data parameter to Vradio_buttons must be a list of strings")
  284.    cv := Vmenu_coupler()
  285.    rb_frame := Vradio_frame(win, cv, callback, id)
  286.    hpos := 0
  287.    every i := 1 to *s do {
  288.       rb := Vradio_entry(win, s[i], cv, i, style)
  289.       VInsert(rb_frame, rb, hpos, 0)
  290.       hpos +:= rb.aw
  291.    }
  292.  
  293.    init_format_Vrb(rb_frame)
  294.    rb_frame.V.resize(rb_frame, 0, 0, Vmin_frame_width(rb_frame), 
  295.       Vmin_frame_height(rb_frame))
  296.  
  297.    if \ins then VInsert(frame, rb_frame, x, y)
  298.    return rb_frame
  299. end
  300.  
  301. #
  302. #  Set to no radio button selected, format size of frame.
  303. #    
  304. procedure init_format_Vrb(rb_frame)
  305.  
  306.    rb_frame.cv.value :=  V_DUMMY_ID
  307.    rb_frame.cv.curr_id := &null
  308.    rb_frame.data := ""
  309. end
  310.  
  311. #
  312. #  Get size of frame based on entries.
  313. #
  314. procedure format_Vradio_frame(self, width)
  315. local maxwidth, child
  316.  
  317.    maxwidth := \width | Vmin_frame_width(self) + 4
  318.    every child := !self.lookup do {
  319.       child.P.w := maxwidth
  320.    }
  321.    self.V.resize(self, 0, 0, maxwidth, Vmin_frame_height(self))
  322. end
  323.