docs: def on_left_click(self, event, grid, choices):
          """
          creates popup menu when user clicks on the column
          if that column is in the list of choices that get a drop-down menu.
          allows user to edit the column, but only from available values
          """
          color = self.grid.GetCellBackgroundColour(event.GetRow(), event.GetCol())
          # allow user to cherry-pick cells for editing.  gets selection of meta key for mac, ctrl key for pc
          if event.ControlDown() or event.MetaDown():
              row, col = event.GetRow(), event.GetCol()
              if (row, col) not in self.dispersed_selection:
                  self.dispersed_selection.append((row, col))
                  self.grid.SetCellBackgroundColour(row, col, 'light blue')
              else:
                  self.dispersed_selection.remove((row, col))
                  self.grid.SetCellBackgroundColour(row, col, color)# 'white'
              self.grid.ForceRefresh()
              return
          if event.ShiftDown(): # allow user to highlight multiple consecutive cells in a column
              previous_col = self.grid.GetGridCursorCol()
              previous_row = self.grid.GetGridCursorRow()
              col = event.GetCol()
              row = event.GetRow()
              if col != previous_col:
                  return
              else:
                  if row > previous_row:
                      row_range = list(range(previous_row, row+1))
                  else:
                      row_range = list(range(row, previous_row+1))
              for r in row_range:
                  self.grid.SetCellBackgroundColour(r, col, 'light blue')
                  self.selection.append((r, col))
              self.grid.ForceRefresh()
              return
  
          selection = False
  
          if self.dispersed_selection:
              is_dispersed = True
              selection = self.dispersed_selection
  
          if self.selection:
              is_dispersed = False
              selection = self.selection
  
          try:
              col = event.GetCol()
              row = event.GetRow()
          except AttributeError:
              row, col = selection[0][0], selection[0][1]
  
          self.grid.SetGridCursor(row, col)
  
          if col in list(choices.keys()): # column should have a pop-up menu
              menu = wx.Menu()
              two_tiered = choices[col][1]
              choices = choices[col][0]
              if not two_tiered: # menu is one tiered
                  if 'CLEAR cell of all values' not in choices:
                      choices.insert(0, 'CLEAR cell of all values')
                  for choice in choices:
                      if not choice:
                          choice = " " # prevents error if choice is an empty string
                      menuitem = menu.Append(wx.ID_ANY, str(choice))
                      self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), menuitem)
                  self.show_menu(event, menu)
              else: # menu is two_tiered
                  clear = menu.Append(-1, 'CLEAR cell of all values')
                  self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), clear)
                  for choice in sorted(choices.items()):
                      submenu = wx.Menu()
                      for item in choice[1]:
                          menuitem = submenu.Append(-1, str(item))
                          self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), menuitem)
                      menu.Append(-1, choice[0], submenu)
                  self.show_menu(event, menu)
  
          if selection:
              # re-whiten the cells that were previously highlighted
              for row, col in selection:
                  self.grid.SetCellBackgroundColour(row, col, self.col_color)
              self.dispersed_selection = []
              self.selection = []
              self.grid.ForceRefresh()