fixed up subframes and started work on refactoring into components
This commit is contained in:
parent
cf0b013204
commit
e6323d4009
|
@ -81,33 +81,60 @@ pub struct SigninPage {
|
|||
hostname: String,
|
||||
username: String,
|
||||
cursor: SigninCursorLocation,
|
||||
cursor_position: u16,
|
||||
frame: Option<Frame>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum SigninCursorLocation {
|
||||
Hostname,
|
||||
Username,
|
||||
Next,
|
||||
Hostname(u16),
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl Default for SigninCursorLocation {
|
||||
fn default() -> Self {
|
||||
Self::Hostname
|
||||
Self::Ok
|
||||
}
|
||||
}
|
||||
|
||||
impl SigninPage {
|
||||
#[inline]
|
||||
fn draw(&self) -> String {
|
||||
fn draw(&self, highlight: ColorSet, normal: ColorSet) -> String {
|
||||
const HEADER_Y: u16 = 1;
|
||||
const HOSTNAME_Y: u16 = 3;
|
||||
const OK_Y: u16 = 5;
|
||||
let frame = self.frame.unwrap();
|
||||
let fr_width = frame.size().0;
|
||||
let total_width = fr_width / 3;
|
||||
|
||||
format!(
|
||||
"{header}{hostname}",
|
||||
header = frame.write_centered("login kk", 1)
|
||||
hostname = frame.write_centered("instance:", 3),
|
||||
"{header}{hostname}{retheme}{ok}",
|
||||
header = frame.write_centered("login kk", HEADER_Y),
|
||||
hostname = frame.write_centered(
|
||||
&self.field_str(
|
||||
highlight,
|
||||
total_width,
|
||||
"hostname",
|
||||
"",
|
||||
),
|
||||
HOSTNAME_Y,
|
||||
),
|
||||
retheme = normal.to_string(),
|
||||
ok = frame.write_centered("[ok]", OK_Y),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn field_str(
|
||||
&self,
|
||||
color: ColorSet,
|
||||
width: u16,
|
||||
field: &str,
|
||||
field_content: &str,
|
||||
) -> String {
|
||||
let unpadded = format!("{field}: {field_content}",);
|
||||
let len = field.len() + field_content.len() + 2;
|
||||
unpadded + &"_".repeat(width as usize - len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Page for SigninPage {
|
||||
|
@ -140,22 +167,25 @@ impl Page for SigninPage {
|
|||
screen: &mut RawTerminal<Stdout>,
|
||||
) -> Result<()> {
|
||||
self.frame = Some(env.frame.sub(
|
||||
env.theme.colors.subwin,
|
||||
super::frame::FrameSize::ByPercent(80, 80),
|
||||
env.theme.colors.subframe,
|
||||
super::frame::FrameSize::ByPercent(50, 50),
|
||||
2,
|
||||
));
|
||||
write!(
|
||||
screen,
|
||||
"{theme}{clear}{frame}{subframe}{show_cursor}{content}",
|
||||
"{theme}{clear}{frame}{subframe}{content}{hide_cursor}",
|
||||
theme = env.theme.frame(),
|
||||
clear = clear::All,
|
||||
frame = env.frame.frame_str(env.theme.primary()),
|
||||
subframe = self
|
||||
.frame
|
||||
.unwrap()
|
||||
.frame_str(ColorSet::default().to_string()),
|
||||
show_cursor = cursor::Show,
|
||||
content = self.draw(),
|
||||
.frame_str(env.theme.colors.subwin.to_string()),
|
||||
hide_cursor = cursor::Hide,
|
||||
content = self.draw(
|
||||
env.theme.colors.highlight,
|
||||
env.theme.colors.subwin
|
||||
),
|
||||
)?;
|
||||
screen.flush()?;
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use super::{frame::Frame, theme::ColorSet};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Component {
|
||||
String(String),
|
||||
Goto(u16, u16),
|
||||
Theme(ColorSet),
|
||||
Clear,
|
||||
}
|
||||
|
||||
impl Component {
|
||||
pub fn prepare_for(&self, frame: &Frame) -> String {
|
||||
match self {
|
||||
Component::String(s) => s.to_owned(),
|
||||
Component::Goto(x, y) => frame.goto(*x, *y),
|
||||
Component::Theme(c) => c.to_string(),
|
||||
Component::Clear => termion::clear::All.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Components(Vec<Component>);
|
||||
|
||||
impl Deref for Components {
|
||||
type Target = Vec<Component>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Component>> for Components {
|
||||
fn from(value: Vec<Component>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Component> for Components {
|
||||
fn from(value: Component) -> Self {
|
||||
Self(vec![value])
|
||||
}
|
||||
}
|
||||
|
||||
impl Components {
|
||||
pub fn str_len(&self) -> u16 {
|
||||
let mut len_cnt: u16 = 0;
|
||||
for elem in &self.0 {
|
||||
if let Component::String(s) = elem {
|
||||
len_cnt += s.len() as u16;
|
||||
}
|
||||
}
|
||||
len_cnt
|
||||
}
|
||||
|
||||
pub fn concat_for(self, frame: &Frame) -> String {
|
||||
self.0
|
||||
.into_iter()
|
||||
.map(|component| component.prepare_for(frame))
|
||||
.collect::<String>()
|
||||
}
|
||||
}
|
|
@ -28,10 +28,14 @@ impl Frame {
|
|||
&self,
|
||||
theme: ColorSet,
|
||||
size: FrameSize,
|
||||
width: u16,
|
||||
border: u16,
|
||||
) -> Frame {
|
||||
let (p_width, p_height) = self.size();
|
||||
size.abs_size((p_width - 1, p_height - 1), theme, width)
|
||||
let sub_size = size.abs_size((
|
||||
p_width - self.border * 2,
|
||||
p_height - self.border * 2,
|
||||
));
|
||||
self.child_centered(sub_size, border, theme)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -61,6 +65,8 @@ impl Frame {
|
|||
#[inline(always)]
|
||||
fn write_centered_clear(&self, s: &str) -> String {
|
||||
let width = self.size().0 as usize;
|
||||
let limit = width - self.border as usize * 2;
|
||||
let s = if s.len() > limit { &s[..limit] } else { s };
|
||||
let len = s.len();
|
||||
let base_size = ((width - len) / 2) - self.border as usize;
|
||||
format!(
|
||||
|
@ -81,6 +87,8 @@ impl Frame {
|
|||
|
||||
#[inline(always)]
|
||||
fn write_clear_to_end(&self, s: &str) -> String {
|
||||
let limit = (self.size().0 - self.border * 2) as usize;
|
||||
let s = if s.len() > limit { &s[..limit] } else { s };
|
||||
let clear_length = self.size().0 as usize
|
||||
- s.len()
|
||||
- (self.border * 2) as usize;
|
||||
|
@ -115,6 +123,10 @@ impl Frame {
|
|||
|
||||
#[inline(always)]
|
||||
pub fn size(&self) -> (u16, u16) {
|
||||
eprintln!(
|
||||
"end.0: {}, start.0: {}, end.1: {}, start.1: {}",
|
||||
self.end.0, self.start.0, self.end.1, self.start.1
|
||||
);
|
||||
(self.end.0 - self.start.0, self.end.1 - self.start.1)
|
||||
}
|
||||
|
||||
|
@ -124,24 +136,71 @@ impl Frame {
|
|||
width: u16,
|
||||
) -> Result<Self, anyhow::Error> {
|
||||
let term = termion::terminal_size()?;
|
||||
// Swap term dimensions to use x/y
|
||||
// let term = (term.1, term.0);
|
||||
Ok(Self::from_bottom_right(term, term, width, theme))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn child_centered(
|
||||
&self,
|
||||
(pos_w, pos_h): (u16, u16),
|
||||
border: u16,
|
||||
theme: ColorSet,
|
||||
) -> Frame {
|
||||
let parent_offset = self.border / 2;
|
||||
let (parent_w, parent_h) = self.size();
|
||||
let (parent_w, parent_h) =
|
||||
(parent_w - self.border, parent_h - self.border);
|
||||
let start = (
|
||||
1.max(
|
||||
(parent_w - pos_w) / 2
|
||||
+ ((parent_w - pos_w) % 2)
|
||||
+ parent_offset,
|
||||
),
|
||||
1.max(
|
||||
(parent_h - pos_h) / 2
|
||||
+ ((parent_h - pos_h) % 2)
|
||||
+ parent_offset,
|
||||
),
|
||||
);
|
||||
let frame = Self {
|
||||
end: (start.0 + pos_w, start.1 + pos_h),
|
||||
start,
|
||||
border,
|
||||
theme,
|
||||
};
|
||||
frame
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn from_bottom_right(
|
||||
(pos_w, pos_h): (u16, u16),
|
||||
(term_w, term_h): (u16, u16),
|
||||
width: u16,
|
||||
border: u16,
|
||||
theme: ColorSet,
|
||||
) -> Self {
|
||||
Self {
|
||||
start: (1.max(term_w - pos_w), 1.max(term_h - pos_h)),
|
||||
end: (pos_w, pos_h),
|
||||
border: width,
|
||||
let start = (1.max(term_w - pos_w), 1.max(term_h - pos_h));
|
||||
let frame = Self {
|
||||
end: (start.0 + pos_w, start.1 + pos_h),
|
||||
start,
|
||||
border,
|
||||
theme,
|
||||
};
|
||||
if frame.start.0 > frame.end.0 || frame.start.1 > frame.end.1
|
||||
{
|
||||
eprintln!(
|
||||
"pos_w {}, pos_h {}, term_w {}, term_h {}, border {}",
|
||||
pos_w, pos_h, term_w, term_h, border
|
||||
);
|
||||
panic!(
|
||||
"start.0: {} end.0: {}, start.1: {}, end.1: {}",
|
||||
frame.start.0,
|
||||
frame.end.0,
|
||||
frame.start.1,
|
||||
frame.end.1
|
||||
);
|
||||
}
|
||||
|
||||
frame
|
||||
}
|
||||
|
||||
pub fn frame_str(&self, body_theme: String) -> String {
|
||||
|
@ -188,14 +247,12 @@ impl FrameSize {
|
|||
fn abs_size(
|
||||
&self,
|
||||
(term_width, term_height): (u16, u16),
|
||||
theme: ColorSet,
|
||||
width: u16,
|
||||
) -> Frame {
|
||||
let pos = match self {
|
||||
FrameSize::ByAbsolute(h, w) => {
|
||||
) -> (u16, u16) {
|
||||
match self {
|
||||
FrameSize::ByAbsolute(w, h) => {
|
||||
((*w).min(term_width), (*h).min(term_height))
|
||||
}
|
||||
FrameSize::ByPercent(h, w) => {
|
||||
FrameSize::ByPercent(w, h) => {
|
||||
// term_height = 100%
|
||||
// x = h%
|
||||
//
|
||||
|
@ -205,12 +262,6 @@ impl FrameSize {
|
|||
term_height * (*h).min(100) / 100,
|
||||
)
|
||||
}
|
||||
};
|
||||
Frame::from_bottom_right(
|
||||
pos,
|
||||
(term_width, term_height),
|
||||
width,
|
||||
theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ use self::frame::Frame;
|
|||
use self::theme::{Color, Theme};
|
||||
|
||||
pub mod body;
|
||||
pub mod compose;
|
||||
pub mod frame;
|
||||
pub mod theme;
|
||||
type Result<T> = std::result::Result<T, anyhow::Error>;
|
||||
|
@ -54,11 +55,7 @@ impl Display for Event {
|
|||
) -> std::fmt::Result {
|
||||
match self {
|
||||
Event::Key(key) => {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
format!("{:#?}", key)
|
||||
)
|
||||
write!(f, "{}", format!("{:#?}", key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +164,7 @@ impl Screen {
|
|||
clear = clear::All,
|
||||
show_cursor = cursor::Show,
|
||||
)?;
|
||||
scr.flush();
|
||||
scr.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ impl ToString for ColorSet {
|
|||
pub struct Colors {
|
||||
pub primary: ColorSet,
|
||||
pub frame: ColorSet,
|
||||
pub subframe: ColorSet,
|
||||
pub subwin: ColorSet,
|
||||
pub highlight: ColorSet,
|
||||
}
|
||||
impl Theme {}
|
||||
|
||||
|
@ -86,7 +88,18 @@ impl Default for Theme {
|
|||
fg: "#ffe6ff".into(),
|
||||
bg: "#330033".into(),
|
||||
},
|
||||
subwin: ColorSet{ fg: "#ffe6ff".into(), bg: "#110011".into() },
|
||||
subframe: ColorSet{
|
||||
fg: "#ffe6ff".into(),
|
||||
bg: "#110011".into()
|
||||
},
|
||||
highlight: ColorSet{
|
||||
fg: "#ffffff".into(),
|
||||
bg: "#0000ff".into()
|
||||
},
|
||||
subwin: ColorSet{
|
||||
fg: "#ffffff".into(),
|
||||
bg: "#000000".into(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue