@@ -84,11 +84,11 @@ def _create_main_paned_window(pathbrowser_instance):
8484 pathbrowser_instance .paned = ttk .PanedWindow (
8585 pathbrowser_instance , orient = tk .HORIZONTAL
8686 )
87- pathbrowser_instance .paned .pack (fill = tk .BOTH , expand = True , padx = 5 , pady = 5 )
87+ pathbrowser_instance .paned .pack (fill = tk .BOTH , expand = True , padx = 2 , pady = 2 )
8888
8989 # Left pane - Directory tree
9090 pathbrowser_instance .tree_frame = ttk .Frame (pathbrowser_instance .paned )
91- pathbrowser_instance .paned .add (pathbrowser_instance .tree_frame , weight = 1 )
91+ pathbrowser_instance .paned .add (pathbrowser_instance .tree_frame , weight = 2 )
9292
9393 # Directory tree with icons and better styling
9494 pathbrowser_instance .tree = ttk .Treeview (
@@ -97,13 +97,55 @@ def _create_main_paned_window(pathbrowser_instance):
9797 selectmode = "browse" ,
9898 height = 10 , # Reduced height for smaller dialog
9999 )
100- pathbrowser_instance .tree .pack (fill = tk .BOTH , expand = True , padx = 5 , pady = 5 )
100+ pathbrowser_instance .tree .pack (fill = tk .BOTH , expand = True , padx = 2 , pady = 2 )
101+
102+ # Set initial sash position to give 200px to the tree view (DPI-scaled)
103+ # This will be applied after the paned window is fully created
104+ def set_dpi_scaled_sash ():
105+ try :
106+ # Get DPI scaling factor
107+ from tkface .win .dpi import get_scaling_factor
108+ scaling_factor = get_scaling_factor (pathbrowser_instance )
109+ dpi_scaled_width = int (200 * scaling_factor )
110+ pathbrowser_instance .paned .sashpos (0 , dpi_scaled_width )
111+ except Exception :
112+ # Fallback to unscaled 200px if DPI detection fails
113+ pathbrowser_instance .paned .sashpos (0 , 200 )
114+
115+ pathbrowser_instance .after (100 , set_dpi_scaled_sash )
101116
102117 # Configure tree style for better appearance
103118 style = ttk .Style ()
104119 # Set row height based on OS - Windows uses original spacing, others use compact
105120 row_height = 25 if utils .IS_WINDOWS else 20
106121 style .configure ("Treeview" , rowheight = row_height )
122+
123+ # Bind to tree selection to adjust indent based on current level
124+ def adjust_tree_indent (event = None ):
125+ """Adjust tree indent based on current directory level."""
126+ try :
127+ current_dir = pathbrowser_instance .state .current_dir
128+ # Count directory depth from root
129+ path_parts = Path (current_dir ).parts
130+ depth = len (path_parts ) - 1 # Subtract 1 for root
131+
132+ # Calculate indent: base indent minus depth-based offset
133+ # This reduces left padding for deeper directories
134+ base_indent = 20
135+ depth_offset = min (depth * 2 , 15 ) # Max 15px reduction
136+ adjusted_indent = max (base_indent - depth_offset , 5 ) # Min 5px
137+
138+ # Apply the adjusted indent
139+ style .configure ("Treeview" , indent = adjusted_indent )
140+
141+ except Exception as e :
142+ logger .debug ("Failed to adjust tree indent: %s" , e )
143+
144+ # Bind to directory changes to adjust indent
145+ pathbrowser_instance .tree .bind ("<<TreeviewSelect>>" , adjust_tree_indent )
146+
147+ # Initial adjustment
148+ pathbrowser_instance .after (100 , adjust_tree_indent )
107149
108150
109151def _create_file_list (pathbrowser_instance ):
@@ -149,23 +191,23 @@ def _create_file_list(pathbrowser_instance):
149191 )
150192
151193 pathbrowser_instance .file_tree .column ("#0" , width = 200 , minwidth = 150 )
152- pathbrowser_instance .file_tree .column ("size" , width = 80 , minwidth = 60 )
194+ pathbrowser_instance .file_tree .column ("size" , width = 70 , minwidth = 50 )
153195 pathbrowser_instance .file_tree .column ("modified" , width = 120 , minwidth = 100 )
154- pathbrowser_instance .file_tree .column ("type" , width = 100 , minwidth = 80 )
196+ pathbrowser_instance .file_tree .column ("type" , width = 60 , minwidth = 50 )
155197
156198 # Apply OS-specific row height to file tree as well
157199 style = ttk .Style ()
158- row_height = 25 if utils . IS_WINDOWS else 20
200+ row_height = 20
159201 style .configure ("Treeview" , rowheight = row_height )
160202
161- pathbrowser_instance .file_tree .pack (fill = tk .BOTH , expand = True , padx = 5 , pady = 5 )
203+ pathbrowser_instance .file_tree .pack (fill = tk .BOTH , expand = True , padx = 2 , pady = 2 )
162204
163205
164206def _create_status_and_buttons (pathbrowser_instance ):
165207 """Create status bar and bottom buttons in a horizontal layout."""
166208 # Bottom frame containing status bar and buttons
167209 pathbrowser_instance .bottom_frame = ttk .Frame (pathbrowser_instance )
168- pathbrowser_instance .bottom_frame .pack (fill = tk .X , padx = 5 , pady = 5 , side = tk .BOTTOM )
210+ pathbrowser_instance .bottom_frame .pack (fill = tk .X , padx = 2 , pady = 2 , side = tk .BOTTOM )
169211
170212 # Status bar (left side)
171213 pathbrowser_instance .status_var = tk .StringVar ()
@@ -267,11 +309,13 @@ def _create_toolbar(pathbrowser_instance):
267309
268310def create_pathbrowser_widgets (pathbrowser_instance ):
269311 """Create the widget layout for PathBrowser."""
312+ # Pack bottom areas first so they remain visible even when window is small
270313 _create_path_navigation (pathbrowser_instance )
271- _create_main_paned_window (pathbrowser_instance )
272- _create_file_list (pathbrowser_instance )
273314 _create_status_and_buttons (pathbrowser_instance )
274315 _create_toolbar (pathbrowser_instance )
316+ # Main content takes the remaining space
317+ _create_main_paned_window (pathbrowser_instance )
318+ _create_file_list (pathbrowser_instance )
275319
276320 # Initialize view mode
277321 pathbrowser_instance .view_mode = "details"
@@ -397,25 +441,48 @@ def setup_pathbrowser_bindings(pathbrowser_instance):
397441def load_directory_tree (pathbrowser_instance ):
398442 """Load the directory tree."""
399443 pathbrowser_instance .tree .delete (* pathbrowser_instance .tree .get_children ())
444+ # Flatten view to start at the current directory level to avoid left-side slack
445+ try :
446+ base_path = Path (pathbrowser_instance .state .current_dir )
447+
448+ # List only immediate subdirectories of the current directory as top-level
449+ dirs = []
450+ for item in base_path .iterdir ():
451+ if item .is_dir ():
452+ dirs .append ((item .name , str (item )))
400453
401- # Add root directories with better icons and labels
402- if utils . IS_WINDOWS : # Windows
403- for drive in string . ascii_uppercase :
404- drive_path = f" { drive } : \\ "
405- if Path ( drive_path ). exists ():
406- # Get drive label if possible
454+ # Sort and add directories
455+ dirs . sort ( key = lambda x : x [ 0 ]. lower ())
456+
457+ for child_name , child_path in dirs :
458+ if not pathbrowser_instance . tree . exists (child_path ):
459+ # Insert as top-level item (no ancestors, no extra left indent)
407460 pathbrowser_instance .tree .insert (
408- "" , "end" , drive_path , text = drive_path , open = False
461+ "" , "end" , child_path , text = child_name , open = False
409462 )
410- # Pre-populate root level directories for better UX
411- populate_tree_node (pathbrowser_instance , drive_path )
412- else : # Unix-like
413- pathbrowser_instance .tree .insert ("" , "end" , "/" , text = "/" , open = False )
414- # Pre-populate root level directories for better UX
415- populate_tree_node (pathbrowser_instance , "/" )
416-
417- # Expand current directory path
418- expand_path (pathbrowser_instance , pathbrowser_instance .state .current_dir )
463+
464+ # Add placeholder if the directory has subdirectories (for lazy loading)
465+ with suppress (OSError , PermissionError ):
466+ has_subdirs = False
467+ for subitem in base_path .joinpath (child_name ).iterdir ():
468+ if subitem .is_dir ():
469+ has_subdirs = True
470+ break
471+ if has_subdirs :
472+ placeholder_id = f"{ child_path } _placeholder"
473+ if not pathbrowser_instance .tree .exists (placeholder_id ):
474+ pathbrowser_instance .tree .insert (
475+ child_path ,
476+ "end" ,
477+ placeholder_id ,
478+ text = lang .get ("Loading..." , pathbrowser_instance ),
479+ open = False ,
480+ )
481+ except (OSError , PermissionError ) as e :
482+ logger .warning ("Failed to load directory tree for %s: %s" , base_path , e )
483+ pathbrowser_instance .status_var .set (
484+ f"{ lang .get ('Cannot access:' , pathbrowser_instance )} { base_path .name } "
485+ )
419486
420487
421488def populate_tree_node (pathbrowser_instance , parent ):
0 commit comments