Modify the code so that the datatypes in the change datatype menu are opened as a sidemenu. Python Code: class Header:
    """Combined class for handling header UI and column data types functionality."""
    
    DATA_TYPE_OPTIONS = ["string", "integer", "float", "boolean"]
    
    def __init__(self, root: tk.Tk, app: 'TableApp'):
        self.root = root
        self.app = app
        self.style = app.style
        self.colors = app.colors
        self.fonts = app.fonts
        self.dimensions = app.dimensions
        self.table_name_label = None
        self.lower_header_frame = None
        self.result = None
        self._setup_header()

    def _setup_header(self) -> None:
        header_frame = self._setup_main_frame()
        self._setup_upper_section(header_frame)
        self._setup_lower_section(header_frame)

    def _setup_main_frame(self) -> tk.Frame:
        header_frame = create_frame(parent=self.root, width=None, bg=self.colors["background"])
        header_frame.grid(row=0, column=1, columnspan=2, sticky="ew")
        header_frame.config(height=self.dimensions["header_height"])
        header_frame.grid_propagate(False)
        header_frame.grid_rowconfigure(0, weight=0)
        header_frame.grid_rowconfigure(1, weight=0)
        for i in range(5):
            header_frame.grid_columnconfigure(i, weight=1 if i == 4 else 0)
        return header_frame

    def _setup_upper_section(self, parent: tk.Frame) -> None:
        upper_frame = create_frame(parent=parent, width=None, bg=self.colors["background"])
        upper_frame.grid(row=0, column=0, columnspan=5, sticky="ew", pady=(0, 10))
        upper_frame.grid_columnconfigure(5, weight=1)
        self._add_upper_content(upper_frame)

    def _add_upper_content(self, frame: tk.Frame) -> None:
        tk.Label(frame, text="Data > ",
                bg=self.colors["background"], fg=self.colors["header_info"],
                font=self.fonts["header_info"]).grid(row=0, column=0, padx=22, pady=(22, 0), sticky="nw")

        self.table_name_label = tk.Label(frame,
                                      text=self.app.current_table_name or "No Table Selected",
                                      bg=self.colors["background"], fg=self.colors["text"],
                                      font=self.fonts["header_info"])
        self.table_name_label.grid(row=0, column=0, padx=(88, 10), pady=(22, 0), sticky="nw")
        self._setup_settings_section(frame)

    def _setup_settings_section(self, frame: tk.Frame) -> None:
        settings_container = tk.Frame(frame, bg=self.colors["background"])
        settings_container.grid(row=0, column=5, padx=(0, 40), pady=(22, 0), sticky="ne")

        settings_label = tk.Label(settings_container, text="...",
                               bg=self.colors["background"], fg=self.colors["text"],
                               cursor="hand2", anchor="e", font=self.fonts["text"])
        settings_label.pack(anchor="e")

        def on_enter(_): settings_label.config(bg=self.colors["button_selected"])
        def on_leave(_): settings_label.config(bg=self.colors["background"])

        settings_menu = self._create_settings_menu()
        settings_label.bind("<Button-1>", lambda e: settings_menu.post(e.x_root, e.y_root))
        settings_label.bind("<Enter>", on_enter)
        settings_label.bind("<Leave>", on_leave)

    def _create_settings_menu(self) -> tk.Menu:
        menu = tk.Menu(self.root, tearoff=0, bg=self.colors["background"],
                     fg=self.colors["text"], font=self.fonts["header_info"])

        stats_menu = tk.Menu(menu, tearoff=0, bg=self.colors["background"],
                          fg=self.colors["text"], font=self.fonts["header_info"])
        menu.add_cascade(label="Stats", menu=stats_menu)

        stats_menu.add_command(label="Boolean Count: 0", command=None)
        self.true_counter_label = stats_menu

        menu_items = [
            ("Export Table", self.app.table_io.export_table),
            ("Import Table", self.app.table_io.import_file),
            ("Change Datatypes", self.show_datatype_dialog)
        ]

        for label, command in menu_items:
            menu.add_command(label=label, command=command)

        return menu

    def _setup_lower_section(self, parent: tk.Frame) -> None:
        self.lower_header_frame = create_frame(
            parent=parent, width=None, bg=self.colors["background"]
        )
        self.lower_header_frame.grid(row=1, column=0, columnspan=5, sticky="ew")

    def update_true_counter(self, count_text: str) -> None:
        if hasattr(self, 'true_counter_label'):
            self.true_counter_label.entryconfig(0, label=f"Boolean Count: {count_text}")

    def show_datatype_dialog(self) -> None:
        """Show menu for changing column data types."""
        table_name = self.app.current_table_name
        if not table_name:
            messagebox.showwarning("No Table Selected", "Please select a table to change datatypes.")
            return
    
        current_headers = self.app.current_sheet.headers() if self.app.current_sheet else []
        self.app.data_manager.headers[table_name] = current_headers
    
        data_types = self.app.data_manager.tables_data[table_name].get("data_types", [])
        while len(data_types) < len(current_headers):
            data_types.append('string')
    
        # Create popup menu
        self.datatype_menu = tk.Menu(self.root, tearoff=0, bg=self.colors["background"],
                                    fg=self.colors["text"], font=self.fonts["text"])
        
        self.datatype_vars = {}  # Store StringVars for each header
        
        for header, dtype in zip(current_headers, data_types):
            var = tk.StringVar(value=dtype)
            self.datatype_vars[header] = var
            
            # Create cascade menu item with current datatype
            self.datatype_menu.add_command(
                label=f"{header}: {dtype}",
                command=lambda h=header: self._show_type_options(h)
            )
    
        # Add Apply button at the bottom
        self.datatype_menu.add_separator()
        self.datatype_menu.add_command(label="Apply Changes", command=self._apply_datatype_changes)
        
        # Show menu at cursor position
        self.datatype_menu.post(self.root.winfo_pointerx(), self.root.winfo_pointery())
    
    def _show_type_options(self, header: str) -> None:
        """Show submenu with datatype options."""
        # Create options menu
        options_menu = tk.Menu(self.root, tearoff=0, bg=self.colors["background"],
                              fg=self.colors["text"], font=self.fonts["text"])
        
        current_type = self.datatype_vars[header].get()
        
        for option in self.DATA_TYPE_OPTIONS:
            options_menu.add_command(
                label=option,
                command=lambda h=header, t=option: self._on_datatype_change(h, t),
                background=self.colors["button_selected"] if option == current_type else self.colors["background"]
            )
        
        # Show options menu next to main menu
        options_menu.post(
            self.root.winfo_pointerx() + 50,
            self.root.winfo_pointery()
        )
    
    def _on_datatype_change(self, header: str, new_type: str) -> None:
        """Update datatype when option is selected."""
        self.datatype_vars[header].set(new_type)
        
        # Update the label in the main menu
        for i in range(self.datatype_menu.index('end') + 1):
            try:
                label = self.datatype_menu.entrycget(i, "label")
                if label.startswith(header + ":"):
                    self.datatype_menu.entryconfigure(i, label=f"{header}: {new_type}")
                    break
            except:
                continue
        
        # Repost the main menu to keep it open
        self.datatype_menu.post(self.root.winfo_pointerx(), self.root.winfo_pointery())
    
    def _apply_datatype_changes(self) -> None:
        """Apply the datatype changes and update the table."""
        table_name = self.app.current_table_name
        new_data_types = [self.datatype_vars[header].get() 
                         for header in self.app.current_sheet.headers()]
        
        self.app.data_manager.tables_data[table_name]["data_types"] = new_data_types
        self.app.data_manager.save_data()
        self.app.table_display.apply_column_data_types(new_data_types)
        self.app.table_display.process_and_save_current_sheet_data()
        self.app.refresh_table()
        
        # Unpost the menu after applying changes
        self.datatype_menu.unpost()