@ -11,7 +11,7 @@ local widgets = require('gui.widgets')
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					HotspotMenuWidget  =  defclass ( HotspotMenuWidget ,  overlay.OverlayWidget ) HotspotMenuWidget  =  defclass ( HotspotMenuWidget ,  overlay.OverlayWidget )  
			
		
	
		
		
			
				
					
					HotspotMenuWidget.ATTRS { HotspotMenuWidget.ATTRS {  
			
		
	
		
		
			
				
					
					    default_pos = { x = 1 , y = 2 } , 
    default_pos = { x = 1 , y = 3 } , 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    hotspot = true , 
    hotspot = true , 
 
			
		
	
		
		
			
				
					
					    viewscreens = { ' dwarfmode ' } , 
    viewscreens = { ' dwarfmode ' } , 
 
			
		
	
		
		
			
				
					
					    overlay_onupdate_max_freq_seconds = 0 , 
    overlay_onupdate_max_freq_seconds = 0 , 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -48,8 +48,8 @@ OVERLAY_WIDGETS = {menu=HotspotMenuWidget}
 
			
		
	
		
		
			
				
					
					-- ---------- -- -- ---------- --  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					local  ARROW  =  string.char ( 26 ) local  ARROW  =  string.char ( 26 )  
			
		
	
		
		
			
				
					
					local  M ENU_WIDTH =  42  local  M AX_LIST_WIDTH =  45   
			
				
				
			
		
	
		
		
			
				
					
					local  M ENU_HEIGHT =  12  local  M AX_LIST_HEIGHT =  15   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					MenuScreen  =  defclass ( MenuScreen ,  gui.Screen ) MenuScreen  =  defclass ( MenuScreen ,  gui.Screen )  
			
		
	
		
		
			
				
					
					MenuScreen.ATTRS { MenuScreen.ATTRS {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -59,32 +59,90 @@ MenuScreen.ATTRS{
 
			
		
	
		
		
			
				
					
					    bindings = DEFAULT_NIL , 
    bindings = DEFAULT_NIL , 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					-- get a map from the binding string to a list of hotkey strings that all  
			
		
	
		
		
			
				
					
					-- point to that binding  
			
		
	
		
		
			
				
					
					local  function  get_bindings_to_hotkeys ( hotkeys ,  bindings )  
			
		
	
		
		
			
				
					
					    local  bindings_to_hotkeys  =  { } 
 
			
		
	
		
		
			
				
					
					    for  _ , hotkey  in  ipairs ( hotkeys )  do 
 
			
		
	
		
		
			
				
					
					        local  binding  =  bindings [ hotkey ] 
 
			
		
	
		
		
			
				
					
					        table.insert ( ensure_key ( bindings_to_hotkeys ,  binding ) ,  hotkey ) 
 
			
		
	
		
		
			
				
					
					    end 
 
			
		
	
		
		
			
				
					
					    return  bindings_to_hotkeys 
 
			
		
	
		
		
			
				
					
					end  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					-- number of non-text tiles: icon, space, space between cmd and hk, scrollbar  
			
		
	
		
		
			
				
					
					local  LIST_BUFFER  =  2  +  1  +  1  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					local  function  get_choices ( hotkeys ,  bindings ,  is_inverted )  
			
		
	
		
		
			
				
					
					    local  choices ,  max_width ,  seen  =  { } ,  0 ,  { } 
 
			
		
	
		
		
			
				
					
					    local  bindings_to_hotkeys  =  get_bindings_to_hotkeys ( hotkeys ,  bindings ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    -- build list choices 
 
			
		
	
		
		
			
				
					
					    for  _ , hotkey  in  ipairs ( hotkeys )  do 
 
			
		
	
		
		
			
				
					
					        local  command  =  bindings [ hotkey ] 
 
			
		
	
		
		
			
				
					
					        if  seen [ command ]  then  goto  continue  end 
 
			
		
	
		
		
			
				
					
					        seen [ command ]  =  true 
 
			
		
	
		
		
			
				
					
					        local  hk_width ,  tokens  =  0 ,  { } 
 
			
		
	
		
		
			
				
					
					        for  _ , hk  in  ipairs ( bindings_to_hotkeys [ command ] )  do 
 
			
		
	
		
		
			
				
					
					            if  hk_width  ~=  0  then 
 
			
		
	
		
		
			
				
					
					                table.insert ( tokens ,  ' ,  ' ) 
 
			
		
	
		
		
			
				
					
					                hk_width  =  hk_width  +  2 
 
			
		
	
		
		
			
				
					
					            end 
 
			
		
	
		
		
			
				
					
					            table.insert ( tokens ,  { text = hk ,  pen = COLOR_LIGHTGREEN } ) 
 
			
		
	
		
		
			
				
					
					            hk_width  =  hk_width  +  # hk 
 
			
		
	
		
		
			
				
					
					        end 
 
			
		
	
		
		
			
				
					
					        local  command_str  =  command 
 
			
		
	
		
		
			
				
					
					        if  hk_width  +  # command  +  LIST_BUFFER  >  MAX_LIST_WIDTH  then 
 
			
		
	
		
		
			
				
					
					            local  max_command_len  =  MAX_LIST_WIDTH  -  hk_width  -  LIST_BUFFER 
 
			
		
	
		
		
			
				
					
					            command_str  =  command : sub ( 1 ,  max_command_len  -  3 )  ..  ' ... ' 
 
			
		
	
		
		
			
				
					
					        end 
 
			
		
	
		
		
			
				
					
					        table.insert ( tokens ,  1 ,  { text = command_str } ) 
 
			
		
	
		
		
			
				
					
					        local  choice  =  { icon = ARROW ,  command = command ,  text = tokens , 
 
			
		
	
		
		
			
				
					
					                        hk_width = hk_width } 
 
			
		
	
		
		
			
				
					
					        max_width  =  math.max ( max_width ,  hk_width  +  # command_str  +  LIST_BUFFER ) 
 
			
		
	
		
		
			
				
					
					        table.insert ( choices ,  is_inverted  and  1  or  # choices  +  1 ,  choice ) 
 
			
		
	
		
		
			
				
					
					        :: continue :: 
 
			
		
	
		
		
			
				
					
					    end 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    -- adjust width of command fields so the hotkey tokens are right justified 
 
			
		
	
		
		
			
				
					
					    for  _ , choice  in  ipairs ( choices )  do 
 
			
		
	
		
		
			
				
					
					        local  command_token  =  choice.text [ 1 ] 
 
			
		
	
		
		
			
				
					
					        command_token.width  =  max_width  -  choice.hk_width  -  3 
 
			
		
	
		
		
			
				
					
					    end 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    return  choices ,  max_width 
 
			
		
	
		
		
			
				
					
					end  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					function  MenuScreen : init ( ) function  MenuScreen : init ( )  
			
		
	
		
		
			
				
					
					    self.mouseover  =  false 
    self.mouseover  =  false 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    local  list_frame  =  copyall ( self.hotspot_frame ) 
    local  choices , list_width  =  get_choices ( self.hotkeys ,  self.bindings , 
 
			
				
				
			
		
	
		
		
			
				
					
					    list_frame.w  =  MENU_WIDTH 
                                           self.hotspot_frame . b ) 
 
			
				
				
			
		
	
		
		
			
				
					
					    list_frame.h  =  MENU_HEIGHT 
 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    local  help_frame  =  { w = MENU_WIDTH ,  l = list_frame.l ,  r = list_frame.r } 
    local  list_frame  =  copyall ( self.hotspot_frame ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    list_frame.w  =  list_width  +  2 
 
			
		
	
		
		
			
				
					
					    list_frame.h  =  math.min ( # choices ,  MAX_LIST_HEIGHT )  +  2 
 
			
		
	
		
		
			
				
					
					    if  list_frame.t  then 
    if  list_frame.t  then 
 
			
		
	
		
		
			
				
					
					        help_frame.t  =  list_frame.t  +  MENU_HEIGHT  +  1 
        list_frame.t =  math.max ( 0 ,  list_frame.t  -  1 )  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    else 
    else 
 
			
		
	
		
		
			
				
					
					        help_frame.b  =  list_frame.b  +  MENU_HEIGHT  +  1 
        list_frame.b  =  math.max ( 0 ,  list_frame.b  -  1 ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    end 
 
			
		
	
		
		
			
				
					
					    if  list_frame.l  then 
 
			
		
	
		
		
			
				
					
					        list_frame.l  =  math.max ( 0 ,  list_frame.l  -  1 ) 
 
			
		
	
		
		
			
				
					
					    else 
 
			
		
	
		
		
			
				
					
					        list_frame.r  =  math.max ( 0 ,  list_frame.r  -  1 ) 
 
			
		
	
		
		
			
				
					
					    end 
    end 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    local  bindings  =  self.bindings 
    local  help_frame  =  { w = list_frame.w ,  l = list_frame.l ,  r = list_frame.r } 
 
			
				
				
			
		
	
		
		
			
				
					
					    local  choices  =  { } 
    if  list_frame.t  then 
 
			
				
				
			
		
	
		
		
			
				
					
					    for  _ , hotkey  in  ipairs ( self.hotkeys )  do 
        help_frame.t  =  list_frame.t  +  list_frame.h  +  1 
 
			
				
				
			
		
	
		
		
			
				
					
					        local  command  =  bindings [ hotkey ] 
    else 
 
			
				
				
			
		
	
		
		
			
				
					
					        local  choice_text  =  command  ..  ( '  (%s) ' ) : format ( hotkey ) 
        help_frame.b  =  list_frame.b  +  list_frame.h  +  1 
 
			
				
				
			
		
	
		
		
			
				
					
					        local  choice  =  { 
 
			
		
	
		
		
			
				
					
					            icon = ARROW ,  text = choice_text ,  command = command } 
 
			
		
	
		
		
			
				
					
					        table.insert ( choices ,  list_frame.b  and  1  or  # choices  +  1 ,  choice ) 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					    end 
    end 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    self : addviews { 
    self : addviews { 
 
			
		
	
		
		
			
				
					
					        widgets.ResizingPanel { 
        widgets.ResizingPanel { 
 
			
		
	
		
		
			
				
					
					            view_id = ' list_panel ' , 
 
			
		
	
		
		
			
				
					
					            autoarrange_subviews = true , 
            autoarrange_subviews = true , 
 
			
		
	
		
		
			
				
					
					            frame = list_frame , 
            frame = list_frame , 
 
			
		
	
		
		
			
				
					
					            frame_style = gui.GREY_LINE_FRAME , 
            frame_style = gui.GREY_LINE_FRAME , 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -164,6 +222,7 @@ function MenuScreen:onRenderFrame(dc, rect)
 
			
		
	
		
		
			
				
					
					end end  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					function  MenuScreen : onRenderBody ( dc ) function  MenuScreen : onRenderBody ( dc )  
			
		
	
		
		
			
				
					
					    local  panel  =  self.subviews . list_panel 
 
			
		
	
		
		
			
				
					
					    local  list  =  self.subviews . list 
    local  list  =  self.subviews . list 
 
			
		
	
		
		
			
				
					
					    local  idx  =  list : getIdxUnderMouse ( ) 
    local  idx  =  list : getIdxUnderMouse ( ) 
 
			
		
	
		
		
			
				
					
					    if  idx  and  idx  ~=  self.last_mouse_idx  then 
    if  idx  and  idx  ~=  self.last_mouse_idx  then 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -173,8 +232,9 @@ function MenuScreen:onRenderBody(dc)
 
			
		
	
		
		
			
				
					
					        list : setSelected ( idx ) 
        list : setSelected ( idx ) 
 
			
		
	
		
		
			
				
					
					        self.mouseover  =  true 
        self.mouseover  =  true 
 
			
		
	
		
		
			
				
					
					        self.last_mouse_idx  =  idx 
        self.last_mouse_idx  =  idx 
 
			
		
	
		
		
			
				
					
					    elseif  not  idx  and  self.mouseover  then 
    elseif  not  panel : getMousePos ( gui.ViewRect { rect = panel.frame_rect } ) 
 
			
				
				
			
		
	
		
		
			
				
					
					        -- once the mouse has entered the list area, leaving it again should 
            and  self.mouseover  then 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        -- once the mouse has entered the list area, leaving the frame should 
 
			
		
	
		
		
			
				
					
					        -- close the menu screen 
        -- close the menu screen 
 
			
		
	
		
		
			
				
					
					        self : dismiss ( ) 
        self : dismiss ( ) 
 
			
		
	
		
		
			
				
					
					    end 
    end