fortrangoingonforty/sniffly / 18904d0

Browse files

add close buttons with prevent-last-tab logic

Authored by espadonne
SHA
18904d0801399f35d9b5f04164fe7824e36992e7
Parents
13f475d
Tree
4d97a4d

1 changed file

StatusFile+-
M src/gui/tab_widget.f90 71 6
src/gui/tab_widget.f90modified
@@ -23,6 +23,7 @@ module tab_widget
2323
 
2424
   ! Track button pointers to determine which tab was clicked
2525
   type(c_ptr), dimension(MAX_TABS), save :: tab_buttons = c_null_ptr
26
+  type(c_ptr), dimension(MAX_TABS), save :: close_buttons = c_null_ptr
2627
 
2728
   ! Tab click callback interface
2829
   abstract interface
@@ -75,7 +76,7 @@ contains
7576
 
7677
   ! Refresh tab bar (rebuild all tab buttons)
7778
   subroutine refresh_tab_bar()
78
-    type(c_ptr) :: plus_btn, tab_btn, child, next_child
79
+    type(c_ptr) :: plus_btn, tab_btn, close_btn, tab_container, child, next_child
7980
     type(tab_state), pointer :: tab
8081
     integer :: i
8182
     character(len=256) :: label_text
@@ -96,8 +97,9 @@ contains
9697
       child = next_child
9798
     end do
9899
 
99
-    ! Clear button pointer array
100
+    ! Clear button pointer arrays
100101
     tab_buttons(:) = c_null_ptr
102
+    close_buttons(:) = c_null_ptr
101103
 
102104
     print *, "Cleared old tab bar widgets"
103105
 
@@ -113,12 +115,15 @@ contains
113115
       tab => get_tab(i)
114116
       if (.not. associated(tab)) cycle
115117
 
118
+      ! Create horizontal container for this tab (label + close button)
119
+      tab_container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2_c_int)
120
+
116121
       ! Format label as ".../basename"
117122
       label_text = ".../" // trim(tab%label)
118123
 
119
-      ! Create tab button
124
+      ! Create tab label button
120125
       tab_btn = gtk_button_new_with_label(trim(label_text)//c_null_char)
121
-      call gtk_widget_set_size_request(tab_btn, 120_c_int, 28_c_int)
126
+      call gtk_widget_set_size_request(tab_btn, 110_c_int, 28_c_int)
122127
 
123128
       ! Store button pointer so we can identify which tab was clicked
124129
       tab_buttons(i) = tab_btn
@@ -128,11 +133,27 @@ contains
128133
         call gtk_widget_add_css_class(tab_btn, "active-tab"//c_null_char)
129134
       end if
130135
 
131
-      ! Connect click handler
136
+      ! Connect click handler for tab selection
132137
       call g_signal_connect(tab_btn, "clicked"//c_null_char, &
133138
                             c_funloc(on_tab_clicked), c_null_ptr)
134139
 
135
-      call gtk_box_append(tab_bar_container, tab_btn)
140
+      call gtk_box_append(tab_container, tab_btn)
141
+
142
+      ! Create close button (small × button)
143
+      close_btn = gtk_button_new_with_label("×"//c_null_char)
144
+      call gtk_widget_set_size_request(close_btn, 24_c_int, 28_c_int)
145
+
146
+      ! Store close button pointer
147
+      close_buttons(i) = close_btn
148
+
149
+      ! Connect click handler for closing tab
150
+      call g_signal_connect(close_btn, "clicked"//c_null_char, &
151
+                            c_funloc(on_close_clicked), c_null_ptr)
152
+
153
+      call gtk_box_append(tab_container, close_btn)
154
+
155
+      ! Add the tab container to the tab bar
156
+      call gtk_box_append(tab_bar_container, tab_container)
136157
       print *, "Added tab button ", i, ": ", trim(label_text)
137158
     end do
138159
 
@@ -252,6 +273,50 @@ contains
252273
     print *, "Switched to tab ", clicked_tab_index
253274
   end subroutine on_tab_clicked
254275
 
276
+  ! Callback when a close button is clicked
277
+  subroutine on_close_clicked(button, user_data) bind(c)
278
+    type(c_ptr), value :: button, user_data
279
+    integer :: i, clicked_tab_index
280
+
281
+    ! Find which close button was clicked
282
+    clicked_tab_index = -1
283
+    do i = 1, num_tabs
284
+      if (c_associated(close_buttons(i), button)) then
285
+        clicked_tab_index = i
286
+        exit
287
+      end if
288
+    end do
289
+
290
+    if (clicked_tab_index == -1) then
291
+      print *, "WARNING: Could not determine which close button was clicked"
292
+      return
293
+    end if
294
+
295
+    print *, "Close button clicked for tab ", clicked_tab_index
296
+
297
+    ! Prevent closing last tab
298
+    if (num_tabs <= 1) then
299
+      print *, "ERROR: Cannot close last tab"
300
+      return
301
+    end if
302
+
303
+    ! Close the tab
304
+    call close_tab(clicked_tab_index)
305
+
306
+    ! Rebuild tab bar
307
+    call refresh_tab_bar()
308
+
309
+    ! Update visual states
310
+    call update_tab_visual_states()
311
+
312
+    ! Update UI for the new active tab
313
+    if (associated(tab_switch_cb)) then
314
+      call tab_switch_cb()
315
+    end if
316
+
317
+    print *, "Tab ", clicked_tab_index, " closed - now ", num_tabs, " tabs remaining"
318
+  end subroutine on_close_clicked
319
+
255320
   ! Register tab click callback
256321
   subroutine register_tab_click_callback(callback)
257322
     procedure(tab_click_callback) :: callback