Point to cursor
This commit is contained in:
parent
83061366dd
commit
c27fbff586
@ -11,31 +11,27 @@ use neovim_lib::Value;
|
||||
|
||||
use ui_model::{Attrs, ModelLayout};
|
||||
use ui::UiMutex;
|
||||
use render;
|
||||
use render::{self, CellMetrics};
|
||||
use shell;
|
||||
use cursor;
|
||||
|
||||
pub struct Level {
|
||||
model_layout: ModelLayout,
|
||||
preferred_width: i32,
|
||||
preferred_height: i32,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
|
||||
pub fn from(
|
||||
content: Vec<(HashMap<String, Value>, String)>,
|
||||
pos: u64,
|
||||
firstc: String,
|
||||
prompt: String,
|
||||
indent: u64,
|
||||
) -> Self {
|
||||
//TODO: double width chars
|
||||
pub fn from(ctx: &CmdLineContext, render_state: &shell::RenderState) -> Self {
|
||||
//TODO: double width chars render, also note in text wrapping
|
||||
//TODO: im
|
||||
|
||||
let content_line: Vec<(Option<Attrs>, Vec<char>)> = content
|
||||
let content_line: Vec<(Option<Attrs>, Vec<char>)> = ctx.content
|
||||
.iter()
|
||||
.map(|c| (Some(Attrs::from_value_map(&c.0)), c.1.chars().collect()))
|
||||
.collect();
|
||||
let prompt_lines = prompt_lines(firstc, prompt, indent);
|
||||
let prompt_lines = prompt_lines(&ctx.firstc, &ctx.prompt, ctx.indent);
|
||||
|
||||
let mut content: Vec<_> = prompt_lines.into_iter().map(|line| vec![line]).collect();
|
||||
|
||||
@ -45,11 +41,20 @@ impl Level {
|
||||
content.last_mut().map(|line| line.extend(content_line));
|
||||
}
|
||||
|
||||
let mut model_layout = ModelLayout::new();
|
||||
// TODO: calculate width
|
||||
model_layout.layout(content, 5);
|
||||
let &CellMetrics {
|
||||
line_height,
|
||||
char_width,
|
||||
..
|
||||
} = render_state.font_ctx.cell_metrics();
|
||||
|
||||
Level { model_layout }
|
||||
let max_width_chars = (ctx.max_width as f64 / char_width) as u64;
|
||||
|
||||
let mut model_layout = ModelLayout::new();
|
||||
let (columns, rows) = model_layout.layout(content, max_width_chars);
|
||||
|
||||
let preferred_width = (char_width * columns as f64) as i32;
|
||||
let preferred_height = (line_height * rows as f64) as i32;
|
||||
Level { model_layout, preferred_width, preferred_height }
|
||||
}
|
||||
|
||||
fn update_cache(&mut self, render_state: &shell::RenderState) {
|
||||
@ -61,7 +66,7 @@ impl Level {
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_lines(firstc: String, prompt: String, indent: u64) -> Vec<(Option<Attrs>, Vec<char>)> {
|
||||
fn prompt_lines(firstc: &str, prompt: &str, indent: u64) -> Vec<(Option<Attrs>, Vec<char>)> {
|
||||
if !firstc.is_empty() {
|
||||
vec![(None, firstc.chars().chain((0..indent).map(|_| ' ')).collect())]
|
||||
} else if !prompt.is_empty() {
|
||||
@ -103,7 +108,7 @@ impl CmdLine {
|
||||
pub fn new(drawing: >k::DrawingArea, render_state: Rc<RefCell<shell::RenderState>>) -> Self {
|
||||
let popover = gtk::Popover::new(Some(drawing));
|
||||
popover.set_modal(false);
|
||||
popover.set_position(gtk::PositionType::Top);
|
||||
popover.set_position(gtk::PositionType::Right);
|
||||
|
||||
let edit_frame = gtk::Frame::new(None);
|
||||
edit_frame.set_shadow_type(gtk::ShadowType::In);
|
||||
@ -131,31 +136,25 @@ impl CmdLine {
|
||||
|
||||
pub fn show_level(
|
||||
&mut self,
|
||||
content: Vec<(HashMap<String, Value>, String)>,
|
||||
pos: u64,
|
||||
firstc: String,
|
||||
prompt: String,
|
||||
indent: u64,
|
||||
level_idx: u64,
|
||||
ctx: &CmdLineContext,
|
||||
) {
|
||||
let mut state = self.state.borrow_mut();
|
||||
|
||||
let mut level = Level::from(content, pos, firstc, prompt, indent);
|
||||
let mut level = Level::from(ctx, &*state.render_state.borrow());
|
||||
level.update_cache(&*state.render_state.borrow());
|
||||
|
||||
if level_idx as usize == state.levels.len() {
|
||||
if ctx.level_idx as usize == state.levels.len() {
|
||||
// TODO: update level
|
||||
state.levels.pop();
|
||||
}
|
||||
state.levels.push(level);
|
||||
if !self.displyed {
|
||||
self.displyed = true;
|
||||
let allocation = self.popover.get_relative_to().unwrap().get_allocation();
|
||||
self.popover.set_pointing_to(>k::Rectangle {
|
||||
x: allocation.width / 2,
|
||||
y: allocation.height / 2,
|
||||
width: 1,
|
||||
height: 1,
|
||||
x: ctx.x,
|
||||
y: ctx.y,
|
||||
width: ctx.width,
|
||||
height: ctx.height,
|
||||
});
|
||||
|
||||
self.popover.popup();
|
||||
@ -200,3 +199,17 @@ fn gtk_draw(
|
||||
}
|
||||
Inhibit(false)
|
||||
}
|
||||
|
||||
pub struct CmdLineContext {
|
||||
pub content: Vec<(HashMap<String, Value>, String)>,
|
||||
pub pos: u64,
|
||||
pub firstc: String,
|
||||
pub prompt: String,
|
||||
pub indent: u64,
|
||||
pub level_idx: u64,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub max_width: i32,
|
||||
}
|
||||
|
21
src/shell.rs
21
src/shell.rs
@ -30,7 +30,7 @@ use cursor::{Cursor, CursorRedrawCb};
|
||||
use ui::UiMutex;
|
||||
use popup_menu::{self, PopupMenu};
|
||||
use tabline::Tabline;
|
||||
use cmd_line::CmdLine;
|
||||
use cmd_line::{CmdLine, CmdLineContext};
|
||||
use error;
|
||||
use mode;
|
||||
use render;
|
||||
@ -1186,7 +1186,24 @@ impl RedrawEvents for State {
|
||||
indent: u64,
|
||||
level: u64,
|
||||
) -> RepaintMode {
|
||||
self.cmd_line.show_level(content, pos, firstc, prompt, indent, level);
|
||||
let cursor = self.model.cur_point();
|
||||
let render_state = self.render_state.borrow();
|
||||
let (x, y, width, height) = cursor.to_area(render_state.font_ctx.cell_metrics());
|
||||
let ctx = CmdLineContext {
|
||||
content,
|
||||
pos,
|
||||
firstc,
|
||||
prompt,
|
||||
indent,
|
||||
level_idx: level,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
max_width: self.drawing_area.get_allocated_width() - 20,
|
||||
};
|
||||
|
||||
self.cmd_line.show_level(&ctx);
|
||||
RepaintMode::Nothing
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,11 @@ impl ModelLayout {
|
||||
}
|
||||
|
||||
/// Wrap all lines into model
|
||||
pub fn layout(&mut self, lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>, columns: u64) {
|
||||
if lines.len() > self.model.rows || columns as usize > self.model.columns {
|
||||
let model_cols = ((columns / ModelLayout::COLUMNS_STEP) + 1) *
|
||||
///
|
||||
/// returns actual width
|
||||
pub fn layout(&mut self, lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>, max_columns: u64) -> (u64, u64) {
|
||||
if lines.len() > self.model.rows || max_columns as usize > self.model.columns {
|
||||
let model_cols = ((max_columns / ModelLayout::COLUMNS_STEP) + 1) *
|
||||
ModelLayout::COLUMNS_STEP;
|
||||
let model_rows = ((lines.len() as u64 / ModelLayout::ROWS_STEP) + 1) *
|
||||
ModelLayout::ROWS_STEP;
|
||||
@ -24,16 +26,21 @@ impl ModelLayout {
|
||||
}
|
||||
|
||||
|
||||
let mut max_col_idx = 0;
|
||||
let mut col_idx = 0;
|
||||
let mut row_idx = 0;
|
||||
for content in lines {
|
||||
for (attr, ch_list) in content {
|
||||
for ch in ch_list {
|
||||
if col_idx >= columns {
|
||||
if col_idx >= max_columns {
|
||||
col_idx = 0;
|
||||
row_idx += 1;
|
||||
}
|
||||
|
||||
if max_col_idx < col_idx {
|
||||
max_col_idx = col_idx;
|
||||
}
|
||||
|
||||
self.model.set_cursor(row_idx, col_idx as usize);
|
||||
self.model.put(ch, false, attr.as_ref());
|
||||
col_idx += 1;
|
||||
@ -41,5 +48,7 @@ impl ModelLayout {
|
||||
}
|
||||
row_idx += 1;
|
||||
}
|
||||
|
||||
(max_col_idx + 1, row_idx as u64)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user