@@ -49,30 +49,95 @@ fn build_ui(app: >k::Application, app_state: GuiStateHandle) {
4949 window. show_all ( ) ;
5050}
5151
52- fn setup_chart_area ( builder : & gtk:: Builder , app_state : GuiStateHandle ) {
53- // First chart:
54- let draw_area: gtk:: DrawingArea = builder. get_object ( "chart_control" ) . unwrap ( ) ;
55- let chart_state1 = setup_drawing_area ( draw_area, app_state. clone ( ) , "chart1" ) ;
52+ /// Create new chart area with extra buttons around it
53+ /// to enable splitting in vertical and horizontal direction
54+ fn create_new_chart_area ( app_state : & GuiStateHandle , parent_box : gtk:: Box ) {
55+ let box1 = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 0 ) ;
56+ let draw_area: gtk:: DrawingArea = gtk:: DrawingArea :: new ( ) ;
57+ massage_drawing_area ( & draw_area) ;
58+ box1. pack_start ( & draw_area, true , true , 0 ) ;
59+
60+ // generate new unique chart id based on amount of charts so far:
61+ let chart_id = format ! ( "chart{}" , app_state. borrow( ) . num_charts( ) + 1 ) ;
62+
63+ let chart_state1 = setup_drawing_area ( draw_area, app_state. clone ( ) , & chart_id) ;
5664 app_state. borrow_mut ( ) . add_chart ( chart_state1) ;
5765
58- // Second chart:
59- let draw_area2: gtk:: DrawingArea = builder. get_object ( "chart_control2" ) . unwrap ( ) ;
60- let chart_state2 = setup_drawing_area ( draw_area2, app_state. clone ( ) , "chart2" ) ;
61- app_state. borrow_mut ( ) . add_chart ( chart_state2) ;
62-
63- // Split handler:
64- // TODO:
65- // let hbx: gtk::Box = builder.get_object("root_splittor_box").unwrap();
66- // let split_button: gtk::Button = builder.get_object("button_split_vertical").unwrap();
67- // split_button.connect_clicked(move |_| {
68- // println!("Split!");
69- // hbx.remove(&draw_area2);
70- // let paned = gtk::Paned::new(gtk::Orientation::Vertical);
71- // hbx.add(&paned);
72- // paned.add(&draw_area2);
73-
74- // // hbx.add_widget(draw_area2);
75- // });
66+ // Create split buttons:
67+ let box2 = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 0 ) ;
68+ let button1 = gtk:: Button :: new ( ) ;
69+ button1. set_label ( "Split vertical" ) ;
70+ box2. pack_start ( & button1, false , false , 0 ) ;
71+
72+ let button2 = gtk:: Button :: new ( ) ;
73+ button2. set_label ( "Split horizontal" ) ;
74+ box2. pack_start ( & button2, false , false , 0 ) ;
75+
76+ box1. pack_start ( & box2, false , false , 0 ) ;
77+ box1. show_all ( ) ;
78+
79+ button1. connect_clicked (
80+ clone ! ( @strong app_state, @strong box1, @strong parent_box => move |_| {
81+ info!( "Split vertically" ) ;
82+ split_chart( & app_state, & box1, gtk:: Orientation :: Vertical ) ;
83+ } ) ,
84+ ) ;
85+
86+ button2. connect_clicked (
87+ clone ! ( @strong app_state, @strong box1, @strong parent_box => move |_| {
88+ info!( "Split horizontally" ) ;
89+ split_chart( & app_state, & box1, gtk:: Orientation :: Horizontal ) ;
90+ } ) ,
91+ ) ;
92+
93+ parent_box. pack_start ( & box1, true , true , 0 ) ;
94+ }
95+
96+ /// Complex way of finding position of box in parent box:
97+ fn find_index ( box1 : gtk:: Box , parent : & gtk:: Box ) -> i32 {
98+ for ( index, child) in parent. get_children ( ) . iter ( ) . enumerate ( ) {
99+ let child_box: gtk:: Box = child. clone ( ) . downcast :: < gtk:: Box > ( ) . unwrap ( ) ;
100+ if child_box == box1 {
101+ return index as i32 ;
102+ }
103+ }
104+
105+ 0
106+ }
107+
108+ /// Takes care of splitting the chart into two areas
109+ /// This is done by determining the containing box parent,
110+ /// and removing this box from the parent, placing a new
111+ /// box in between in the box hierarchy..
112+ fn split_chart ( app_state : & GuiStateHandle , box1 : & gtk:: Box , orientation : gtk:: Orientation ) {
113+ // Create new split pane:
114+ let new_box = gtk:: Box :: new ( orientation, 0 ) ;
115+
116+ // Determine parent box (either vertical or horizontal)
117+ let parent_box: gtk:: Box = box1. get_parent ( ) . unwrap ( ) . downcast :: < gtk:: Box > ( ) . unwrap ( ) ;
118+
119+ // find position in parent:
120+ let index = find_index ( box1. clone ( ) , & parent_box) ;
121+ info ! ( "Old position: {:?}" , index) ;
122+
123+ // Remove original container and add new box:
124+ parent_box. remove ( box1) ;
125+ parent_box. pack_start ( & new_box, true , true , 0 ) ;
126+ parent_box. reorder_child ( & new_box, index) ; // move to first position again!
127+
128+ new_box. pack_start ( box1, true , true , 0 ) ;
129+
130+ // create new chart area:
131+ create_new_chart_area ( & app_state, new_box. clone ( ) ) ;
132+
133+ new_box. show_all ( ) ;
134+ }
135+
136+ fn setup_chart_area ( builder : & gtk:: Builder , app_state : GuiStateHandle ) {
137+ let root_splittor: gtk:: Box = builder. get_object ( "root_splittor" ) . unwrap ( ) ;
138+
139+ // Initial chart:
140+ create_new_chart_area ( & app_state, root_splittor) ;
76141}
77142
78143fn setup_about_dialog ( about_dialog : & gtk:: AboutDialog ) {
@@ -87,8 +152,8 @@ fn setup_about_dialog(about_dialog: >k::AboutDialog) {
87152 about_dialog. connect_response ( |p, _| p. hide ( ) ) ;
88153}
89154
90- /// Construct new plot window with the given number of plots .
91- fn new_plot_window ( app_state : GuiStateHandle , amount : usize ) {
155+ /// Construct new plot window.
156+ fn new_plot_window ( app_state : GuiStateHandle ) {
92157 info ! ( "New window!" ) ;
93158 let chart_id = format ! ( "chart{}" , app_state. borrow( ) . num_charts( ) + 1 ) ;
94159 let new_window = gtk:: WindowBuilder :: new ( )
@@ -99,47 +164,15 @@ fn new_plot_window(app_state: GuiStateHandle, amount: usize) {
99164 new_window. set_icon ( Some ( & icon) ) ;
100165 }
101166
102- let mut charts = vec ! [ ] ;
103- if amount > 1 {
104- let grid = gtk:: Grid :: new ( ) ;
105- new_window. add ( & grid) ;
106-
107- // Create grid of plots:
108- for row in 0_i32 ..amount as i32 {
109- for column in 0_i32 ..amount as i32 {
110- let chart_id = format ! (
111- "chart{}" ,
112- app_state. borrow( ) . num_charts( ) + 1 + charts. len( )
113- ) ;
114- // println!("Row: {}", row);
115- let new_chart_area = gtk:: DrawingArea :: new ( ) ;
116- grid. attach ( & new_chart_area, column, row, 1 , 1 ) ;
117- massage_drawing_area ( & new_chart_area) ;
118-
119- let chart_n = setup_drawing_area ( new_chart_area, app_state. clone ( ) , & chart_id) ;
120- charts. push ( chart_n) ;
121- }
122- }
123-
124- grid. show ( ) ;
125- } else {
126- let new_chart_area = gtk:: DrawingArea :: new ( ) ;
127- new_window. add ( & new_chart_area) ;
128- massage_drawing_area ( & new_chart_area) ;
129-
130- let chart_n = setup_drawing_area ( new_chart_area, app_state. clone ( ) , & chart_id) ;
131- charts. push ( chart_n) ;
132- }
167+ let root_box = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 0 ) ;
168+ new_window. add ( & root_box) ;
133169
134- for chart_n in & charts {
135- app_state. borrow_mut ( ) . add_chart ( chart_n. clone ( ) ) ;
136- }
170+ create_new_chart_area ( & app_state, root_box) ;
137171
138172 new_window. connect_delete_event ( clone ! ( @strong app_state => move |_, _| {
139173 // Remove all chart structs from the app state:
140- for chart_n in & charts {
141- app_state. borrow_mut( ) . delete_chart( & chart_n) ;
142- }
174+ // TODO: remove charts of this window!
175+ // TODO: by not doing this, we suffer from some memory leakage?
143176 Inhibit ( false )
144177 } ) ) ;
145178 new_window. show_all ( ) ;
@@ -150,6 +183,7 @@ fn massage_drawing_area(new_chart_area: >k::DrawingArea) {
150183 new_chart_area. show ( ) ;
151184 new_chart_area. set_hexpand ( true ) ;
152185 new_chart_area. set_vexpand ( true ) ;
186+ new_chart_area. set_size_request ( 200 , 200 ) ;
153187
154188 new_chart_area. set_can_focus ( true ) ;
155189 new_chart_area. set_can_default ( true ) ;
@@ -181,13 +215,7 @@ fn setup_menus(builder: >k::Builder, app_state: GuiStateHandle) {
181215
182216 let menu_new_plot_window: gtk:: MenuItem = builder. get_object ( "menu_new_plot_window" ) . unwrap ( ) ;
183217 menu_new_plot_window. connect_activate ( clone ! ( @strong app_state => move |_| {
184- new_plot_window( app_state. clone( ) , 1 ) ;
185- } ) ) ;
186-
187- let menu_new_grid_plot_window: gtk:: MenuItem =
188- builder. get_object ( "menu_new_grid_plot_window" ) . unwrap ( ) ;
189- menu_new_grid_plot_window. connect_activate ( clone ! ( @strong app_state => move |_| {
190- new_plot_window( app_state. clone( ) , 2 ) ;
218+ new_plot_window( app_state. clone( ) ) ;
191219 } ) ) ;
192220
193221 let top_level: gtk:: Window = builder. get_object ( "top_unit" ) . unwrap ( ) ;
0 commit comments