lib: Introduce label group

This commit is contained in:
Erik Kundt
2024-01-08 16:56:03 +01:00
parent fded6f2ebf
commit fb413954a4
4 changed files with 99 additions and 34 deletions
+1 -1
View File
@@ -135,7 +135,7 @@ pub fn browse_context(context: &Context, theme: &Theme, progress: Progress) -> W
"Patches",
"",
"",
&format!("{draft} draft | {open} open | {archived} archived | {merged} merged"),
&format!("Draft {draft} | Open {open} | Archived {archived} | Merged {merged}"),
&progress.to_string(),
)
}
+15
View File
@@ -19,6 +19,8 @@ use widget::list::{ColumnWidth, Property, PropertyList, PropertyTable};
use widget::Widget;
use self::widget::label::LabelGroup;
use super::context::Context;
use crate::ui::theme::Theme;
@@ -36,6 +38,19 @@ pub fn label(content: &str) -> Widget<Label> {
.width(width)
}
pub fn label_group(labels: &[Widget<Label>]) -> Widget<LabelGroup> {
let group = LabelGroup::new(labels);
let width = labels.iter().fold(0, |total, label| {
total
+ label
.query(Attribute::Width)
.unwrap_or(AttrValue::Size(0))
.unwrap_size()
});
Widget::new(group).width(width)
}
pub fn reversable_label(content: &str) -> Widget<Label> {
let content = &format!(" {content} ");
+41 -33
View File
@@ -3,7 +3,7 @@ use tuirealm::props::{AttrValue, Attribute, Props};
use tuirealm::tui::layout::Rect;
use tuirealm::{Frame, MockComponent, State};
use super::label::Label;
use super::label::{Label, LabelGroup};
use crate::ui::layout;
use crate::ui::theme::Theme;
@@ -123,11 +123,11 @@ impl WidgetComponent for Shortcuts {
}
pub struct ContextBar {
label_0: Widget<Label>,
label_1: Widget<Label>,
label_2: Widget<Label>,
label_3: Widget<Label>,
label_4: Widget<Label>,
col_0: Widget<LabelGroup>,
col_1: Widget<LabelGroup>,
col_2: Widget<LabelGroup>,
col_3: Widget<LabelGroup>,
col_4: Widget<LabelGroup>,
theme: Theme,
}
@@ -136,19 +136,19 @@ impl ContextBar {
pub fn new(
theme: Theme,
label_0: Widget<Label>,
label_1: Widget<Label>,
label_2: Widget<Label>,
label_3: Widget<Label>,
label_4: Widget<Label>,
col_0: Widget<LabelGroup>,
col_1: Widget<LabelGroup>,
col_2: Widget<LabelGroup>,
col_3: Widget<LabelGroup>,
col_4: Widget<LabelGroup>,
) -> Self {
Self {
theme,
label_0,
label_1,
label_2,
label_3,
label_4,
col_0,
col_1,
col_2,
col_3,
col_4,
}
}
}
@@ -165,13 +165,13 @@ impl WidgetComponent for ContextBar {
)
.unwrap_flag();
let label_0_w = self.label_0.query(Attribute::Width).unwrap().unwrap_size();
let label_1_w = self.label_1.query(Attribute::Width).unwrap().unwrap_size();
let label_2_w = self.label_2.query(Attribute::Width).unwrap().unwrap_size();
let label_4_w = self.label_4.query(Attribute::Width).unwrap().unwrap_size();
let col_0_w = self.col_0.query(Attribute::Width).unwrap().unwrap_size();
let col_1_w = self.col_1.query(Attribute::Width).unwrap().unwrap_size();
let col_3_w = self.col_3.query(Attribute::Width).unwrap().unwrap_size();
let col_4_w = self.col_4.query(Attribute::Width).unwrap().unwrap_size();
if edit_mode {
self.label_0.attr(
self.col_0.attr(
Attribute::Background,
AttrValue::Color(self.theme.colors.context_badge_edit_bg),
)
@@ -180,17 +180,17 @@ impl WidgetComponent for ContextBar {
if display {
let layout = layout::h_stack(
vec![
self.label_0.clone().to_boxed(),
self.label_1.clone().to_boxed(),
self.label_3
self.col_0.clone().to_boxed(),
self.col_1.clone().to_boxed(),
self.col_2
.clone()
.width(
area.width
.saturating_sub(label_0_w + label_1_w + label_2_w + label_4_w),
.saturating_sub(col_0_w + col_1_w + col_3_w + col_4_w),
)
.to_boxed(),
self.label_2.clone().to_boxed(),
self.label_4.clone().to_boxed(),
self.col_3.clone().to_boxed(),
self.col_4.clone().to_boxed(),
],
area,
);
@@ -218,23 +218,31 @@ pub fn bar(
label_3: &str,
label_4: &str,
) -> Widget<ContextBar> {
let context = crate::ui::label(&format!(" {label_0} "))
use crate::ui::{label, label_group};
let label_0 = label(&format!(" {label_0} "))
.foreground(theme.colors.context_bg)
.background(theme.colors.context_badge_bg);
let id = crate::ui::label(&format!(" {label_1} "))
let label_1 = label(&format!(" {label_1} "))
.foreground(theme.colors.context_color_fg)
.background(theme.colors.context_bg);
let title = crate::ui::label(&format!(" {label_2} "))
let label_2 = label(&format!(" {label_2} "))
.foreground(theme.colors.default_fg)
.background(theme.colors.context_bg);
let author = crate::ui::label(&format!(" {label_3} "))
let label_3 = label(&format!(" {label_3} "))
.foreground(theme.colors.context_light)
.background(theme.colors.context_bg);
let comments = crate::ui::label(&format!(" {label_4} "))
let label_4 = label(&format!(" {label_4} "))
.foreground(theme.colors.context_light)
.background(theme.colors.context_bg);
let context_bar = ContextBar::new(theme.clone(), context, id, author, title, comments);
let label_0 = label_group(&[label_0]);
let label_1 = label_group(&[label_1]);
let label_2 = label_group(&[label_2]);
let label_3 = label_group(&[label_3]);
let label_4 = label_group(&[label_4]);
let context_bar = ContextBar::new(theme.clone(), label_0, label_1, label_2, label_3, label_4);
Widget::new(context_bar).height(1)
}
+42
View File
@@ -4,6 +4,7 @@ use tuirealm::tui::layout::{Constraint, Direction, Layout, Rect};
use tuirealm::tui::text::{Span, Spans, Text};
use tuirealm::{Frame, MockComponent, State, StateValue};
use crate::ui::layout;
use crate::ui::theme::Theme;
use crate::ui::widget::{Widget, WidgetComponent};
@@ -81,6 +82,47 @@ impl From<&Widget<Label>> for Text<'_> {
}
}
#[derive(Clone, Default)]
pub struct LabelGroup {
labels: Vec<Widget<Label>>,
}
impl LabelGroup {
pub fn new(labels: &[Widget<Label>]) -> Self {
Self {
labels: labels.to_vec(),
}
}
}
impl WidgetComponent for LabelGroup {
fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
let display = properties
.get_or(Attribute::Display, AttrValue::Flag(true))
.unwrap_flag();
if display {
let mut labels: Vec<Box<dyn MockComponent>> = vec![];
for label in &self.labels {
labels.push(label.clone().to_boxed());
}
let layout = layout::h_stack(labels, area);
for (mut label, area) in layout {
label.view(frame, area);
}
}
}
fn state(&self) -> State {
State::None
}
fn perform(&mut self, _properties: &Props, _cmd: Cmd) -> CmdResult {
CmdResult::None
}
}
pub struct Textarea {
/// The current theme.
theme: Theme,