Refactoring, ext_cmdline window

This commit is contained in:
daa 2017-11-18 15:56:37 +03:00
parent 56bc8f32de
commit 932b7d98b4
7 changed files with 98 additions and 108 deletions

23
src/cmd_line.rs Normal file
View File

@ -0,0 +1,23 @@
use gtk;
use gtk::prelude::*;
pub struct CmdLine {
dlg: gtk::Dialog,
}
impl CmdLine {
pub fn new() -> Self {
let dlg = gtk::Dialog::new();
dlg.set_modal(true);
dlg.set_destroy_with_parent(true);
CmdLine {
dlg,
}
}
pub fn show<W: gtk::IsA<gtk::Window>>(&self, parent: &W) {
self.dlg.set_transient_for(parent);
self.dlg.show();
}
}

View File

@ -43,6 +43,7 @@ mod shell;
mod input; mod input;
mod settings; mod settings;
mod cursor; mod cursor;
mod cmd_line;
mod shell_dlg; mod shell_dlg;
mod popup_menu; mod popup_menu;
mod project; mod project;

View File

@ -1,30 +0,0 @@
use ui_model;
pub struct CmdLine {
content: Vec<(ui_model::Attrs, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
}
impl CmdLine {
pub fn new(
content: Vec<(ui_model::Attrs, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
) -> Self {
CmdLine {
content,
pos,
firstc,
prompt,
indent,
level,
}
}
}

View File

@ -4,13 +4,11 @@ mod handler;
mod mode_info; mod mode_info;
mod redraw_handler; mod redraw_handler;
mod repaint_mode; mod repaint_mode;
mod cmd_line;
pub use self::redraw_handler::{RedrawEvents, GuiApi}; pub use self::redraw_handler::{RedrawEvents, GuiApi};
pub use self::repaint_mode::RepaintMode; pub use self::repaint_mode::RepaintMode;
pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef}; pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef};
pub use self::mode_info::{ModeInfo, CursorShape}; pub use self::mode_info::{ModeInfo, CursorShape};
pub use self::cmd_line::{CmdLine};
use std::error; use std::error;
use std::fmt; use std::fmt;

View File

@ -37,7 +37,7 @@ pub trait RedrawEvents {
fn on_update_sp(&mut self, sp: i64) -> RepaintMode; fn on_update_sp(&mut self, sp: i64) -> RepaintMode;
fn on_mode_change(&mut self, mode: &str, idx: u64) -> RepaintMode; fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode;
fn on_mouse(&mut self, on: bool) -> RepaintMode; fn on_mouse(&mut self, on: bool) -> RepaintMode;
@ -45,7 +45,7 @@ pub trait RedrawEvents {
fn popupmenu_show( fn popupmenu_show(
&mut self, &mut self,
menu: &[Vec<&str>], menu: Vec<Vec<String>>,
selected: i64, selected: i64,
row: u64, row: u64,
col: u64, col: u64,
@ -118,6 +118,7 @@ macro_rules! map_array {
macro_rules! try_arg { macro_rules! try_arg {
($value:expr, bool) => (try_bool!($value)); ($value:expr, bool) => (try_bool!($value));
($value:expr, uint) => (try_uint!($value)); ($value:expr, uint) => (try_uint!($value));
($value:expr, int) => (try_int!($value));
($value:expr, str) => ( ($value:expr, str) => (
match $value { match $value {
Value::String(s) => { Value::String(s) => {
@ -198,31 +199,18 @@ pub fn call(
call!(ui->on_set_scroll_region(args: uint, uint, uint, uint)); call!(ui->on_set_scroll_region(args: uint, uint, uint, uint));
RepaintMode::Nothing RepaintMode::Nothing
} }
"scroll" => ui.on_scroll(try_int!(args[0])), "scroll" => call!(ui->on_scroll(args: int)),
"update_bg" => ui.on_update_bg(try_int!(args[0])), "update_bg" => call!(ui->on_update_bg(args: int)),
"update_fg" => ui.on_update_fg(try_int!(args[0])), "update_fg" => call!(ui->on_update_fg(args: int)),
"update_sp" => ui.on_update_sp(try_int!(args[0])), "update_sp" => call!(ui->on_update_sp(args: int)),
"mode_change" => ui.on_mode_change(try_str!(args[0]), try_uint!(args[1])), "mode_change" => call!(ui->on_mode_change(args: str, uint)),
"mouse_on" => ui.on_mouse(true), "mouse_on" => ui.on_mouse(true),
"mouse_off" => ui.on_mouse(false), "mouse_off" => ui.on_mouse(false),
"busy_start" => ui.on_busy(true), "busy_start" => ui.on_busy(true),
"busy_stop" => ui.on_busy(false), "busy_stop" => ui.on_busy(false),
"popupmenu_show" => { "popupmenu_show" => call!(ui->popupmenu_show(args: ext, int, uint, uint)),
let menu_items = map_array!(args[0], "Error get menu list array", |item| {
map_array!(item, "Error get menu item array", |col| {
col.as_str().ok_or("Error get menu column")
})
})?;
ui.popupmenu_show(
&menu_items,
try_int!(args[1]),
try_uint!(args[2]),
try_uint!(args[3]),
)
}
"popupmenu_hide" => ui.popupmenu_hide(), "popupmenu_hide" => ui.popupmenu_hide(),
"popupmenu_select" => ui.popupmenu_select(try_int!(args[0])), "popupmenu_select" => call!(ui->popupmenu_select(args: int)),
"tabline_update" => { "tabline_update" => {
let tabs_out = map_array!(args[1], "Error get tabline list".to_owned(), |tab| { let tabs_out = map_array!(args[1], "Error get tabline list".to_owned(), |tab| {
tab.as_map() tab.as_map()

View File

@ -10,9 +10,10 @@ use gdk::{EventButton, EventType};
use neovim_lib::{Neovim, NeovimApi}; use neovim_lib::{Neovim, NeovimApi};
use color::ColorModel; use color::ColorModel;
use nvim::{self, ErrorReport}; use nvim::{self, ErrorReport, NeovimClient};
use shell; use shell;
use input; use input;
use render;
const MAX_VISIBLE_ROWS: i32 = 10; const MAX_VISIBLE_ROWS: i32 = 10;
@ -41,25 +42,25 @@ impl State {
} }
} }
fn before_show(&mut self, shell: &shell::State, menu_items: &[Vec<&str>], selected: i64) { fn before_show(&mut self, ctx: PopupMenuContext) {
if self.nvim.is_none() { if self.nvim.is_none() {
self.nvim = Some(shell.nvim_clone()); self.nvim = Some(ctx.nvim.clone());
} }
self.update_tree(menu_items, shell); self.update_tree(&ctx);
self.select(selected); self.select(ctx.selected);
} }
fn update_tree(&self, menu: &[Vec<&str>], shell: &shell::State) { fn update_tree(&self, ctx: &PopupMenuContext) {
if menu.is_empty() { if ctx.menu_items.is_empty() {
return; return;
} }
self.renderer.set_property_font( self.renderer.set_property_font(Some(
Some(&shell.get_font_desc().to_string()), &ctx.font_ctx.font_description().to_string(),
); ));
let color_model = &shell.color_model; let color_model = &ctx.color_model;
self.renderer.set_property_foreground_rgba( self.renderer.set_property_foreground_rgba(
Some(&color_model.pmenu_fg().into()), Some(&color_model.pmenu_fg().into()),
); );
@ -69,7 +70,7 @@ impl State {
self.update_css(color_model); self.update_css(color_model);
let col_count = menu[0].len(); let col_count = ctx.menu_items[0].len();
let columns = self.tree.get_columns(); let columns = self.tree.get_columns();
if columns.len() != col_count { if columns.len() != col_count {
@ -85,7 +86,7 @@ impl State {
let list_store = gtk::ListStore::new(&vec![gtk::Type::String; col_count]); let list_store = gtk::ListStore::new(&vec![gtk::Type::String; col_count]);
let all_column_ids: Vec<u32> = (0..col_count).map(|i| i as u32).collect(); let all_column_ids: Vec<u32> = (0..col_count).map(|i| i as u32).collect();
for line in menu { for line in ctx.menu_items {
let line_array: Vec<&glib::ToValue> = let line_array: Vec<&glib::ToValue> =
line.iter().map(|v| v as &glib::ToValue).collect(); line.iter().map(|v| v as &glib::ToValue).collect();
list_store.insert_with_values(None, &all_column_ids, &line_array[..]); list_store.insert_with_values(None, &all_column_ids, &line_array[..]);
@ -215,30 +216,17 @@ impl PopupMenu {
self.open self.open
} }
pub fn show( pub fn show(&mut self, ctx: PopupMenuContext) {
&mut self,
shell: &shell::State,
menu_items: &[Vec<&str>],
selected: i64,
x: i32,
y: i32,
width: i32,
height: i32,
) {
self.open = true; self.open = true;
self.popover.set_pointing_to(&gtk::Rectangle { self.popover.set_pointing_to(&gtk::Rectangle {
x, x: ctx.x,
y, y: ctx.y,
width, width: ctx.width,
height, height: ctx.height,
}); });
self.state.borrow_mut().before_show( self.state.borrow_mut().before_show(ctx);
shell,
menu_items,
selected,
);
self.popover.popup() self.popover.popup()
} }
@ -255,6 +243,17 @@ impl PopupMenu {
} }
} }
pub struct PopupMenuContext<'a> {
pub nvim: &'a Rc<NeovimClient>,
pub color_model: &'a ColorModel,
pub font_ctx: &'a render::Context,
pub menu_items: &'a [Vec<String>],
pub selected: i64,
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
}
fn tree_button_press(tree: &gtk::TreeView, ev: &EventButton, nvim: &mut Neovim) -> Inhibit { fn tree_button_press(tree: &gtk::TreeView, ev: &EventButton, nvim: &mut Neovim) -> Inhibit {
if ev.get_event_type() != EventType::ButtonPress { if ev.get_event_type() != EventType::ButtonPress {

View File

@ -23,14 +23,14 @@ use ui_model::{UiModel, Attrs, ModelRect};
use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED};
use nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef, use nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef,
NeovimClientAsync, CmdLine}; NeovimClientAsync};
use input; use input::{self, keyval_to_input_string};
use input::keyval_to_input_string;
use cursor::Cursor; use cursor::Cursor;
use ui::UiMutex; use ui::UiMutex;
use popup_menu::PopupMenu; use popup_menu::{self, PopupMenu};
use tabline::Tabline; use tabline::Tabline;
use cmd_line::CmdLine;
use error; use error;
use mode; use mode;
use render; use render;
@ -66,7 +66,8 @@ pub struct State {
nvim: Rc<NeovimClient>, nvim: Rc<NeovimClient>,
pub font_ctx: render::Context, pub font_ctx: render::Context,
cursor: Option<Cursor>, cursor: Option<Cursor>,
popup_menu: RefCell<PopupMenu>, popup_menu: PopupMenu,
cmd_line: CmdLine,
settings: Rc<RefCell<Settings>>, settings: Rc<RefCell<Settings>>,
pub mode: mode::Mode, pub mode: mode::Mode,
@ -88,7 +89,7 @@ pub struct State {
impl State { impl State {
pub fn new(settings: Rc<RefCell<Settings>>, options: ShellOptions) -> State { pub fn new(settings: Rc<RefCell<Settings>>, options: ShellOptions) -> State {
let drawing_area = gtk::DrawingArea::new(); let drawing_area = gtk::DrawingArea::new();
let popup_menu = RefCell::new(PopupMenu::new(&drawing_area)); let popup_menu = PopupMenu::new(&drawing_area);
let font_ctx = render::Context::new(FontDescription::from_string(DEFAULT_FONT_NAME)); let font_ctx = render::Context::new(FontDescription::from_string(DEFAULT_FONT_NAME));
State { State {
@ -100,6 +101,7 @@ impl State {
font_ctx, font_ctx,
cursor: None, cursor: None,
popup_menu, popup_menu,
cmd_line: CmdLine::new(),
settings, settings,
mode: mode::Mode::new(), mode: mode::Mode::new(),
@ -183,7 +185,7 @@ impl State {
} }
fn close_popup_menu(&self) { fn close_popup_menu(&self) {
if self.popup_menu.borrow().is_open() { if self.popup_menu.is_open() {
if let Some(mut nvim) = self.nvim() { if let Some(mut nvim) = self.nvim() {
nvim.input("<Esc>").report_err(&mut *nvim); nvim.input("<Esc>").report_err(&mut *nvim);
} }
@ -306,6 +308,14 @@ impl State {
} }
fn get_window(&self) -> gtk::Window {
self.drawing_area
.get_toplevel()
.unwrap()
.downcast()
.unwrap()
}
fn resize_main_window(&mut self) { fn resize_main_window(&mut self) {
let &CellMetrics { let &CellMetrics {
line_height, line_height,
@ -319,11 +329,7 @@ impl State {
let request_width = (self.model.columns as f64 * char_width) as i32; let request_width = (self.model.columns as f64 * char_width) as i32;
if width != request_width || height != request_height { if width != request_width || height != request_height {
let window: gtk::Window = self.drawing_area let window = self.get_window();
.get_toplevel()
.unwrap()
.downcast()
.unwrap();
let (win_width, win_height) = window.get_size(); let (win_width, win_height) = window.get_size();
let h_border = win_width - width; let h_border = win_width - width;
let v_border = win_height - height; let v_border = win_height - height;
@ -998,8 +1004,8 @@ impl RedrawEvents for State {
RepaintMode::Nothing RepaintMode::Nothing
} }
fn on_mode_change(&mut self, mode: &str, idx: u64) -> RepaintMode { fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode {
self.mode.update(mode, idx as usize); self.mode.update(&mode, idx as usize);
RepaintMode::Area(self.model.cur_point()) RepaintMode::Area(self.model.cur_point())
} }
@ -1019,7 +1025,7 @@ impl RedrawEvents for State {
fn popupmenu_show( fn popupmenu_show(
&mut self, &mut self,
menu: &[Vec<&str>], menu: Vec<Vec<String>>,
selected: i64, selected: i64,
row: u64, row: u64,
col: u64, col: u64,
@ -1027,26 +1033,30 @@ impl RedrawEvents for State {
let point = ModelRect::point(col as usize, row as usize); let point = ModelRect::point(col as usize, row as usize);
let (x, y, width, height) = point.to_area(self.font_ctx.cell_metrics()); let (x, y, width, height) = point.to_area(self.font_ctx.cell_metrics());
self.popup_menu.borrow_mut().show( let context = popup_menu::PopupMenuContext {
self, nvim: &self.nvim,
menu, color_model: &self.color_model,
font_ctx: &self.font_ctx,
menu_items: &menu,
selected, selected,
x, x,
y, y,
width, width,
height, height
); };
self.popup_menu.show(context);
RepaintMode::Nothing RepaintMode::Nothing
} }
fn popupmenu_hide(&mut self) -> RepaintMode { fn popupmenu_hide(&mut self) -> RepaintMode {
self.popup_menu.borrow_mut().hide(); self.popup_menu.hide();
RepaintMode::Nothing RepaintMode::Nothing
} }
fn popupmenu_select(&mut self, selected: i64) -> RepaintMode { fn popupmenu_select(&mut self, selected: i64) -> RepaintMode {
self.popup_menu.borrow().select(selected); self.popup_menu.select(selected);
RepaintMode::Nothing RepaintMode::Nothing
} }
@ -1079,6 +1089,7 @@ impl RedrawEvents for State {
indent: u64, indent: u64,
level: u64, level: u64,
) -> RepaintMode { ) -> RepaintMode {
self.cmd_line.show(&self.get_window());
// TODO: implement // TODO: implement
RepaintMode::Nothing RepaintMode::Nothing
} }