Skip to content

Commit 877db0f

Browse files
committed
Make hdf5 a feature. Add popover menu to zoom to last button.
1 parent e1347fa commit 877db0f

File tree

5 files changed

+199
-46
lines changed

5 files changed

+199
-46
lines changed

lognplotgtk/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ version = "0.1.0"
55
authors = ["Windel Bouwman <windel@windel.nl>"]
66
edition = "2018"
77

8+
[features]
9+
default = ["hdf5"]
10+
11+
# Build without hdf5 using: cargo build --no-default-features
12+
813
[dependencies]
914
clap = "2.33.0"
1015
cairo-rs = "0.8"
@@ -14,7 +19,7 @@ gio = "0.8"
1419
gtk = "0.8"
1520
gdk = "0.12"
1621
gdk-pixbuf = "0.8"
17-
hdf5 = "0.6"
22+
hdf5 = { version = "0.6", optional = true }
1823
lognplot = { path = "../lognplot", features=["cairo", "server"] }
1924
log = "0.4.8"
2025
ndarray = "0.13"

lognplotgtk/src/gui.glade

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<!-- Generated with glade 3.22.2 -->
2+
<!-- Generated with glade 3.36.0 -->
33
<interface>
44
<requires lib="gtk+" version="3.20"/>
55
<object class="GtkDialog">
66
<property name="can_focus">False</property>
77
<property name="type_hint">dialog</property>
8-
<child type="titlebar">
9-
<placeholder/>
10-
</child>
118
<child internal-child="vbox">
129
<object class="GtkBox">
1310
<property name="can_focus">False</property>
@@ -35,6 +32,9 @@
3532
</child>
3633
</object>
3734
</child>
35+
<child type="titlebar">
36+
<placeholder/>
37+
</child>
3838
</object>
3939
<object class="GtkAboutDialog" id="about_dialog">
4040
<property name="can_focus">False</property>
@@ -46,9 +46,6 @@
4646
<property name="authors">Windel Bouwman</property>
4747
<property name="logo_icon_name"/>
4848
<property name="license_type">gpl-3-0</property>
49-
<child type="titlebar">
50-
<placeholder/>
51-
</child>
5249
<child internal-child="vbox">
5350
<object class="GtkBox">
5451
<property name="can_focus">False</property>
@@ -70,6 +67,9 @@
7067
</child>
7168
</object>
7269
</child>
70+
<child type="titlebar">
71+
<placeholder/>
72+
</child>
7373
</object>
7474
<object class="GtkMenu" id="my_menu1">
7575
<property name="visible">True</property>
@@ -142,7 +142,115 @@
142142
<object class="GtkPopover" id="popover1">
143143
<property name="can_focus">False</property>
144144
<child>
145-
<placeholder/>
145+
<object class="GtkBox">
146+
<property name="visible">True</property>
147+
<property name="can_focus">False</property>
148+
<property name="orientation">vertical</property>
149+
<child>
150+
<object class="GtkButton" id="bt_last_year">
151+
<property name="label" translatable="yes">Last year</property>
152+
<property name="visible">True</property>
153+
<property name="can_focus">True</property>
154+
<property name="receives_default">True</property>
155+
</object>
156+
<packing>
157+
<property name="expand">False</property>
158+
<property name="fill">True</property>
159+
<property name="position">0</property>
160+
</packing>
161+
</child>
162+
<child>
163+
<object class="GtkButton" id="bt_last_day">
164+
<property name="label" translatable="yes">Last day</property>
165+
<property name="visible">True</property>
166+
<property name="can_focus">True</property>
167+
<property name="receives_default">True</property>
168+
</object>
169+
<packing>
170+
<property name="expand">False</property>
171+
<property name="fill">True</property>
172+
<property name="position">1</property>
173+
</packing>
174+
</child>
175+
<child>
176+
<object class="GtkButton" id="bt_last_hour">
177+
<property name="label" translatable="yes">Last hour</property>
178+
<property name="visible">True</property>
179+
<property name="can_focus">True</property>
180+
<property name="receives_default">True</property>
181+
</object>
182+
<packing>
183+
<property name="expand">False</property>
184+
<property name="fill">True</property>
185+
<property name="position">2</property>
186+
</packing>
187+
</child>
188+
<child>
189+
<object class="GtkButton" id="bt_last_10_minutes">
190+
<property name="label" translatable="yes">Last 10 minutes</property>
191+
<property name="visible">True</property>
192+
<property name="can_focus">True</property>
193+
<property name="receives_default">True</property>
194+
</object>
195+
<packing>
196+
<property name="expand">False</property>
197+
<property name="fill">True</property>
198+
<property name="position">3</property>
199+
</packing>
200+
</child>
201+
<child>
202+
<object class="GtkButton" id="bt_last_minute">
203+
<property name="label" translatable="yes">Last minute</property>
204+
<property name="visible">True</property>
205+
<property name="can_focus">True</property>
206+
<property name="receives_default">True</property>
207+
</object>
208+
<packing>
209+
<property name="expand">False</property>
210+
<property name="fill">True</property>
211+
<property name="position">4</property>
212+
</packing>
213+
</child>
214+
<child>
215+
<object class="GtkButton" id="bt_last_30_seconds">
216+
<property name="label" translatable="yes">Last 30 seconds</property>
217+
<property name="visible">True</property>
218+
<property name="can_focus">True</property>
219+
<property name="receives_default">True</property>
220+
</object>
221+
<packing>
222+
<property name="expand">False</property>
223+
<property name="fill">True</property>
224+
<property name="position">5</property>
225+
</packing>
226+
</child>
227+
<child>
228+
<object class="GtkButton" id="bt_last_10_seconds">
229+
<property name="label" translatable="yes">Last 10 seconds</property>
230+
<property name="visible">True</property>
231+
<property name="can_focus">True</property>
232+
<property name="receives_default">True</property>
233+
</object>
234+
<packing>
235+
<property name="expand">False</property>
236+
<property name="fill">True</property>
237+
<property name="position">6</property>
238+
</packing>
239+
</child>
240+
<child>
241+
<object class="GtkButton" id="bt_last_second">
242+
<property name="label" translatable="yes">Last second</property>
243+
<property name="visible">True</property>
244+
<property name="can_focus">True</property>
245+
<property name="receives_default">True</property>
246+
</object>
247+
<packing>
248+
<property name="expand">False</property>
249+
<property name="fill">True</property>
250+
<property name="position">7</property>
251+
</packing>
252+
</child>
253+
</object>
146254
</child>
147255
</object>
148256
<object class="GtkTreeStore" id="signal_hierarchy">
@@ -154,9 +262,6 @@
154262
<object class="GtkWindow" id="top_unit">
155263
<property name="can_focus">False</property>
156264
<property name="title" translatable="yes">Lognplot GTK GUI</property>
157-
<child type="titlebar">
158-
<placeholder/>
159-
</child>
160265
<child>
161266
<object class="GtkBox">
162267
<property name="visible">True</property>
@@ -346,10 +451,10 @@
346451
</packing>
347452
</child>
348453
<child>
349-
<object class="GtkMenuToolButton" id="tb_zoom_to">
454+
<object class="GtkToolButton" id="tb_zoom_to">
350455
<property name="visible">True</property>
351456
<property name="can_focus">False</property>
352-
<property name="label" translatable="yes">Zoom to last...</property>
457+
<property name="label" translatable="yes">Follow last...</property>
353458
<property name="use_underline">True</property>
354459
</object>
355460
<packing>
@@ -569,5 +674,8 @@
569674
</child>
570675
</object>
571676
</child>
677+
<child type="titlebar">
678+
<placeholder/>
679+
</child>
572680
</object>
573681
</interface>

lognplotgtk/src/main.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ extern crate glib;
66

77
mod chart_widget;
88
mod error_dialog;
9+
10+
#[cfg(feature = "hdf5")]
911
mod io;
12+
1013
mod mainwindow;
1114
mod mime_types;
1215
mod resources;
@@ -21,6 +24,19 @@ use std::sync::Arc;
2124

2225
pub use state::{GuiState, GuiStateHandle};
2326

27+
#[cfg(not(features = "hdf5"))]
28+
mod io {
29+
use super::GuiStateHandle;
30+
31+
pub fn save_data_as_hdf5(top_level: &gtk::Window, app_state: &GuiStateHandle) {
32+
unimplemented!();
33+
}
34+
35+
pub fn load_data_from_hdf5(top_level: &gtk::Window, app_state: &GuiStateHandle) {
36+
unimplemented!();
37+
}
38+
}
39+
2440
/// Create database, start server, and open a GUI.
2541
fn main() {
2642
let matches = clap::App::new("lognplot GTK gui")

lognplotgtk/src/mainwindow.rs

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,25 @@ fn setup_menus(builder: &gtk::Builder, app_state: GuiStateHandle) {
203203

204204
let top_level: gtk::Window = builder.get_object("top_unit").unwrap();
205205
let menu_open: gtk::MenuItem = builder.get_object("menu_open").unwrap();
206-
menu_open.connect_activate(clone!(@strong app_state => move |_| {
207-
load_data_from_hdf5(&top_level, &app_state);
208-
}));
206+
if cfg!(feature = "hdf5") {
207+
menu_open.set_sensitive(true);
208+
menu_open.connect_activate(clone!(@strong app_state => move |_| {
209+
load_data_from_hdf5(&top_level, &app_state);
210+
}));
211+
} else {
212+
menu_open.set_sensitive(false);
213+
}
209214

210215
let top_level: gtk::Window = builder.get_object("top_unit").unwrap();
211216
let menu_save: gtk::MenuItem = builder.get_object("menu_save").unwrap();
212-
menu_save.connect_activate(clone!(@strong app_state => move |_| {
213-
save_data_as_hdf5(&top_level, &app_state);
214-
}));
217+
if cfg!(feature = "hdf5") {
218+
menu_save.set_sensitive(true);
219+
menu_save.connect_activate(clone!(@strong app_state => move |_| {
220+
save_data_as_hdf5(&top_level, &app_state);
221+
}));
222+
} else {
223+
menu_save.set_sensitive(false);
224+
}
215225

216226
let top_level: gtk::Window = builder.get_object("top_unit").unwrap();
217227
let menu_save_session: gtk::MenuItem = builder.get_object("menu_save_session").unwrap();
@@ -251,32 +261,7 @@ fn setup_toolbar_buttons(builder: &gtk::Builder, app_state: GuiStateHandle) {
251261
}));
252262
}
253263

254-
// Zoom to button:
255-
{
256-
let tb_zoom_to: gtk::MenuToolButton = builder.get_object("tb_zoom_to").unwrap();
257-
let menu2: gtk::Menu = builder.get_object("my_menu1").unwrap();
258-
tb_zoom_to.set_menu(&menu2);
259-
260-
let menu_ids = vec![
261-
("menu_last_year", 365.0 * 24.0 * 60.0 * 60.0),
262-
("menu_last_day", 24.0 * 60.0 * 60.0),
263-
("menu_last_hour", 60.0 * 60.0),
264-
("menu_last_10_minutes", 10.0 * 60.0),
265-
("menu_last_minute", 60.0),
266-
("menu_last_30_seconds", 30.0),
267-
("menu_last_10_seconds", 10.0),
268-
("menu_last_second", 1.0),
269-
];
270-
for (menu_id, tail_duration) in menu_ids {
271-
let menu_item: gtk::MenuItem = builder.get_object(menu_id).unwrap();
272-
menu_item.connect_activate(clone!(@strong app_state => move |_tb| {
273-
info!("Zoom to last {} seconds", tail_duration);
274-
app_state
275-
.borrow_mut()
276-
.enable_tailing(tail_duration);
277-
}));
278-
}
279-
}
264+
setup_zoom_to_options(builder, app_state.clone());
280265

281266
{
282267
let tb_link_x_axis: gtk::ToggleToolButton = builder.get_object("tb_link_x_axis").unwrap();
@@ -286,6 +271,38 @@ fn setup_toolbar_buttons(builder: &gtk::Builder, app_state: GuiStateHandle) {
286271
}
287272
}
288273

274+
/// Setup zoom-to button and popover menu
275+
fn setup_zoom_to_options(builder: &gtk::Builder, app_state: GuiStateHandle) {
276+
let tb_zoom_to: gtk::ToolButton = builder.get_object("tb_zoom_to").unwrap();
277+
let pop_over: gtk::Popover = builder.get_object("popover1").unwrap();
278+
pop_over.set_relative_to(Some(&tb_zoom_to));
279+
280+
tb_zoom_to.connect_clicked(clone!(@strong pop_over => move |_tb| {
281+
pop_over.show_all();
282+
}));
283+
284+
let menu_ids = vec![
285+
("bt_last_year", 365.0 * 24.0 * 60.0 * 60.0),
286+
("bt_last_day", 24.0 * 60.0 * 60.0),
287+
("bt_last_hour", 60.0 * 60.0),
288+
("bt_last_10_minutes", 10.0 * 60.0),
289+
("bt_last_minute", 60.0),
290+
("bt_last_30_seconds", 30.0),
291+
("bt_last_10_seconds", 10.0),
292+
("bt_last_second", 1.0),
293+
];
294+
for (menu_id, tail_duration) in menu_ids {
295+
let duration_button: gtk::Button = builder.get_object(menu_id).unwrap();
296+
duration_button.connect_clicked(clone!(@strong app_state, @strong pop_over => move |_tb| {
297+
pop_over.hide();
298+
info!("Zoom to last {} seconds", tail_duration);
299+
app_state
300+
.borrow_mut()
301+
.enable_tailing(tail_duration);
302+
}));
303+
}
304+
}
305+
289306
/// Subscribe to database changes and redraw correct things.
290307
fn setup_notify_change(app_state: GuiStateHandle) {
291308
let mut receiver = app_state.borrow().db.new_notify_queue();

lognplotgtk/src/state.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,22 @@ impl GuiState {
3939
self.db.delete_all();
4040
}
4141

42+
#[cfg(features = "hdf5")]
4243
pub fn save(&self, filename: &Path) -> Result<(), String> {
4344
info!("Save data to {:?}", filename);
4445
super::io::export_data(self.db.clone(), filename).map_err(|e| e.to_string())
4546
}
4647

48+
#[cfg(features = "hdf5")]
4749
pub fn load(&self, filename: &Path) -> Result<(), String> {
4850
super::io::import_data(self.db.clone(), filename).map_err(|e| e.to_string())
4951
}
5052

53+
#[cfg(not(features = "hdf5"))]
54+
pub fn load(&self, filename: &Path) -> Result<(), String> {
55+
Err("No hdf5 support!".to_owned())
56+
}
57+
5158
pub fn save_session(&self, filename: &Path) -> std::io::Result<()> {
5259
let mut s = session::Session::new();
5360
for chart in &self.charts {

0 commit comments

Comments
 (0)