Add Padding to the TextBox (#36)
* WIP: initial text-margin support * Fix the selection issue when clicking the margins * Move the margin size into the main * using padding, consistent with iced text_input * Added top and bottom margin * bugfix: selection starting from the top margin works * bugfix: left half of first glyph was being ignored
This commit is contained in:
parent
bbe7d77b7b
commit
b253800383
3 changed files with 51 additions and 19 deletions
|
|
@ -11,6 +11,7 @@ use cosmic::{
|
|||
mouse::{self, Button, Event as MouseEvent, ScrollDelta},
|
||||
renderer,
|
||||
widget::{self, tree, Widget},
|
||||
Padding
|
||||
},
|
||||
};
|
||||
use cosmic_text::{
|
||||
|
|
@ -27,14 +28,21 @@ use super::text;
|
|||
|
||||
pub struct SyntaxTextBox<'a> {
|
||||
editor: &'a Mutex<SyntaxEditor<'static>>,
|
||||
padding: Padding,
|
||||
}
|
||||
|
||||
impl<'a> SyntaxTextBox<'a> {
|
||||
pub fn new(editor: &'a Mutex<SyntaxEditor<'static>>) -> Self {
|
||||
Self {
|
||||
editor,
|
||||
padding: Padding::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
|
||||
self.padding = padding.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn syntax_text_box<'a>(editor: &'a Mutex<SyntaxEditor<'static>>) -> SyntaxTextBox<'a> {
|
||||
|
|
@ -116,8 +124,8 @@ where
|
|||
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
|
||||
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32);
|
||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32);
|
||||
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32) - self.padding.horizontal() as i32;
|
||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32)- self.padding.vertical() as i32;
|
||||
editor.buffer_mut().set_size(view_w, view_h);
|
||||
|
||||
editor.shape_as_needed();
|
||||
|
|
@ -137,7 +145,7 @@ where
|
|||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
bounds: Rectangle::new(
|
||||
Point::new(layout.position().x + x as f32, layout.position().y + y as f32),
|
||||
layout.position() + [x as f32, y as f32].into() + [self.padding.left as f32, self.padding.top as f32].into(),
|
||||
Size::new(w as f32, h as f32)
|
||||
),
|
||||
border_radius: 0.0,
|
||||
|
|
@ -158,7 +166,7 @@ where
|
|||
|
||||
let handle = image::Handle::from_pixels(view_w as u32, view_h as u32, pixels);
|
||||
image::Renderer::draw(renderer, handle, Rectangle::new(
|
||||
layout.position(),
|
||||
layout.position() + [self.padding.left as f32, self.padding.top as f32].into(),
|
||||
Size::new(view_w as f32, view_h as f32)
|
||||
));
|
||||
|
||||
|
|
@ -235,8 +243,8 @@ where
|
|||
Event::Mouse(MouseEvent::ButtonPressed(Button::Left)) => {
|
||||
if layout.bounds().contains(cursor_position) {
|
||||
editor.action(Action::Click {
|
||||
x: (cursor_position.x - layout.bounds().x) as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32,
|
||||
x: (cursor_position.x - layout.bounds().x) as i32 - self.padding.left as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32 - self.padding.top as i32,
|
||||
});
|
||||
state.is_dragging = true;
|
||||
status = Status::Captured;
|
||||
|
|
@ -249,8 +257,8 @@ where
|
|||
Event::Mouse(MouseEvent::CursorMoved { .. }) => {
|
||||
if state.is_dragging {
|
||||
editor.action(Action::Drag {
|
||||
x: (cursor_position.x - layout.bounds().x) as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32,
|
||||
x: (cursor_position.x - layout.bounds().x) as i32 - self.padding.left as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32 - self.padding.top as i32,
|
||||
});
|
||||
status = Status::Captured;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use cosmic::{
|
|||
mouse::{self, Button, Event as MouseEvent, ScrollDelta},
|
||||
renderer,
|
||||
widget::{self, tree, Widget},
|
||||
Padding
|
||||
},
|
||||
theme::Theme,
|
||||
};
|
||||
|
|
@ -52,14 +53,22 @@ impl StyleSheet for Theme {
|
|||
|
||||
pub struct TextBox<'a> {
|
||||
editor: &'a Mutex<Editor<'static>>,
|
||||
padding: Padding,
|
||||
}
|
||||
|
||||
impl<'a> TextBox<'a> {
|
||||
pub fn new(editor: &'a Mutex<Editor<'static>>) -> Self {
|
||||
Self {
|
||||
editor,
|
||||
padding: Padding::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
|
||||
self.padding = padding.into();
|
||||
self
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn text_box<'a>(editor: &'a Mutex<Editor<'static>>) -> TextBox<'a> {
|
||||
|
|
@ -163,8 +172,8 @@ where
|
|||
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
|
||||
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32);
|
||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32);
|
||||
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32) - self.padding.horizontal() as i32;
|
||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32) - self.padding.vertical() as i32;
|
||||
editor.buffer.set_size(view_w, view_h);
|
||||
|
||||
editor.shape_as_needed();
|
||||
|
|
@ -184,8 +193,8 @@ where
|
|||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
bounds: Rectangle::new(
|
||||
Point::new(layout.position().x + x as f32, layout.position().y + y as f32),
|
||||
Size::new(w as f32, h as f32)
|
||||
layout.position() + [x as f32, y as f32].into() + [self.padding.left as f32, self.padding.top as f32].into(),
|
||||
Size::new(w as f32 , h as f32)
|
||||
),
|
||||
border_radius: 0.0,
|
||||
border_width: 0.0,
|
||||
|
|
@ -205,7 +214,7 @@ where
|
|||
|
||||
let handle = image::Handle::from_pixels(view_w as u32, view_h as u32, pixels);
|
||||
image::Renderer::draw(renderer, handle, Rectangle::new(
|
||||
layout.position(),
|
||||
layout.position() + [self.padding.left as f32, self.padding.top as f32].into(),
|
||||
Size::new(view_w as f32, view_h as f32)
|
||||
));
|
||||
|
||||
|
|
@ -282,8 +291,8 @@ where
|
|||
Event::Mouse(MouseEvent::ButtonPressed(Button::Left)) => {
|
||||
if layout.bounds().contains(cursor_position) {
|
||||
editor.action(Action::Click {
|
||||
x: (cursor_position.x - layout.bounds().x) as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32,
|
||||
x: (cursor_position.x - layout.bounds().x) as i32 - self.padding.left as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32 - self.padding.top as i32,
|
||||
});
|
||||
state.is_dragging = true;
|
||||
status = Status::Captured;
|
||||
|
|
@ -296,8 +305,8 @@ where
|
|||
Event::Mouse(MouseEvent::CursorMoved { .. }) => {
|
||||
if state.is_dragging {
|
||||
editor.action(Action::Drag {
|
||||
x: (cursor_position.x - layout.bounds().x) as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32,
|
||||
x: (cursor_position.x - layout.bounds().x) as i32 - self.padding.left as i32,
|
||||
y: (cursor_position.y - layout.bounds().y) as i32 - self.padding.top as i32,
|
||||
});
|
||||
status = Status::Captured;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,15 +424,30 @@ impl<'a> Buffer<'a> {
|
|||
let mut new_cursor_opt = None;
|
||||
|
||||
let mut runs = self.layout_runs().peekable();
|
||||
let mut first_run = true;
|
||||
while let Some(run) = runs.next() {
|
||||
let line_y = run.line_y;
|
||||
|
||||
if y >= line_y - font_size
|
||||
&& y < line_y - font_size + line_height
|
||||
if first_run && y < line_y - font_size {
|
||||
first_run = false;
|
||||
let new_cursor = Cursor::new(run.line_i, 0);
|
||||
new_cursor_opt = Some(new_cursor);
|
||||
} else if y >= line_y - font_size
|
||||
&& y < line_y - font_size + line_height
|
||||
{
|
||||
let mut new_cursor_glyph = run.glyphs.len();
|
||||
let mut new_cursor_char = 0;
|
||||
|
||||
let mut first_glyph = true;
|
||||
|
||||
'hit: for (glyph_i, glyph) in run.glyphs.iter().enumerate() {
|
||||
if first_glyph {
|
||||
first_glyph = false;
|
||||
if (run.rtl && x > glyph.x as i32) || (!run.rtl && x < 0) {
|
||||
new_cursor_glyph = 0;
|
||||
new_cursor_char = 0;
|
||||
}
|
||||
}
|
||||
if x >= glyph.x as i32
|
||||
&& x <= (glyph.x + glyph.w) as i32
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue