use crate::frame::context::UpdateType;
use crate::render::rectangle::param::RectParam;
use crate::render::{RenderParam, WrcRender};
use crate::size::border::Border;
use crate::size::pos::Pos;
use crate::size::radius::Radius;
use crate::size::rect::Rect;
use crate::style::color::Color;
use crate::style::ClickStyle;
use crate::ui::Ui;
use crate::widgets::textedit::buffer::CharBuffer;
use crate::widgets::textedit::cursor::EditCursor;
use crate::Offset;
use crate::window::UserEvent;
pub struct EditSelection {
renders: Vec<RenderParam<RectParam>>,
changed: bool,
pub(crate) has_selected: bool,
pub(crate) start_vert: usize,
pub(crate) start_horiz: usize,
}
impl EditSelection {
pub fn new() -> EditSelection {
EditSelection {
renders: vec![],
changed: false,
has_selected: false,
start_vert: 0,
start_horiz: 0,
}
}
pub fn init(&mut self, rows: usize, rect: &Rect, line_height: f32, ui: &mut Ui, init: bool) {
if init {
let mut select_style = ClickStyle::new();
select_style.fill.inactive = Color::rgba(255, 0, 0, 100); select_style.fill.hovered = Color::rgba(144, 209, 255, 100);
select_style.fill.clicked = Color::rgba(144, 209, 255, 100);
select_style.border.inactive = Border::new(0.0).radius(Radius::same(0));
select_style.border.hovered = Border::new(0.0).radius(Radius::same(0));
select_style.border.clicked = Border::new(0.0).radius(Radius::same(0));
for row in 0..rows {
let mut rect = rect.clone();
rect.set_x_max(rect.dx().min);
rect.set_height(line_height);
rect.offset(&Offset::new(Pos::new()).with_y(row as f32 * line_height).covered());
let render = RenderParam::new(RectParam::new(rect, select_style.clone()));
self.renders.push(render);
}
}
self.renders.iter_mut().for_each(|x| x.init_rectangle(ui, false, false));
}
pub fn set_by_cursor(&mut self, cursor: &EditCursor) {
let x = cursor.cursor_min();
for (index, render) in self.renders.iter_mut().enumerate() {
if index == cursor.vert {
render.param.rect.set_x_min(x);
render.param.rect.set_x_max(x);
} else {
render.param.rect.set_x_max(render.param.rect.dx().min);
}
}
self.start_vert = cursor.vert;
self.start_horiz = cursor.horiz;
self.changed = true;
}
pub fn update(&mut self, ui: &mut Ui) {
if !self.changed { return; }
self.changed = false;
for render in self.renders.iter_mut() {
render.update(ui, false, false);
}
}
pub fn render(&mut self, ui: &mut Ui, rows: usize) {
let pass = ui.pass.as_mut().unwrap();
for (index, render) in self.renders.iter().enumerate() {
if index >= rows { continue; }
ui.context.render.rectangle.render(render, pass);
}
}
pub fn reset(&mut self, cursor: &EditCursor) {
for render in self.renders.iter_mut() {
render.param.rect.set_x_max(render.param.rect.dx().min);
}
self.start_vert = cursor.vert;
self.start_horiz = cursor.horiz;
self.changed = true;
self.has_selected = false;
}
pub fn move_select(&mut self, ui: &mut Ui, cursor: &mut EditCursor, cchar: &mut CharBuffer) {
let pos = ui.device.device_input.mouse.lastest;
cursor.update_by_pos(pos, cchar);
if cursor.vert > self.start_vert { for (index, render) in self.renders.iter_mut().enumerate() {
if index == self.start_vert {
let line = &cchar.buffer.lines[index];
render.param.rect.set_x_min(line.get_width_in_char(self.start_horiz) + cursor.min_pos.x);
render.param.rect.set_x_max(line.width + cursor.min_pos.x);
} else if index == cursor.vert {
render.param.rect.set_x_min(cursor.min_pos.x);
render.param.rect.set_x_max(cursor.cursor_min());
} else if index > self.start_vert && index < cursor.vert {
let line = &cchar.buffer.lines[index];
render.param.rect.set_x_min(cursor.min_pos.x);
render.param.rect.set_x_max(cursor.min_pos.x + line.width);
} else {
render.param.rect.set_x_max(render.param.rect.dx().min);
}
}
} else if cursor.vert < self.start_vert { for (index, render) in self.renders.iter_mut().enumerate() {
if index == self.start_vert {
render.param.rect.set_x_min(cursor.min_pos.x);
} else if index == cursor.vert {
let line = &cchar.buffer.lines[index];
render.param.rect.set_x_min(cursor.cursor_min());
render.param.rect.set_x_max(cursor.min_pos.x + line.width);
} else if index > cursor.vert && index < self.start_vert {
let line = &cchar.buffer.lines[index];
render.param.rect.set_x_min(cursor.min_pos.x);
render.param.rect.set_x_max(cursor.min_pos.x + line.width);
} else {
render.param.rect.set_x_max(render.param.rect.dx().min);
}
}
} else { for (index, render) in self.renders.iter_mut().enumerate() {
if index != cursor.vert {
render.param.rect.set_x_max(render.param.rect.dx().min);
continue;
}
let line = &cchar.buffer.lines[self.start_vert];
if cursor.horiz > self.start_horiz { let ox = line.get_width_in_char(self.start_horiz) + cchar.offset.x;
let ox = if cursor.min_pos.x + ox < cursor.min_pos.x { cursor.min_pos.x } else { cursor.min_pos.x + ox };
render.param.rect.set_x_min(ox);
render.param.rect.set_x_max(cursor.cursor_min());
} else if cursor.horiz < self.start_horiz { render.param.rect.set_x_min(cursor.cursor_min());
let ox = line.get_width_in_char(self.start_horiz) + cchar.offset.x;
let ox = if cursor.min_pos.x + ox > cursor.max_pos.x { cursor.max_pos.x } else { cursor.min_pos.x + ox };
render.param.rect.set_x_max(ox);
}
if pos.x > cursor.max_pos.x {
let wid = ui.context.window.id();
ui.context.user_update = (wid, UpdateType::None);
let window = ui.context.window.clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(100));
window.request_update_event(UserEvent::ReqUpdate);
});
} else if pos.x < cursor.min_pos.x {
let wid = ui.context.window.id();
ui.context.user_update = (wid, UpdateType::None);
let window = ui.context.window.clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(100));
window.request_update_event(UserEvent::ReqUpdate);
});
}
}
}
self.has_selected = true;
println!("move_select-{} {} {} {}", self.start_horiz, self.start_vert, cursor.horiz, cursor.vert);
if self.start_horiz == cursor.horiz && self.start_vert == cursor.vert { self.has_selected = false; }
self.changed = true;
}
pub fn select_by_ime(&mut self, start_horiz: usize, start_vert: usize, cchar: &CharBuffer, cursor: &EditCursor) {
self.reset(cursor);
self.start_horiz = start_horiz;
self.start_vert = start_vert;
self.has_selected = true;
if start_vert == cursor.vert { let line = &cchar.buffer.lines[cursor.vert];
let x_min = line.get_width_in_char(start_horiz) + cursor.min_pos.x;
let x_max = line.get_width_in_char(cursor.horiz) + cursor.min_pos.x;
self.renders[cursor.vert].param.rect.set_x_min(x_min);
self.renders[cursor.vert].param.rect.set_x_max(x_max);
} else {
let start_line = &cchar.buffer.lines[start_vert];
let end_line = &cchar.buffer.lines[cursor.vert];
let sm = start_line.get_width_in_char(start_horiz) + cursor.min_pos.x;
self.renders[start_vert].param.rect.set_x_min(sm);
self.renders[start_vert].param.rect.set_x_max(cursor.max_pos.x);
self.renders[cursor.vert].param.rect.set_x_min(cursor.min_pos.x);
let em = end_line.get_width_in_char(cursor.horiz) + cursor.min_pos.x;
self.renders[cursor.vert].param.rect.set_x_max(em);
for v in start_vert + 1..cursor.vert {
self.renders[v].param.rect.set_x_min(cursor.min_pos.x);
self.renders[v].param.rect.set_x_max(cursor.max_pos.x);
}
}
self.changed = true;
}
pub fn update_position(&mut self, ui: &mut Ui, mut rect: Rect) {
for render in self.renders.iter_mut() {
render.param.rect.offset_y_to(rect.dy().min);
render.update(ui, false, false);
rect.add_min_y(render.param.rect.height());
}
}
}