@@ -6,6 +6,8 @@ use tracing::error;
66
77use crate :: distrobox:: { self , CreateArgName , CreateArgs , Error } ;
88use crate :: root_store:: RootStore ;
9+ use crate :: container:: Container ;
10+ use crate :: sidebar_row:: SidebarRow ;
911
1012use std:: path:: PathBuf ;
1113use std:: { cell:: RefCell , rc:: Rc } ;
@@ -42,6 +44,38 @@ mod imp {
4244 pub init_row : adw:: SwitchRow ,
4345 pub volume_rows : Rc < RefCell < Vec < adw:: EntryRow > > > ,
4446 pub scrolled_window : gtk:: ScrolledWindow ,
47+ #[ property( get, set=Self :: set_clone_src, nullable) ]
48+ pub clone_src : RefCell < Option < Container > > ,
49+ // transient widget used to show the source container info when cloning
50+ pub clone_sidebar : RefCell < Option < SidebarRow > > ,
51+ pub cloning_content : gtk:: Box ,
52+ pub view_switcher : adw:: InlineViewSwitcher ,
53+ }
54+
55+ impl CreateDistroboxDialog {
56+ fn set_clone_src ( & self , value : Option < Container > ) {
57+ // store the value
58+ self . clone_src . replace ( value. clone ( ) ) ;
59+
60+ if let Some ( sidebar_row) = self . clone_sidebar . borrow_mut ( ) . take ( ) {
61+ self . cloning_content . remove ( & sidebar_row) ;
62+ }
63+
64+ if let Some ( container) = value {
65+ self . image_row . set_visible ( false ) ;
66+ self . cloning_content . set_visible ( true ) ;
67+ self . view_switcher . set_visible ( false ) ;
68+ let sidebar_row = SidebarRow :: new ( & container) ;
69+ // insert at the top of the cloning_content box
70+ self . cloning_content . append ( & sidebar_row) ;
71+ self . clone_sidebar . replace ( Some ( sidebar_row) ) ;
72+ } else {
73+ // no clone source, ensure image row is visible
74+ self . image_row . set_visible ( true ) ;
75+ self . cloning_content . set_visible ( false ) ;
76+ self . view_switcher . set_visible ( true ) ;
77+ }
78+ }
4579 }
4680
4781 #[ derived_properties]
@@ -56,15 +90,35 @@ mod imp {
5690 // Create view switcher and stack
5791 let view_stack = adw:: ViewStack :: new ( ) ;
5892
59- // Create GUI creation page
60- let gui_page = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 12 ) ;
61- gui_page. set_margin_start ( 12 ) ;
62- gui_page. set_margin_end ( 12 ) ;
63- gui_page. set_margin_top ( 12 ) ;
64- gui_page. set_margin_bottom ( 12 ) ;
93+ self . content . set_margin_start ( 12 ) ;
94+ self . content . set_margin_end ( 12 ) ;
95+ self . content . set_margin_top ( 12 ) ;
96+ self . content . set_margin_bottom ( 12 ) ;
97+ self . content . set_spacing ( 12 ) ;
98+ self . content . set_orientation ( gtk:: Orientation :: Vertical ) ;
99+
100+
101+ // Create cloning_content box with header and sidebar
102+ self . cloning_content . set_orientation ( gtk:: Orientation :: Vertical ) ;
103+ self . cloning_content . set_spacing ( 12 ) ;
104+ self . cloning_content . set_visible ( false ) ;
105+
106+ // Create header box with "Cloning" label
107+ let cloning_header = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 12 ) ;
108+ cloning_header. set_homogeneous ( false ) ;
109+
110+ let cloning_label = gtk:: Label :: new ( Some ( "Cloning" ) ) ;
111+ cloning_label. set_halign ( gtk:: Align :: Start ) ;
112+ cloning_label. add_css_class ( "title-3" ) ;
113+
114+ cloning_header. set_hexpand ( true ) ;
115+ cloning_header. append ( & cloning_label) ;
116+
117+ self . cloning_content . append ( & cloning_header) ;
118+ self . content . append ( & self . cloning_content ) ;
119+
65120 let preferences_group = adw:: PreferencesGroup :: new ( ) ;
66121 preferences_group. set_title ( "Settings" ) ;
67-
68122 self . name_row . set_title ( "Name" ) ;
69123
70124 self . image_row
@@ -133,8 +187,8 @@ mod imp {
133187 preferences_group. add ( & self . init_row ) ;
134188
135189 let volumes_group = self . obj ( ) . build_volumes_group ( ) ;
136- gui_page . append ( & preferences_group) ;
137- gui_page . append ( & volumes_group) ;
190+ self . content . append ( & preferences_group) ;
191+ self . content . append ( & volumes_group) ;
138192
139193 let create_btn = gtk:: Button :: with_label ( "Create" ) ;
140194 create_btn. set_halign ( gtk:: Align :: Center ) ;
@@ -148,7 +202,14 @@ mod imp {
148202 let res = obj. extract_create_args( ) . await ;
149203 obj. update_errors( & res) ;
150204 if let Ok ( create_args) = res {
151- obj. root_store( ) . create_container( create_args) ;
205+ // If cloning from a source, delegate to clone_container, otherwise create normally
206+ if let Some ( src) = obj. clone_src( ) {
207+ obj. root_store( )
208+ . clone_container( & src. name( ) , create_args) ;
209+ } else {
210+ obj. root_store( ) . create_container( create_args) ;
211+ }
212+ obj. close( ) ;
152213 }
153214 } ) ;
154215 }
@@ -157,7 +218,7 @@ mod imp {
157218 create_btn. add_css_class ( "pill" ) ;
158219 create_btn. set_margin_top ( 12 ) ;
159220
160- gui_page . append ( & create_btn) ;
221+ self . content . append ( & create_btn) ;
161222
162223 // Create page for assemble from file
163224 let assemble_page = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 12 ) ;
@@ -261,22 +322,22 @@ mod imp {
261322 } ) ;
262323
263324 // Add pages to view stack
264- view_stack. add_titled ( & gui_page , Some ( "create" ) , "Guided" ) ;
325+ view_stack. add_titled ( & self . content , Some ( "create" ) , "Guided" ) ;
265326 view_stack. add_titled ( & assemble_page, Some ( "assemble-file" ) , "From File" ) ;
266327 view_stack. add_titled ( & url_page, Some ( "assemble-url" ) , "From URL" ) ;
267328
329+
268330 // Create a box to hold the view switcher and content
269331 let content_box = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 0 ) ;
270332
271333 // Add inline view switcher
272- let view_switcher = adw:: InlineViewSwitcher :: new ( ) ;
273- view_switcher. set_stack ( Some ( & view_stack) ) ;
274- view_switcher. set_margin_start ( 12 ) ;
275- view_switcher. set_margin_end ( 12 ) ;
276- view_switcher. set_margin_top ( 12 ) ;
277- view_switcher. set_margin_bottom ( 12 ) ;
278-
279- content_box. append ( & view_switcher) ;
334+ self . view_switcher . set_stack ( Some ( & view_stack) ) ;
335+ self . view_switcher . set_margin_start ( 12 ) ;
336+ self . view_switcher . set_margin_end ( 12 ) ;
337+ self . view_switcher . set_margin_top ( 12 ) ;
338+ self . view_switcher . set_margin_bottom ( 12 ) ;
339+
340+ content_box. append ( & self . view_switcher ) ;
280341 content_box. append ( & view_stack) ;
281342
282343 // Wrap content_box in a scrolled window
0 commit comments