widgets: Allow widgets to fill remaining space
This is implemented by propagating the expected remaining space to all widget draw calls. It is not currently as smart as it could be, but it works well enough to let the last widget in a row/column fill things. BarWidget-type widgets and the Launcher widget now fill remaining space if their length is set to 0.
This commit is contained in:
@@ -272,6 +272,7 @@ impl<'a> App<'a> {
|
|||||||
force,
|
force,
|
||||||
},
|
},
|
||||||
(0, 0),
|
(0, 0),
|
||||||
|
size,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
mmap.flush().unwrap();
|
mmap.flush().unwrap();
|
||||||
|
|||||||
+4
-4
@@ -282,7 +282,7 @@ impl Default for Config {
|
|||||||
widget: Box::new(Widget::Battery {
|
widget: Box::new(Widget::Battery {
|
||||||
font: None,
|
font: None,
|
||||||
font_size: 24.0,
|
font_size: 24.0,
|
||||||
length: 600,
|
length: 0,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Widget::Margin {
|
Widget::Margin {
|
||||||
@@ -291,7 +291,7 @@ impl Default for Config {
|
|||||||
device: "intel_backlight".to_string(),
|
device: "intel_backlight".to_string(),
|
||||||
font: None,
|
font: None,
|
||||||
font_size: 24.0,
|
font_size: 24.0,
|
||||||
length: 600,
|
length: 0,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
#[cfg(feature = "pulseaudio-widget")]
|
#[cfg(feature = "pulseaudio-widget")]
|
||||||
@@ -300,7 +300,7 @@ impl Default for Config {
|
|||||||
widget: Box::new(Widget::PulseAudio {
|
widget: Box::new(Widget::PulseAudio {
|
||||||
font: None,
|
font: None,
|
||||||
font_size: 24.0,
|
font_size: 24.0,
|
||||||
length: 600,
|
length: 0,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
@@ -314,7 +314,7 @@ impl Default for Config {
|
|||||||
Widget::Launcher {
|
Widget::Launcher {
|
||||||
font: None,
|
font: None,
|
||||||
font_size: 32.0,
|
font_size: 32.0,
|
||||||
length: 1200,
|
length: 0,
|
||||||
app_opener: "".to_string(),
|
app_opener: "".to_string(),
|
||||||
term_opener: "".to_string(),
|
term_opener: "".to_string(),
|
||||||
url_opener: "".to_string(),
|
url_opener: "".to_string(),
|
||||||
|
|||||||
+44
-14
@@ -56,6 +56,7 @@ pub trait Widget {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error>;
|
) -> Result<DrawReport, ::std::io::Error>;
|
||||||
|
|
||||||
fn keyboard_input(
|
fn keyboard_input(
|
||||||
@@ -115,16 +116,20 @@ impl<'a> Widget for VerticalLayout<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let mut offset = pos.1;
|
let mut offset = 0;
|
||||||
let mut width = 0;
|
let mut width = 0;
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
let mut full_damage = false;
|
let mut full_damage = false;
|
||||||
|
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
let mut report = child.draw(ctx, (pos.0, offset))?;
|
let mut report = child.draw(
|
||||||
|
ctx,
|
||||||
|
(pos.0, offset + pos.1),
|
||||||
|
(expansion.0, expansion.1 - offset),
|
||||||
|
)?;
|
||||||
if report.width > width {
|
if report.width > width {
|
||||||
width = report.width;
|
width = report.width
|
||||||
}
|
}
|
||||||
offset += report.height;
|
offset += report.height;
|
||||||
full_damage |= report.full_damage;
|
full_damage |= report.full_damage;
|
||||||
@@ -133,7 +138,7 @@ impl<'a> Widget for VerticalLayout<'a> {
|
|||||||
|
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
width,
|
width,
|
||||||
height: offset - pos.1,
|
height: offset,
|
||||||
damage,
|
damage,
|
||||||
full_damage,
|
full_damage,
|
||||||
})
|
})
|
||||||
@@ -189,6 +194,19 @@ impl<'a> HorizontalLayout<'a> {
|
|||||||
pub fn new(children: Vec<Box<dyn Widget + Send + 'a>>) -> Box<HorizontalLayout> {
|
pub fn new(children: Vec<Box<dyn Widget + Send + 'a>>) -> Box<HorizontalLayout> {
|
||||||
Box::new(HorizontalLayout { children })
|
Box::new(HorizontalLayout { children })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn height(&self) -> u32 {
|
||||||
|
let mut height = 0;
|
||||||
|
|
||||||
|
for child in &self.children {
|
||||||
|
let size = child.size();
|
||||||
|
if size.1 > height {
|
||||||
|
height = size.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
height
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for HorizontalLayout<'a> {
|
impl<'a> Widget for HorizontalLayout<'a> {
|
||||||
@@ -226,16 +244,20 @@ impl<'a> Widget for HorizontalLayout<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let mut offset = pos.0;
|
let mut offset = 0;
|
||||||
let mut height = 0;
|
let mut height = 0;
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
let mut full_damage = false;
|
let mut full_damage = false;
|
||||||
|
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
let mut report = child.draw(ctx, (offset, pos.1))?;
|
let mut report = child.draw(
|
||||||
|
ctx,
|
||||||
|
(offset + pos.0, pos.1),
|
||||||
|
(expansion.0 - offset, expansion.1),
|
||||||
|
)?;
|
||||||
if report.height > height {
|
if report.height > height {
|
||||||
height = report.height;
|
height = report.height
|
||||||
}
|
}
|
||||||
offset += report.width;
|
offset += report.width;
|
||||||
full_damage |= report.full_damage;
|
full_damage |= report.full_damage;
|
||||||
@@ -243,7 +265,7 @@ impl<'a> Widget for HorizontalLayout<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
width: offset - pos.0,
|
width: offset,
|
||||||
height,
|
height,
|
||||||
damage,
|
damage,
|
||||||
full_damage,
|
full_damage,
|
||||||
@@ -327,10 +349,17 @@ impl<'a> Widget for Margin<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let report = self
|
let expansion = (
|
||||||
.child
|
expansion.0 - self.margins.0 - self.margins.1,
|
||||||
.draw(ctx, (pos.0 + self.margins.0, pos.1 + self.margins.2))?;
|
expansion.1 - self.margins.2 - self.margins.3,
|
||||||
|
);
|
||||||
|
let report = self.child.draw(
|
||||||
|
ctx,
|
||||||
|
(pos.0 + self.margins.0, pos.1 + self.margins.2),
|
||||||
|
expansion,
|
||||||
|
)?;
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
width: report.width + self.margins.0 + self.margins.1,
|
width: report.width + self.margins.0 + self.margins.1,
|
||||||
height: report.height + self.margins.2 + self.margins.3,
|
height: report.height + self.margins.2 + self.margins.3,
|
||||||
@@ -397,8 +426,9 @@ impl<'a> Widget for Fixed<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let report = self.child.draw(ctx, pos)?;
|
let report = self.child.draw(ctx, pos, expansion)?;
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
width: self.size.0,
|
width: self.size.0,
|
||||||
height: self.size.1,
|
height: self.size.1,
|
||||||
|
|||||||
@@ -83,8 +83,12 @@ impl<'a> Widget for BarWidget<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let (width, height) = self.size();
|
if self.length == 0 {
|
||||||
|
self.length = expansion.0;
|
||||||
|
}
|
||||||
|
let (width, height) = (self.length, self.font_size);
|
||||||
{
|
{
|
||||||
let mut d = self.dirty.lock().unwrap();
|
let mut d = self.dirty.lock().unwrap();
|
||||||
if !*d && !ctx.force {
|
if !*d && !ctx.force {
|
||||||
@@ -105,7 +109,7 @@ impl<'a> Widget for BarWidget<'a> {
|
|||||||
draw_bar(
|
draw_bar(
|
||||||
&mut buf.offset((bar_off, 0))?,
|
&mut buf.offset((bar_off, 0))?,
|
||||||
&c,
|
&c,
|
||||||
self.length - bar_off,
|
width - bar_off,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
val,
|
val,
|
||||||
)?;
|
)?;
|
||||||
@@ -117,7 +121,7 @@ impl<'a> Widget for BarWidget<'a> {
|
|||||||
draw_bar(
|
draw_bar(
|
||||||
&mut buf.offset((bar_off, 0))?,
|
&mut buf.offset((bar_off, 0))?,
|
||||||
&c,
|
&c,
|
||||||
self.length - bar_off,
|
width - bar_off,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
val,
|
val,
|
||||||
)?;
|
)?;
|
||||||
@@ -125,7 +129,7 @@ impl<'a> Widget for BarWidget<'a> {
|
|||||||
draw_box(
|
draw_box(
|
||||||
&mut buf.offset((bar_off, 0))?,
|
&mut buf.offset((bar_off, 0))?,
|
||||||
&c,
|
&c,
|
||||||
(self.length - bar_off, self.font_size),
|
(width - bar_off, self.font_size),
|
||||||
)?;
|
)?;
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
width,
|
width,
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ impl<'a> Widget for Calendar<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
_expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let (width, height) = self.size();
|
let (width, height) = self.size();
|
||||||
if ctx.time.date() == self.cur_date && !ctx.force && !self.dirty {
|
if ctx.time.date() == self.cur_date && !ctx.force && !self.dirty {
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ impl<'a> Widget for Clock<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
_expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let (width, height) = self.size();
|
let (width, height) = self.size();
|
||||||
if !(ctx.time.date() != self.cur_time.date()
|
if !(ctx.time.date() != self.cur_time.date()
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ impl<'a> Widget for Date<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
_expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let (width, height) = self.size();
|
let (width, height) = self.size();
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -60,7 +60,12 @@ impl<'a> Launcher<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_launcher(&self, buf: &mut Buffer, bg: &Color) -> Result<(), ::std::io::Error> {
|
fn draw_launcher(
|
||||||
|
&self,
|
||||||
|
buf: &mut Buffer,
|
||||||
|
bg: &Color,
|
||||||
|
width: u32,
|
||||||
|
) -> Result<(), ::std::io::Error> {
|
||||||
let mut x_off = if !self.input.is_empty() {
|
let mut x_off = if !self.input.is_empty() {
|
||||||
let c = if self.matches.is_empty() {
|
let c = if self.matches.is_empty() {
|
||||||
Color::new(1.0, 0.5, 0.5, 1.0)
|
Color::new(1.0, 0.5, 0.5, 1.0)
|
||||||
@@ -77,7 +82,7 @@ impl<'a> Launcher<'a> {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut width_remaining: i32 = (self.length - x_off) as i32;
|
let mut width_remaining: i32 = (width - x_off) as i32;
|
||||||
for (idx, m) in self.matches.iter().enumerate() {
|
for (idx, m) in self.matches.iter().enumerate() {
|
||||||
let mut b = match buf.offset((x_off, 0)) {
|
let mut b = match buf.offset((x_off, 0)) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
@@ -266,8 +271,12 @@ impl<'a> Widget for Launcher<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut DrawContext,
|
ctx: &mut DrawContext,
|
||||||
pos: (u32, u32),
|
pos: (u32, u32),
|
||||||
|
expansion: (u32, u32),
|
||||||
) -> Result<DrawReport, ::std::io::Error> {
|
) -> Result<DrawReport, ::std::io::Error> {
|
||||||
let (width, height) = self.size();
|
if self.length == 0 {
|
||||||
|
self.length = expansion.0;
|
||||||
|
}
|
||||||
|
let (width, height) = (self.length, self.font_size);
|
||||||
if !self.dirty && !ctx.force {
|
if !self.dirty && !ctx.force {
|
||||||
return Ok(DrawReport::empty(width, height));
|
return Ok(DrawReport::empty(width, height));
|
||||||
}
|
}
|
||||||
@@ -313,7 +322,7 @@ impl<'a> Widget for Launcher<'a> {
|
|||||||
match self.input.chars().next() {
|
match self.input.chars().next() {
|
||||||
Some('=') => self.draw_calc(buf, ctx.bg),
|
Some('=') => self.draw_calc(buf, ctx.bg),
|
||||||
Some('!') => self.draw_shell(buf, ctx.bg),
|
Some('!') => self.draw_shell(buf, ctx.bg),
|
||||||
_ => self.draw_launcher(buf, ctx.bg),
|
_ => self.draw_launcher(buf, ctx.bg, width),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
Ok(DrawReport {
|
Ok(DrawReport {
|
||||||
|
|||||||
Reference in New Issue
Block a user