mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-11-15 16:00:38 +08:00
lib: Introduce label group
This commit is contained in:
@@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user