-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
999 additions
and
815 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
use std::ops::{Deref, DerefMut}; | ||
|
||
use winit::keyboard::KeyCode; | ||
use crate::assets::DARK_STRIPE_UV; | ||
|
||
use crate::color::TextColor; | ||
use crate::StrExt; | ||
use crate::text::{Cachelike, KeyResult, Text}; | ||
use crate::vertex_buffer_builder::{Vec2u, VertexBufferBuilder}; | ||
|
||
#[derive(Clone, Eq)] | ||
pub struct SearchBoxCache { | ||
value: String, | ||
cursor: usize, | ||
selection: Option<usize>, | ||
} | ||
|
||
impl PartialEq for SearchBoxCache { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.value == other.value | ||
} | ||
} | ||
|
||
impl Cachelike<SearchBoxAdditional> for SearchBoxCache { | ||
fn new(text: &Text<SearchBoxAdditional, Self>) -> Self where Self: Sized { | ||
Self { | ||
value: text.value.clone(), | ||
cursor: text.cursor, | ||
selection: text.selection, | ||
} | ||
} | ||
|
||
fn revert(self, text: &mut Text<SearchBoxAdditional, Self>) where Self: Sized { | ||
text.value = self.value; | ||
text.cursor = self.cursor; | ||
text.selection = self.selection; | ||
} | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct SearchBoxAdditional { | ||
selected: bool, | ||
horizontal_scroll: usize, | ||
} | ||
|
||
pub struct SearchBox(Text<SearchBoxAdditional, SearchBoxCache>); | ||
|
||
impl Deref for SearchBox { | ||
type Target = Text<SearchBoxAdditional, SearchBoxCache>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl DerefMut for SearchBox { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl SearchBox { | ||
pub fn new() -> Self { | ||
Self(Text::new(String::new(), 0, true, SearchBoxAdditional { selected: false, horizontal_scroll: 0 })) | ||
} | ||
|
||
pub const fn uninit() -> Self { | ||
Self(Text::uninit()) | ||
} | ||
|
||
pub fn render(&self, builder: &mut VertexBufferBuilder) { | ||
use std::fmt::Write; | ||
|
||
let pos = Vec2u::new(284, 23); | ||
|
||
builder.draw_texture_region_z( | ||
pos, | ||
0, | ||
DARK_STRIPE_UV, | ||
(builder.window_width() - 215 - pos.x, 22), | ||
(16, 16), | ||
); | ||
|
||
builder.horizontal_scroll = self.horizontal_scroll; | ||
if self.value.is_empty() { | ||
builder.settings(pos + (0, 3), false, 0); | ||
builder.color = TextColor::Gray.to_raw(); | ||
let _ = write!(builder, "Search..."); | ||
} | ||
if self.is_selected() { | ||
self.0.render(builder, TextColor::White, pos + (0, 3), 0); | ||
} else { | ||
builder.settings(pos + (0, 3), false, 0); | ||
builder.color = TextColor::White.to_raw(); | ||
let _ = write!(builder, "{}", self.value); | ||
} | ||
builder.horizontal_scroll = 0; | ||
} | ||
|
||
#[inline] | ||
pub fn deselect(&mut self) { | ||
self.selected = false; | ||
self.cursor = 0; | ||
self.selection = None; | ||
// better ui this way | ||
// self.horizontal_scroll = 0; | ||
} | ||
|
||
#[inline] | ||
pub fn select(&mut self, x: usize) { | ||
let x = x + self.horizontal_scroll; | ||
self.cursor = 'a: { | ||
let mut current_x = 0; | ||
for (idx, char) in self.value.char_indices() { | ||
let width = if (x as u32) < 56832 { VertexBufferBuilder::CHAR_WIDTH[char as usize] as usize } else { 0 }; | ||
if current_x + width / 2 >= x { | ||
break 'a idx; | ||
} | ||
current_x += width; | ||
} | ||
self.value.len() | ||
}; | ||
self.selected = true; | ||
self.interact(); | ||
} | ||
|
||
#[inline] | ||
pub fn search(&mut self) { | ||
todo!() | ||
} | ||
|
||
#[inline] | ||
#[must_use] | ||
pub fn is_selected(&self) -> bool { | ||
self.selected | ||
} | ||
|
||
#[inline] | ||
pub fn post_input(&mut self, window_dims: (usize, usize)) { | ||
let (window_width, _) = window_dims; | ||
self.0.post_input(); | ||
let field_width = window_width - 215 - 284; | ||
let precursor_width = self.value.split_at(self.cursor).0.width(); | ||
// 8px space just to look cleaner | ||
let horizontal_scroll = (precursor_width + 8).saturating_sub(field_width); | ||
self.horizontal_scroll = horizontal_scroll; | ||
} | ||
|
||
#[must_use] | ||
pub fn on_key_press(&mut self, key: KeyCode, char: Option<char>, flags: u8) -> KeyResult { | ||
self.0.on_key_press(key, char, flags) | ||
} | ||
} |
Oops, something went wrong.