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 settings;
mod cursor;
mod cmd_line;
mod shell_dlg;
mod popup_menu;
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 redraw_handler;
mod repaint_mode;
mod cmd_line;
pub use self::redraw_handler::{RedrawEvents, GuiApi};
pub use self::repaint_mode::RepaintMode;
pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef};
pub use self::mode_info::{ModeInfo, CursorShape};
pub use self::cmd_line::{CmdLine};
use std::error;
use std::fmt;

View File

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

View File

@ -10,9 +10,10 @@ use gdk::{EventButton, EventType};
use neovim_lib::{Neovim, NeovimApi};
use color::ColorModel;
use nvim::{self, ErrorReport};
use nvim::{self, ErrorReport, NeovimClient};
use shell;
use input;
use render;
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() {
self.nvim = Some(shell.nvim_clone());
self.nvim = Some(ctx.nvim.clone());
}
self.update_tree(menu_items, shell);
self.select(selected);
self.update_tree(&ctx);
self.select(ctx.selected);
}
fn update_tree(&self, menu: &[Vec<&str>], shell: &shell::State) {
if menu.is_empty() {
fn update_tree(&self, ctx: &PopupMenuContext) {
if ctx.menu_items.is_empty() {
return;
}
self.renderer.set_property_font(
Some(&shell.get_font_desc().to_string()),
);
self.renderer.set_property_font(Some(
&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(
Some(&color_model.pmenu_fg().into()),
);
@ -69,7 +70,7 @@ impl State {
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();
if columns.len() != col_count {
@ -85,7 +86,7 @@ impl State {
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();
for line in menu {
for line in ctx.menu_items {
let line_array: Vec<&glib::ToValue> =
line.iter().map(|v| v as &glib::ToValue).collect();
list_store.insert_with_values(None, &all_column_ids, &line_array[..]);
@ -215,30 +216,17 @@ impl PopupMenu {
self.open
}
pub fn show(
&mut self,
shell: &shell::State,
menu_items: &[Vec<&str>],
selected: i64,
x: i32,
y: i32,
width: i32,
height: i32,
) {
pub fn show(&mut self, ctx: PopupMenuContext) {
self.open = true;
self.popover.set_pointing_to(&gtk::Rectangle {
x,
y,
width,
height,
x: ctx.x,
y: ctx.y,
width: ctx.width,
height: ctx.height,
});
self.state.borrow_mut().before_show(
shell,
menu_items,
selected,
);
self.state.borrow_mut().before_show(ctx);
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 {
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 nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef,
NeovimClientAsync, CmdLine};
NeovimClientAsync};
use input;
use input::keyval_to_input_string;
use input::{self, keyval_to_input_string};
use cursor::Cursor;
use ui::UiMutex;
use popup_menu::PopupMenu;
use popup_menu::{self, PopupMenu};
use tabline::Tabline;
use cmd_line::CmdLine;
use error;
use mode;
use render;
@ -66,7 +66,8 @@ pub struct State {
nvim: Rc<NeovimClient>,
pub font_ctx: render::Context,
cursor: Option<Cursor>,
popup_menu: RefCell<PopupMenu>,
popup_menu: PopupMenu,
cmd_line: CmdLine,
settings: Rc<RefCell<Settings>>,
pub mode: mode::Mode,
@ -88,7 +89,7 @@ pub struct State {
impl State {
pub fn new(settings: Rc<RefCell<Settings>>, options: ShellOptions) -> State {
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));
State {
@ -100,6 +101,7 @@ impl State {
font_ctx,
cursor: None,
popup_menu,
cmd_line: CmdLine::new(),
settings,
mode: mode::Mode::new(),
@ -183,7 +185,7 @@ impl State {
}
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() {
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) {
let &CellMetrics {
line_height,
@ -319,11 +329,7 @@ impl State {
let request_width = (self.model.columns as f64 * char_width) as i32;
if width != request_width || height != request_height {
let window: gtk::Window = self.drawing_area
.get_toplevel()
.unwrap()
.downcast()
.unwrap();
let window = self.get_window();
let (win_width, win_height) = window.get_size();
let h_border = win_width - width;
let v_border = win_height - height;
@ -998,8 +1004,8 @@ impl RedrawEvents for State {
RepaintMode::Nothing
}
fn on_mode_change(&mut self, mode: &str, idx: u64) -> RepaintMode {
self.mode.update(mode, idx as usize);
fn on_mode_change(&mut self, mode: String, idx: u64) -> RepaintMode {
self.mode.update(&mode, idx as usize);
RepaintMode::Area(self.model.cur_point())
}
@ -1019,7 +1025,7 @@ impl RedrawEvents for State {
fn popupmenu_show(
&mut self,
menu: &[Vec<&str>],
menu: Vec<Vec<String>>,
selected: i64,
row: u64,
col: u64,
@ -1027,26 +1033,30 @@ impl RedrawEvents for State {
let point = ModelRect::point(col as usize, row as usize);
let (x, y, width, height) = point.to_area(self.font_ctx.cell_metrics());
self.popup_menu.borrow_mut().show(
self,
menu,
let context = popup_menu::PopupMenuContext {
nvim: &self.nvim,
color_model: &self.color_model,
font_ctx: &self.font_ctx,
menu_items: &menu,
selected,
x,
y,
width,
height,
);
height
};
self.popup_menu.show(context);
RepaintMode::Nothing
}
fn popupmenu_hide(&mut self) -> RepaintMode {
self.popup_menu.borrow_mut().hide();
self.popup_menu.hide();
RepaintMode::Nothing
}
fn popupmenu_select(&mut self, selected: i64) -> RepaintMode {
self.popup_menu.borrow().select(selected);
self.popup_menu.select(selected);
RepaintMode::Nothing
}
@ -1079,6 +1089,7 @@ impl RedrawEvents for State {
indent: u64,
level: u64,
) -> RepaintMode {
self.cmd_line.show(&self.get_window());
// TODO: implement
RepaintMode::Nothing
}