Implement #52
This commit is contained in:
parent
a6e16d1cbd
commit
8a025c3a7c
192
src/ui.rs
192
src/ui.rs
@ -1,16 +1,18 @@
|
|||||||
use std::cell::{RefCell, Ref, RefMut};
|
use std::cell::{Ref, RefCell, RefMut};
|
||||||
use std::{env, thread};
|
use std::{env, thread};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use gdk;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk_sys;
|
use gtk_sys;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image, AboutDialog, SettingsExt};
|
use gtk::{AboutDialog, ApplicationWindow, HeaderBar, Image, SettingsExt, ToolButton};
|
||||||
use gio::prelude::*;
|
use gio::prelude::*;
|
||||||
use gio::{Menu, MenuExt, MenuItem, SimpleAction};
|
use gio::{Menu, MenuExt, MenuItem, SimpleAction};
|
||||||
|
use toml;
|
||||||
|
|
||||||
use settings::Settings;
|
use settings::{Settings, SettingsLoader};
|
||||||
use shell::{self, Shell, ShellOptions};
|
use shell::{self, Shell, ShellOptions};
|
||||||
use shell_dlg;
|
use shell_dlg;
|
||||||
use project::Projects;
|
use project::Projects;
|
||||||
@ -44,6 +46,7 @@ pub struct Ui {
|
|||||||
|
|
||||||
pub struct Components {
|
pub struct Components {
|
||||||
window: Option<ApplicationWindow>,
|
window: Option<ApplicationWindow>,
|
||||||
|
window_state: WindowState,
|
||||||
open_btn: ToolButton,
|
open_btn: ToolButton,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +58,7 @@ impl Components {
|
|||||||
Components {
|
Components {
|
||||||
open_btn: ToolButton::new(Some(&save_image), "Open"),
|
open_btn: ToolButton::new(Some(&save_image), "Open"),
|
||||||
window: None,
|
window: None,
|
||||||
|
window_state: WindowState::load(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,65 +102,93 @@ impl Ui {
|
|||||||
let mut settings = self.settings.borrow_mut();
|
let mut settings = self.settings.borrow_mut();
|
||||||
settings.init();
|
settings.init();
|
||||||
|
|
||||||
let mut comps = self.comps.borrow_mut();
|
let window = ApplicationWindow::new(app);
|
||||||
|
|
||||||
self.shell.borrow_mut().init();
|
{
|
||||||
|
// initialize window from comps
|
||||||
|
// borrowing of comps must be leaved
|
||||||
|
// for event processing
|
||||||
|
let mut comps = self.comps.borrow_mut();
|
||||||
|
|
||||||
comps.window = Some(ApplicationWindow::new(app));
|
self.shell.borrow_mut().init();
|
||||||
let window = comps.window.as_ref().unwrap();
|
|
||||||
|
|
||||||
let prefer_dark_theme = env::var("NVIM_GTK_PREFER_DARK_THEME")
|
comps.window = Some(window.clone());
|
||||||
.map(|opt| opt.trim() == "1")
|
|
||||||
.unwrap_or(false);
|
let prefer_dark_theme = env::var("NVIM_GTK_PREFER_DARK_THEME")
|
||||||
if prefer_dark_theme {
|
.map(|opt| opt.trim() == "1")
|
||||||
if let Some(settings) = window.get_settings() {
|
.unwrap_or(false);
|
||||||
settings.set_property_gtk_application_prefer_dark_theme(true);
|
if prefer_dark_theme {
|
||||||
|
if let Some(settings) = window.get_settings() {
|
||||||
|
settings.set_property_gtk_application_prefer_dark_theme(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client side decorations including the toolbar are disabled via NVIM_GTK_NO_HEADERBAR=1
|
||||||
|
let use_header_bar = env::var("NVIM_GTK_NO_HEADERBAR")
|
||||||
|
.map(|opt| opt.trim() != "1")
|
||||||
|
.unwrap_or(true);
|
||||||
|
|
||||||
|
if app.prefers_app_menu() || use_header_bar {
|
||||||
|
self.create_main_menu(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
if use_header_bar {
|
||||||
|
let header_bar = HeaderBar::new();
|
||||||
|
|
||||||
|
let projects = self.projects.clone();
|
||||||
|
header_bar.pack_start(&comps.open_btn);
|
||||||
|
comps
|
||||||
|
.open_btn
|
||||||
|
.connect_clicked(move |_| projects.borrow_mut().show());
|
||||||
|
|
||||||
|
let save_image = Image::new_from_icon_name(
|
||||||
|
"document-save",
|
||||||
|
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32,
|
||||||
|
);
|
||||||
|
let save_btn = ToolButton::new(Some(&save_image), "Save");
|
||||||
|
|
||||||
|
let shell = self.shell.clone();
|
||||||
|
save_btn.connect_clicked(move |_| shell.borrow_mut().edit_save_all());
|
||||||
|
header_bar.pack_start(&save_btn);
|
||||||
|
|
||||||
|
let paste_image = Image::new_from_icon_name(
|
||||||
|
"edit-paste",
|
||||||
|
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32,
|
||||||
|
);
|
||||||
|
let paste_btn = ToolButton::new(Some(&paste_image), "Paste");
|
||||||
|
let shell = self.shell.clone();
|
||||||
|
paste_btn.connect_clicked(move |_| shell.borrow_mut().edit_paste());
|
||||||
|
header_bar.pack_start(&paste_btn);
|
||||||
|
|
||||||
|
header_bar.set_show_close_button(true);
|
||||||
|
|
||||||
|
window.set_titlebar(Some(&header_bar));
|
||||||
|
}
|
||||||
|
|
||||||
|
window.set_default_size(
|
||||||
|
comps.window_state.current_width,
|
||||||
|
comps.window_state.current_height,
|
||||||
|
);
|
||||||
|
if comps.window_state.is_maximized {
|
||||||
|
window.maximize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client side decorations including the toolbar are disabled via NVIM_GTK_NO_HEADERBAR=1
|
let comps_ref = self.comps.clone();
|
||||||
let use_header_bar = env::var("NVIM_GTK_NO_HEADERBAR")
|
window.connect_size_allocate(move |window, _| {
|
||||||
.map(|opt| opt.trim() != "1")
|
gtk_window_size_allocate(window, &mut *comps_ref.borrow_mut())
|
||||||
.unwrap_or(true);
|
});
|
||||||
|
|
||||||
if app.prefers_app_menu() || use_header_bar {
|
let comps_ref = self.comps.clone();
|
||||||
self.create_main_menu(app);
|
window.connect_window_state_event(move |_, event| {
|
||||||
}
|
gtk_window_state_event(event, &mut *comps_ref.borrow_mut());
|
||||||
|
Inhibit(false)
|
||||||
|
});
|
||||||
|
|
||||||
if use_header_bar {
|
let comps_ref = self.comps.clone();
|
||||||
let header_bar = HeaderBar::new();
|
window.connect_destroy(move |_| {
|
||||||
|
comps_ref.borrow().window_state.save();
|
||||||
let projects = self.projects.clone();
|
});
|
||||||
header_bar.pack_start(&comps.open_btn);
|
|
||||||
comps.open_btn.connect_clicked(
|
|
||||||
move |_| projects.borrow_mut().show(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let save_image = Image::new_from_icon_name(
|
|
||||||
"document-save",
|
|
||||||
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32,
|
|
||||||
);
|
|
||||||
let save_btn = ToolButton::new(Some(&save_image), "Save");
|
|
||||||
|
|
||||||
let shell = self.shell.clone();
|
|
||||||
save_btn.connect_clicked(move |_| shell.borrow_mut().edit_save_all());
|
|
||||||
header_bar.pack_start(&save_btn);
|
|
||||||
|
|
||||||
let paste_image = Image::new_from_icon_name(
|
|
||||||
"edit-paste",
|
|
||||||
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32,
|
|
||||||
);
|
|
||||||
let paste_btn = ToolButton::new(Some(&paste_image), "Paste");
|
|
||||||
let shell = self.shell.clone();
|
|
||||||
paste_btn.connect_clicked(move |_| shell.borrow_mut().edit_paste());
|
|
||||||
header_bar.pack_start(&paste_btn);
|
|
||||||
|
|
||||||
header_bar.set_show_close_button(true);
|
|
||||||
|
|
||||||
window.set_titlebar(Some(&header_bar));
|
|
||||||
}
|
|
||||||
|
|
||||||
window.set_default_size(800, 600);
|
|
||||||
|
|
||||||
let shell = self.shell.borrow();
|
let shell = self.shell.borrow();
|
||||||
window.add(&**shell);
|
window.add(&**shell);
|
||||||
@ -182,9 +214,9 @@ impl Ui {
|
|||||||
let state_ref = self.shell.borrow().state.clone();
|
let state_ref = self.shell.borrow().state.clone();
|
||||||
let plug_manager_ref = self.plug_manager.clone();
|
let plug_manager_ref = self.plug_manager.clone();
|
||||||
shell.set_nvim_started_cb(Some(move || {
|
shell.set_nvim_started_cb(Some(move || {
|
||||||
plug_manager_ref.borrow_mut().init_nvim_client(
|
plug_manager_ref
|
||||||
state_ref.borrow().nvim_clone(),
|
.borrow_mut()
|
||||||
);
|
.init_nvim_client(state_ref.borrow().nvim_clone());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +268,7 @@ fn on_help_about(comps: &Components) {
|
|||||||
about.set_comments(
|
about.set_comments(
|
||||||
format!(
|
format!(
|
||||||
"Build on top of neovim\n\
|
"Build on top of neovim\n\
|
||||||
Minimum supported neovim version: {}",
|
Minimum supported neovim version: {}",
|
||||||
shell::MINIMUM_SUPPORTED_NVIM_VERSION
|
shell::MINIMUM_SUPPORTED_NVIM_VERSION
|
||||||
).as_str(),
|
).as_str(),
|
||||||
);
|
);
|
||||||
@ -260,6 +292,50 @@ fn gtk_delete(comps: &UiMutex<Components>, shell: &RefCell<Shell>) -> Inhibit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gtk_window_size_allocate(app_window: >k::ApplicationWindow, comps: &mut Components) {
|
||||||
|
if !app_window.is_maximized() {
|
||||||
|
let (current_width, current_height) = app_window.get_size();
|
||||||
|
comps.window_state.current_width = current_width;
|
||||||
|
comps.window_state.current_height = current_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gtk_window_state_event(event: &gdk::EventWindowState, comps: &mut Components) {
|
||||||
|
comps.window_state.is_maximized = event
|
||||||
|
.get_new_window_state()
|
||||||
|
.contains(gdk::WindowState::MAXIMIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WindowState {
|
||||||
|
current_width: i32,
|
||||||
|
current_height: i32,
|
||||||
|
is_maximized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
WindowState {
|
||||||
|
current_width: 800,
|
||||||
|
current_height: 600,
|
||||||
|
is_maximized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SettingsLoader for WindowState {
|
||||||
|
const SETTINGS_FILE: &'static str = "window.toml";
|
||||||
|
|
||||||
|
fn empty() -> WindowState {
|
||||||
|
WindowState::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, String> {
|
||||||
|
toml::from_str(&s).map_err(|e| format!("{}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct UiMutex<T: ?Sized> {
|
pub struct UiMutex<T: ?Sized> {
|
||||||
thread: thread::ThreadId,
|
thread: thread::ThreadId,
|
||||||
data: RefCell<T>,
|
data: RefCell<T>,
|
||||||
|
Loading…
Reference in New Issue
Block a user