Support widgets: Widgets.oz

Source File

functor 
 
import 
   Tk
   TkTools
 
   Configure(images:    Images
             colors:    Colors
             fonts:     Fonts
             capacity:  Capacity
             delta:     Delta
             delay:     DelayMove)
   Country(getCoord
           width
           height
           getGraph
           getRoute)
    
export 
   History
   EntryChooser
   Truck
   map:         CountryMap
 
define 
 
   local 
      An            = 'announce: ' 
      Sp            = '          ' 
      HistoryWidth  = 60
      HistoryHeight = 8
      HistoryFont   = '-adobe-helvetica-medium-r-normal-*-*-100*' 
      HistoryBg     = '#fffff0' 
   in 
       
      class History from Tk.toplevel 
         attr 
            mapped:false 
         feat 
            text entry var
             
         meth init(master:M suffix:U)
            History, tkInit(parent:M.toplevel title:'History: '#U withdraw:true 
                            delete: self # unmap)
            F = {New TkTools.textframe tkInit(parent:self text:'History: '#U)}
            T = {New Tk.text tkInit(parent:F.inner
                                    width:HistoryWidth height:HistoryHeight
                                    bg:HistoryBg font:HistoryFont
                                    highlightthickness: 0)}
            S = {New Tk.scrollbar tkInit(parent:F.inner)}
            V = {New Tk.variable tkInit(false)}
            E = {New Tk.menuentry.checkbutton
                 tkInit(parent:   M.menu.windows.menu
                        label:    U
                        variable: V
                        action:   self # toggle)}
         in 
            {T tkBind(event:'<Map>'   action: self # map)}
            {T tkBind(event:'<Unmap>' action: self # unmap)}
            {Tk.addYScrollbar T S}
            {Tk.batch [pack(T S side:left fill:y) pack(F)]}
            self.text  = T
            self.entry = E
            self.var   = V
         end 
          
         meth setMapped(B)
            mapped <- B
            {self.var tkSet(B)}
         end 
          
         meth toggle 
            {Tk.send wm(if @mapped then 
                           iconify
                        else 
                           deiconify
                        end self)}
            History, setMapped({Not @mapped})
         end 
          
         meth map 
            if {Not @mapped} then 
               {Tk.send wm(deiconify self)}
            end 
            History, setMapped(true)
         end 
          
         meth unmap 
            if @mapped then 
               {Tk.send wm(iconify self)}
            end 
         History, setMapped(false)
         end 
          
         meth print(V)
            Text = self.text
         in 
            {Text tk(insert 'end' V#'\n')}
            {Text tk(yview pickplace:'end')}
         end 
          
         meth announce(what:W weight:N src:S dst:D reply:R<=unit ...)
            History,print(An#W#', '#N#'\n'# 
                          Sp#'from: '#S#' to: '#D# 
                          case R
                          of grant  then '\n'#Sp#'granted' 
                          [] reject then '\n'#Sp#'rejected' 
                          else '' 
                          end)
         end 
          
         meth tkClose 
            {self.entry tkClose}
            Tk.toplevel, tkClose
         end 
      end 
       
   end 
    
   local 
      proc {DefAction _}
         skip 
      end 
      TextHeight    = 6
      BigTextWidth  = 17
   in 
      class EntryChooser 
         from Tk.frame 
         feat entry button toplevel action
         attr entries
             
         meth tkInit(parent:P toplevel:T entries:Es action:A<=DefAction)
            Tk.frame, tkInit(parent:P highlightthickness:2)
            Entry  = {New Tk.entry tkInit(parent:             self 
                                          width:              BigTextWidth
                                          bg:                 Colors.textBg
                                          font:               Fonts.text
                                          highlightthickness: 0)}
            Button = {New Tk.button tkInit(parent: self 
                                           image: Images.down
                                           highlightthickness:0
                                           state:  if Es==nil then disabled
                                                   else normal
                                                   end 
                                           action: self # OpenChooser)}
         in 
            self.entry    = Entry
            self.button   = Button
            self.toplevel = T
            self.action   = A
            EntryChooser,entries(Es)
            {Tk.send pack(self.entry self.button side:left fill:y)}
         end 
          
         meth entries(Es)
            entries <- Es
            if Es\=nil then 
               {self.entry tk(delete 0 'end')}
               {self.entry tk(insert 0 Es.1)}
            end 
         end 
          
         meth OpenChooser 
            [X Y H] = {Map [rootx rooty height]
                       fun {$ WI} {Tk.returnInt winfo(WI self)} end}
            T = {New Tk.toplevel tkInit(withdraw: true 
                                        parent:   self 
                                        cursor:   top_left_arrow)}
            F = {New Tk.frame tkInit(parent:T bg:black bd:2)}
            L = {New Tk.listbox   tkInit(parent:F height:TextHeight
                                         width:BigTextWidth
                                         bg:white
                                         exportselection:false)}
            S = {New Tk.scrollbar tkInit(parent:F width:10)}
         in 
            {L tk(insert 0 b(@entries))}
            {Tk.addYScrollbar L S}
            {self.toplevel tkBind(event:'<1>' action:T#tkClose)}
            {L tkBind(event:'<1>' 
                      action: proc {$}
                                 A={L tkReturnAtom(get
                                                   l(L curselection) $)}
                              in 
                                 {self.entry tk(delete 0 'end')}
                                 {self.entry tk(insert 0 A)}
                                 {self.action A}
                                 {T tkClose}
                              end)}
            {L tkBind(event:'<2>' 
                      action: T # tkClose)}
            {Tk.batch [wm(overrideredirect T true)
                       wm(geometry T '+'#X#'+'#Y+H)
                       pack(L S side:left fill:both)
                       pack(F)
                       wm(deiconify T)]}
         end 
          
      end 
   end 
 
   local 
      LoadLeftX   =  ~3.0
      LoadRightX  = ~24.0
      LoadY       =  ~8.0
      LoadHeight  =   6.0
      LoadWidth   =  27.0
 
      ColMan      = {New class $ from BaseObject 
                            prop final
                            attr ColS: local Cs in 
                                          Cs={Append Colors.truck Cs} Cs
                                       end 
                            meth get(?Col) ColR in Col|ColR=(ColS<-ColR) end 
                         end noop}
   in 
      class Truck 
         from Tk.canvasTag 
         prop final
         feat 
            parent load fill driver
         attr 
            city: unit 
            turn: left
            load: 0
            x:    0.0
            y:    0.0
             
         meth init(parent:P city:C driver:D)
            X Y
         in 
            {Country.getCoord C ?X ?Y}
            city <- C
            Truck, tkInit(parent:P)
            x <- {IntToFloat X}
            y <- {IntToFloat Y}
            self.parent = P
            self.load   = {New Tk.canvasTag tkInit(parent:P)}
            self.fill   = {ColMan get($)}
            self.driver = D
            Truck, draw
         end 
          
         meth draw 
            P = self.parent
            D = @turn
            X = @x
            Y = @y
         in 
            Truck, tk(delete)
            if Tk.isColor then 
               %% Create the truck's window
               {P tk(create image X Y  
                     image: Images.truck.win.D
                     tags:  self)}
               {P tk(create image X Y
                     image: Images.truck.fill.(self.fill).D
                     tags:  self)}
            end 
            %% Create the frame for truck (better visibility)  
            {P tk(create image X Y  
                  image: Images.truck.frame.D
                  tags:  self)}
            {P tk(crea rectangle 0 0 0 0
                  fill:    Colors.good
                  outline: '' 
                  tags:    q(self self.load))}
            Truck, load(@load)
         end 
          
         meth load(L)
            W  = {IntToFloat L} / {IntToFloat Capacity} * LoadWidth
            X0 = @+ case @turn
                      of left  then LoadLeftX
                      [] right then LoadRightX + LoadWidth - W
                      end 
            X1 = X0 + W
            Y0 = @+ LoadY
            Y1 = Y0 + LoadHeight
         in 
            load <- L
            {self.load tk(coords X0 Y0 X1 Y1)}
         end 
          
         meth turn(X0 X1)
            NewTurn = if X0<X1 then right else left end 
         in 
            if @turn\=NewTurn then 
               turn <- NewTurn Truck, draw
            end 
         end 
          
         meth drive(Dst Load NextLoad)
            X Y
         in 
            {Country.getCoord @city ?X ?Y}
            Truck,load(Load)
            Truck,Route({Country.getRoute @city Dst}
                        {IntToFloat X} {IntToFloat Y})
            Truck,load(NextLoad)
            Truck,{self.driver getMessage($)}
         end 
          
         meth Move(N XS YS)
            if N\=then 
               Truck,tk(move XS YS)
               x <- @+ XS y <- @+ YS
               {Delay DelayMove}
               Truck,Move(N-1 XS YS)
            end 
         end 
          
         meth Route(Rs SrcX SrcY)
            %% Moves the truck according to the route "Rs"
            Src#Dist|Rr = Rs
         in 
            case Rr of Dst#_|then 
               Steps = Dist div Delta
               Ratio = {IntToFloat Steps}
               DX DY
               {Country.getCoord Dst ?DX ?DY}
               DstX  = {IntToFloat DX}
               DstY  = {IntToFloat DY}
            in 
               %% Turn the truck
               Truck,turn(SrcX DstX)
               Truck,Move(Steps (DstX - SrcX) / Ratio (DstY - SrcY) / Ratio)
               %% correct
               Truck,tk(move DstX - @x DstY - @y)
               x <- DstX
               y <- DstY
               Truck,Route(Rr DstX DstY)
            [] nil then 
               city <- Src
            end 
         end 
          
         meth close 
            Truck, tkClose
         end 
          
      end 
   end 
 
   local 
      TownSize   = 3
      TextOffset = 11
   in 
 
      class CountryMap 
         from Tk.canvas 
       
         meth init(parent:P)
            Tk.canvas,tkInit(parent: P.toplevel
                             relief: sunken
                             bd:     3
                             width:  Country.width
                             height: Country.height
                             bg:     Colors.back)
            {ForAll {Country.getGraph}
             proc {$ SPDs}
                Src#(SrcX#SrcY)#Dsts = SPDs
                Tag                  = {New Tk.canvasTag tkInit(parent:self)}
             in 
                {Tag tkBind(event:'<1>' action:P # putSrc(Src))}
                {Tag tkBind(event:'<2>' action:P # putDst(Src))}
                {ForAll Dsts
                 proc {$ DstX#DstY}
                    {self tk(create line SrcX SrcY DstX DstY
                             fill: Colors.street)}
                 end}
                {self tk(create rectangle
                         SrcX-TownSize SrcY-TownSize
                         SrcX+TownSize SrcY+TownSize
                         fill: Colors.city
                         tags: Tag)}
                {self tk(create text SrcX SrcY+TextOffset
                         text: Src
                         font: Fonts.text
                         tags: Tag)}
             end}
         end 
          
      end 
       
   end 
    
 
end 
 


Version 1.4.0 (20080702)