More better
This commit is contained in:
@@ -4,9 +4,9 @@ use crate::{
|
||||
buffer::BufferView,
|
||||
color::Color,
|
||||
draw::{draw_bar, draw_box},
|
||||
event::{Event, PointerButton},
|
||||
fonts::FontMap,
|
||||
widgets::{Geometry, Widget},
|
||||
event::{Event, PointerButton},
|
||||
};
|
||||
|
||||
pub trait BarWidgetImpl {
|
||||
@@ -27,7 +27,12 @@ pub struct BarWidget {
|
||||
}
|
||||
|
||||
impl BarWidget {
|
||||
pub fn new(inner_widget: Box<dyn BarWidgetImpl>, fm: &mut FontMap, font: &'static str, size: f32) -> BarWidget {
|
||||
pub fn new(
|
||||
inner_widget: Box<dyn BarWidgetImpl>,
|
||||
fm: &mut FontMap,
|
||||
font: &'static str,
|
||||
size: f32,
|
||||
) -> BarWidget {
|
||||
fm.queue_font(font, size, inner_widget.name());
|
||||
BarWidget {
|
||||
geometry: Default::default(),
|
||||
@@ -51,8 +56,7 @@ impl Widget for BarWidget {
|
||||
let font = fonts.get_font(self.font, self.size);
|
||||
let fg = Color::WHITE;
|
||||
|
||||
font.draw_text(view, fg, self.inner_widget.name())
|
||||
.unwrap();
|
||||
font.draw_text(view, fg, self.inner_widget.name()).unwrap();
|
||||
let size = self.size.ceil() as u32;
|
||||
let bar_offset = 4 * size;
|
||||
let val = self.inner_widget.value();
|
||||
@@ -91,6 +95,15 @@ impl Widget for BarWidget {
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, _fonts: &mut FontMap) -> Geometry {
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: self.size.ceil() as u32 * 6,
|
||||
height: self.size.ceil() as u32,
|
||||
}
|
||||
}
|
||||
|
||||
fn event(&mut self, event: &Event) {
|
||||
match event {
|
||||
Event::PointerEvent(ev) => {
|
||||
@@ -99,9 +112,8 @@ impl Widget for BarWidget {
|
||||
let val = (ev.pos.0 - offset) as f32 / (self.geometry.width - offset) as f32;
|
||||
self.inner_widget.click(val, ev.button);
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
-25
@@ -11,18 +11,33 @@ use dbus::blocking::{
|
||||
|
||||
use crate::{
|
||||
color::Color,
|
||||
fonts::FontMap,
|
||||
event::{Event, Events},
|
||||
fonts::FontMap,
|
||||
widgets::bar_widget::{BarWidget, BarWidgetImpl},
|
||||
};
|
||||
|
||||
enum UpowerBatteryState {
|
||||
Unknown,
|
||||
Charging,
|
||||
Discharging,
|
||||
Empty,
|
||||
Full,
|
||||
NotCharging,
|
||||
Unknown,
|
||||
FullyCharged,
|
||||
PendingCharge,
|
||||
PendingDischarge,
|
||||
}
|
||||
|
||||
impl UpowerBatteryState {
|
||||
fn from_dbus(val: u64) -> UpowerBatteryState {
|
||||
match val {
|
||||
1 => UpowerBatteryState::Charging,
|
||||
2 => UpowerBatteryState::Discharging,
|
||||
3 => UpowerBatteryState::Empty,
|
||||
4 => UpowerBatteryState::FullyCharged,
|
||||
5 => UpowerBatteryState::PendingCharge,
|
||||
6 => UpowerBatteryState::PendingDischarge,
|
||||
_ => UpowerBatteryState::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InnerBattery {
|
||||
@@ -53,15 +68,7 @@ fn start_monitor(inner: Arc<Mutex<InnerBattery>>, events: Arc<Mutex<Events>>) {
|
||||
{
|
||||
let mut inner = inner.lock().unwrap();
|
||||
inner.value = capacity as f32 / 100.;
|
||||
inner.state = match state {
|
||||
1 => UpowerBatteryState::Charging,
|
||||
2 => UpowerBatteryState::Discharging,
|
||||
3 => UpowerBatteryState::Empty,
|
||||
4 => UpowerBatteryState::Full,
|
||||
5 => UpowerBatteryState::NotCharging,
|
||||
6 => UpowerBatteryState::Discharging,
|
||||
_ => UpowerBatteryState::Unknown,
|
||||
}
|
||||
inner.state = UpowerBatteryState::from_dbus(state as u64);
|
||||
}
|
||||
|
||||
proxy
|
||||
@@ -76,15 +83,8 @@ fn start_monitor(inner: Arc<Mutex<InnerBattery>>, events: Arc<Mutex<Events>>) {
|
||||
for (key, value) in c.changed_properties {
|
||||
match key.as_str() {
|
||||
"State" => {
|
||||
inner.state = match value.0.as_u64().unwrap() {
|
||||
1 => UpowerBatteryState::Charging,
|
||||
2 => UpowerBatteryState::Discharging,
|
||||
3 => UpowerBatteryState::Empty,
|
||||
4 => UpowerBatteryState::Full,
|
||||
5 => UpowerBatteryState::NotCharging,
|
||||
6 => UpowerBatteryState::Discharging,
|
||||
_ => UpowerBatteryState::Unknown,
|
||||
};
|
||||
inner.state =
|
||||
UpowerBatteryState::from_dbus(value.0.as_u64().unwrap());
|
||||
inner.dirty = true;
|
||||
let mut events = events.lock().unwrap();
|
||||
events.add_event(Event::PowerUpdate);
|
||||
@@ -115,7 +115,12 @@ pub struct Battery {
|
||||
}
|
||||
|
||||
impl Battery {
|
||||
pub fn new(events: Arc<Mutex<Events>>, fm: &mut FontMap, font: &'static str, size: f32) -> BarWidget {
|
||||
pub fn new(
|
||||
events: Arc<Mutex<Events>>,
|
||||
fm: &mut FontMap,
|
||||
font: &'static str,
|
||||
size: f32,
|
||||
) -> BarWidget {
|
||||
let battery = Battery {
|
||||
inner: Arc::new(Mutex::new(InnerBattery {
|
||||
value: 0.,
|
||||
@@ -143,8 +148,7 @@ impl BarWidgetImpl for Battery {
|
||||
fn color(&self) -> Color {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
match inner.state {
|
||||
UpowerBatteryState::Charging | UpowerBatteryState::Full => Color::LIGHTGREEN,
|
||||
UpowerBatteryState::NotCharging => Color::LIGHTRED,
|
||||
UpowerBatteryState::Charging | UpowerBatteryState::FullyCharged => Color::LIGHTGREEN,
|
||||
_ if inner.value > 0.25 => Color::WHITE,
|
||||
_ if inner.value > 0.1 => Color::DARKORANGE,
|
||||
_ => Color::RED,
|
||||
|
||||
+163
-108
@@ -3,8 +3,8 @@ use std::default::Default;
|
||||
use crate::{
|
||||
buffer::BufferView,
|
||||
color::Color,
|
||||
fonts::FontMap,
|
||||
event::Event,
|
||||
fonts::FontMap,
|
||||
widgets::{Geometry, Widget},
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ use chrono::{Datelike, Local, NaiveDate};
|
||||
|
||||
pub struct Calendar {
|
||||
font: &'static str,
|
||||
month_font: &'static str,
|
||||
sections_x: i32,
|
||||
sections_y: i32,
|
||||
shown_sections_x: u32,
|
||||
@@ -19,22 +20,35 @@ pub struct Calendar {
|
||||
size: f32,
|
||||
dirty: bool,
|
||||
geometry: Geometry,
|
||||
year_width: u32,
|
||||
date_width: u32,
|
||||
day_width: u32,
|
||||
}
|
||||
|
||||
const DAY_FACTOR: f32 = 1.;
|
||||
const YEAR_FACTOR: f32 = 1.5;
|
||||
const MONTH_FACTOR: f32 = 2.;
|
||||
const DATE_FACTOR: f32 = 2.;
|
||||
const LINE_HEIGHT: f32 = 1.8;
|
||||
const DAY_FACTOR: f32 = 0.6;
|
||||
const YEAR_FACTOR: f32 = 0.75;
|
||||
const MONTH_FACTOR: f32 = 1.25;
|
||||
const DATE_FACTOR: f32 = 1.;
|
||||
|
||||
const LINE_HEIGHT: f32 = 0.85;
|
||||
|
||||
impl Calendar {
|
||||
pub fn new(fm: &mut FontMap, font: &'static str, size: f32, sections_x: i32, sections_y: i32) -> Calendar {
|
||||
fm.queue_font(font, size, "ADEFHIMNORSTUW");
|
||||
fm.queue_font(font, size * 1.5, "0123456789");
|
||||
fm.queue_font(font, size * 2.0, "0123456789 ADFJMOSabcehgilmnoprstuvy");
|
||||
pub fn new(
|
||||
fm: &mut FontMap,
|
||||
font: &'static str,
|
||||
month_font: &'static str,
|
||||
size: f32,
|
||||
sections_x: i32,
|
||||
sections_y: i32,
|
||||
) -> Calendar {
|
||||
fm.queue_font(font, size * DAY_FACTOR, "ADEFHIMNORSTUW");
|
||||
fm.queue_font(font, size * YEAR_FACTOR, "0123456789");
|
||||
fm.queue_font(font, size * DATE_FACTOR, "0123456789");
|
||||
fm.queue_font(month_font, size * MONTH_FACTOR, "ADFJMOSabcehgilmnoprstuvy");
|
||||
|
||||
Calendar {
|
||||
font,
|
||||
month_font,
|
||||
size,
|
||||
sections_x,
|
||||
sections_y,
|
||||
@@ -42,6 +56,9 @@ impl Calendar {
|
||||
shown_sections_y: 0,
|
||||
dirty: true,
|
||||
geometry: Default::default(),
|
||||
date_width: 0,
|
||||
day_width: 0,
|
||||
year_width: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,39 +69,33 @@ impl Calendar {
|
||||
orig: NaiveDate,
|
||||
mut time: NaiveDate,
|
||||
) {
|
||||
let white = Color::WHITE;
|
||||
let dim = Color::GREY80;
|
||||
let dimmer = Color::GREY75;
|
||||
|
||||
let mut y_off = 1;
|
||||
// TODO: Fix offsets:
|
||||
// - Headline font is not correctly accounted for
|
||||
|
||||
let cal_width = 8 * self.date_width + 7 * (self.date_width / 2);
|
||||
//
|
||||
// Draw the week day
|
||||
//
|
||||
let day_offset = (self.date_width - self.day_width) / 2;
|
||||
let date_offset = self.date_width + self.date_width / 2;
|
||||
for idx in 1..8 {
|
||||
let day_font = fonts.get_font(self.font, self.size * DAY_FACTOR);
|
||||
let wk_chr = match idx {
|
||||
1 => "MON",
|
||||
2 => "TUE",
|
||||
3 => "WED",
|
||||
4 => "THU",
|
||||
5 => "FRI",
|
||||
6 => "SAT",
|
||||
7 => "SUN",
|
||||
let (wk_chr, c) = match idx {
|
||||
1 => ("MON", Color::WHITE),
|
||||
2 => ("TUE", Color::WHITE),
|
||||
3 => ("WED", Color::WHITE),
|
||||
4 => ("THU", Color::WHITE),
|
||||
5 => ("FRI", Color::WHITE),
|
||||
6 => ("SAT", Color::GREY80),
|
||||
7 => ("SUN", Color::GREY80),
|
||||
_ => panic!("impossible value"),
|
||||
};
|
||||
|
||||
day_font
|
||||
.draw_text(
|
||||
&mut view
|
||||
.offset((
|
||||
idx * (self.size * 2.5).ceil() as u32 + (self.size / 5.).ceil() as u32,
|
||||
y_off * (self.size * LINE_HEIGHT).ceil() as u32
|
||||
+ (self.size * 1.).ceil() as u32,
|
||||
)),
|
||||
white,
|
||||
&mut view.offset((
|
||||
idx * date_offset + day_offset,
|
||||
(self.size * MONTH_FACTOR).ceil() as u32
|
||||
+ (self.size * DAY_FACTOR * 0.2).ceil() as u32,
|
||||
)),
|
||||
c,
|
||||
&wk_chr,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -93,18 +104,7 @@ impl Calendar {
|
||||
//
|
||||
// Draw the month
|
||||
//
|
||||
if time.year() != orig.year() {
|
||||
let year_font = fonts.get_font(self.font, self.size * YEAR_FACTOR);
|
||||
year_font
|
||||
.draw_text(
|
||||
&mut view.offset(((self.size * 17.).ceil() as u32, 0)),
|
||||
dim,
|
||||
&format!("{:}", time.year()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let cal_font = fonts.get_font(self.font, self.size * DATE_FACTOR);
|
||||
let month_font = fonts.get_font(self.month_font, self.size * MONTH_FACTOR);
|
||||
let month_str = match time.month() {
|
||||
1 => "January",
|
||||
2 => "February",
|
||||
@@ -120,59 +120,62 @@ impl Calendar {
|
||||
12 => "December",
|
||||
_ => panic!("impossible value"),
|
||||
};
|
||||
cal_font
|
||||
.draw_text(&mut view, white, month_str)
|
||||
month_font
|
||||
.draw_text(&mut view, Color::WHITE, month_str)
|
||||
.unwrap();
|
||||
|
||||
let mut done = false;
|
||||
while !done {
|
||||
let mut x_pos = 0;
|
||||
|
||||
//
|
||||
// Find the start of this week
|
||||
//
|
||||
let mut wkday = time.weekday();
|
||||
while wkday != chrono::Weekday::Mon {
|
||||
x_pos += 1;
|
||||
wkday = wkday.pred();
|
||||
}
|
||||
//
|
||||
// Draw the year
|
||||
//
|
||||
if time.year() != orig.year() {
|
||||
let year_font = fonts.get_font(self.font, self.size * YEAR_FACTOR);
|
||||
year_font
|
||||
.draw_text(
|
||||
&mut view.offset((cal_width - self.year_width, 0)),
|
||||
Color::GREY80,
|
||||
&format!("{:}", time.year()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let cal_font = fonts.get_font(self.font, self.size * DATE_FACTOR);
|
||||
'row: for y_off in 1.. {
|
||||
//
|
||||
// Draw the week number
|
||||
//
|
||||
let wk = time.iso_week();
|
||||
cal_font
|
||||
.draw_text(
|
||||
&mut view
|
||||
.offset((
|
||||
0,
|
||||
y_off * (self.size * LINE_HEIGHT).ceil() as u32
|
||||
+ (self.size * MONTH_FACTOR).ceil() as u32,
|
||||
)),
|
||||
dimmer,
|
||||
&mut view.offset((
|
||||
0,
|
||||
y_off * (self.size * LINE_HEIGHT).ceil() as u32
|
||||
+ (self.size * MONTH_FACTOR).ceil() as u32,
|
||||
)),
|
||||
Color::GREY75,
|
||||
&format!("{:02}", wk.week()),
|
||||
)
|
||||
.unwrap();
|
||||
x_pos += 1;
|
||||
|
||||
//
|
||||
// Draw the dates
|
||||
//
|
||||
while x_pos < 8 {
|
||||
let x_off = time.weekday().number_from_monday();
|
||||
for x_pos in x_off..8 {
|
||||
let c = if time.day() == orig.day() && time.month() == orig.month() {
|
||||
Color::WHITE
|
||||
} else {
|
||||
} else if x_pos < 6 {
|
||||
Color::GREY50
|
||||
} else {
|
||||
Color::GREY35
|
||||
};
|
||||
|
||||
cal_font
|
||||
.draw_text(
|
||||
&mut view
|
||||
.offset((
|
||||
x_pos * (self.size * 2.5).ceil() as u32,
|
||||
y_off * (self.size * LINE_HEIGHT).ceil() as u32
|
||||
+ (self.size * MONTH_FACTOR).ceil() as u32,
|
||||
)),
|
||||
&mut view.offset((
|
||||
x_pos * date_offset,
|
||||
y_off * (self.size * LINE_HEIGHT).ceil() as u32
|
||||
+ (self.size * MONTH_FACTOR).ceil() as u32,
|
||||
)),
|
||||
c,
|
||||
&format!("{:02}", time.day()),
|
||||
)
|
||||
@@ -180,14 +183,10 @@ impl Calendar {
|
||||
|
||||
let t = time.with_day(time.day() + 1);
|
||||
if t.is_none() {
|
||||
done = true;
|
||||
break;
|
||||
break 'row;
|
||||
}
|
||||
time = t.unwrap();
|
||||
x_pos += 1;
|
||||
}
|
||||
|
||||
y_off += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,9 +221,10 @@ impl<'a> Widget for Calendar {
|
||||
|
||||
let time = Local::now().naive_local().date();
|
||||
|
||||
let cal_height = (self.size * 16.25).ceil() as u32;
|
||||
let cal_width = (7. * self.size * 2.5 + self.size * 2.).ceil() as u32;
|
||||
let cal_pad = (3. * self.size).ceil() as u32;
|
||||
let cal_height =
|
||||
(self.size * MONTH_FACTOR).ceil() as u32 + (self.size * LINE_HEIGHT * 8.).ceil() as u32;
|
||||
let cal_width = 8 * self.date_width + 7 * (self.date_width / 2);
|
||||
let cal_pad = self.date_width * 2;
|
||||
|
||||
let mut t = time.with_day(1).unwrap();
|
||||
let cals = self.shown_sections_y * self.shown_sections_x;
|
||||
@@ -236,8 +236,7 @@ impl<'a> Widget for Calendar {
|
||||
for idx in 0..self.shown_sections_x {
|
||||
self.draw_month(
|
||||
fonts,
|
||||
&mut view
|
||||
.offset(((cal_width + cal_pad) * idx, (cal_height) * ydx)),
|
||||
&mut view.offset(((cal_width + cal_pad) * idx, cal_height * ydx)),
|
||||
time,
|
||||
t,
|
||||
);
|
||||
@@ -252,35 +251,91 @@ impl<'a> Widget for Calendar {
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn geometry_update(&mut self, _fonts: &mut FontMap, geometry: &Geometry) -> Geometry {
|
||||
let cal_width = 7 * (self.size * 2.5).ceil() as u32 + (self.size * 2.).ceil() as u32;
|
||||
let cal_height = (self.size * MONTH_FACTOR).ceil() as u32
|
||||
+ (self.size * LINE_HEIGHT * 8.).ceil() as u32;
|
||||
let cal_pad = (self.size * 3.).ceil() as u32;
|
||||
fn geometry_update(&mut self, fonts: &mut FontMap, geometry: &Geometry) -> Geometry {
|
||||
let year_font = fonts.get_font(self.font, self.size * YEAR_FACTOR);
|
||||
self.year_width = year_font.auto_widest("0123456789").unwrap() * 4;
|
||||
let cal_font = fonts.get_font(self.font, self.size * DATE_FACTOR);
|
||||
self.date_width = cal_font.auto_widest("0123456789").unwrap() * 2;
|
||||
let day_font = fonts.get_font(self.font, self.size * DAY_FACTOR);
|
||||
self.day_width = day_font.auto_widest("ADEFHIMNORSTUW").unwrap() * 3;
|
||||
|
||||
let possible_sections_x = geometry.width / (cal_width + cal_pad);
|
||||
let possible_sections_y = geometry.height / cal_height;
|
||||
let cal_width = 8 * self.date_width + 7 * (self.date_width / 2);
|
||||
let cal_height =
|
||||
(self.size * MONTH_FACTOR).ceil() as u32 + (self.size * LINE_HEIGHT * 8.).ceil() as u32;
|
||||
|
||||
let cal_pad = self.date_width * 2;
|
||||
|
||||
if geometry.width < cal_width || geometry.height < cal_height {
|
||||
self.geometry = Default::default();
|
||||
return self.geometry;
|
||||
}
|
||||
|
||||
let possible_sections_x = 1 + (geometry.width - cal_width) / (cal_width + cal_pad);
|
||||
let possible_sections_y = 1 + (geometry.height - cal_height) / cal_height;
|
||||
|
||||
self.shown_sections_x =
|
||||
if self.sections_x > 0 && self.sections_x < possible_sections_x as i32 {
|
||||
self.sections_x as u32
|
||||
} else {
|
||||
possible_sections_x
|
||||
};
|
||||
self.shown_sections_y =
|
||||
if self.sections_y > 0 && self.sections_y < possible_sections_y as i32 {
|
||||
self.sections_y as u32
|
||||
} else {
|
||||
possible_sections_y
|
||||
};
|
||||
|
||||
let width = if self.sections_x > 0 && self.sections_x < possible_sections_x as i32 {
|
||||
self.shown_sections_x = self.sections_x as u32;
|
||||
cal_width * self.sections_x as u32 + cal_pad * (self.sections_x as u32 - 1)
|
||||
} else {
|
||||
self.shown_sections_x = possible_sections_x;
|
||||
(geometry.width / (cal_width + cal_pad)) * (cal_width + cal_pad)
|
||||
};
|
||||
let height = if self.sections_y > 0 && self.sections_y < possible_sections_y as i32 {
|
||||
self.shown_sections_y = self.sections_y as u32;
|
||||
cal_height * self.sections_y as u32
|
||||
} else {
|
||||
self.shown_sections_y = possible_sections_y;
|
||||
(geometry.height / cal_height) * cal_height
|
||||
};
|
||||
self.geometry = Geometry {
|
||||
x: geometry.x,
|
||||
y: geometry.y,
|
||||
width: width,
|
||||
height: height,
|
||||
width: cal_width * self.shown_sections_x as u32
|
||||
+ cal_pad * (self.shown_sections_x as u32 - 1),
|
||||
height: cal_height * self.shown_sections_y as u32,
|
||||
};
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, fonts: &mut FontMap) -> Geometry {
|
||||
let cal_font = fonts.get_font(self.font, self.size * DATE_FACTOR);
|
||||
let date_width = cal_font.auto_widest("0123456789").unwrap() * 2;
|
||||
|
||||
let cal_width = 8 * date_width + 7 * (date_width / 2);
|
||||
let cal_height =
|
||||
(self.size * MONTH_FACTOR).ceil() as u32 + (self.size * LINE_HEIGHT * 8.).ceil() as u32;
|
||||
let cal_pad = date_width * 2;
|
||||
|
||||
let sections_x = match self.sections_x {
|
||||
-1 => 1,
|
||||
0 => {
|
||||
return Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
}
|
||||
x => x,
|
||||
};
|
||||
let sections_y = match self.sections_y {
|
||||
-1 => 1,
|
||||
0 => {
|
||||
return Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
}
|
||||
y => y,
|
||||
};
|
||||
let width = cal_width * sections_x as u32 + cal_pad * (sections_x as u32 - 1);
|
||||
let height = cal_height * sections_y as u32;
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -3,8 +3,8 @@ use std::default::Default;
|
||||
use crate::{
|
||||
buffer::BufferView,
|
||||
color::Color,
|
||||
fonts::FontMap,
|
||||
event::Event,
|
||||
fonts::FontMap,
|
||||
widgets::{Geometry, Widget},
|
||||
};
|
||||
|
||||
@@ -81,4 +81,16 @@ impl<'a> Widget for Clock {
|
||||
};
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, fonts: &mut FontMap) -> Geometry {
|
||||
let font = fonts.get_font(self.font, self.size);
|
||||
let digit_width = font.auto_widest("0123456789").unwrap();
|
||||
let colon_width = font.auto_widest(":").unwrap();
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: digit_width * 4 + colon_width,
|
||||
height: self.size.ceil() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -3,8 +3,8 @@ use std::default::Default;
|
||||
use crate::{
|
||||
buffer::BufferView,
|
||||
color::Color,
|
||||
fonts::FontMap,
|
||||
event::Event,
|
||||
fonts::FontMap,
|
||||
widgets::{Geometry, Widget},
|
||||
};
|
||||
|
||||
@@ -78,4 +78,15 @@ impl<'a> Widget for Date {
|
||||
};
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, fonts: &mut FontMap) -> Geometry {
|
||||
let width = (3. + 2. + 2. + 2. + 4.) * self.size / 2.;
|
||||
let font = fonts.get_font(self.font, self.size);
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: width.ceil() as u32,
|
||||
height: font.height().ceil() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
-24
@@ -1,10 +1,10 @@
|
||||
use std::{
|
||||
cmp::{max, min, Ordering},
|
||||
collections::HashMap,
|
||||
env,
|
||||
io::Write,
|
||||
fs::{read_to_string, File},
|
||||
default::Default,
|
||||
env,
|
||||
fs::{read_to_string, File},
|
||||
io::Write,
|
||||
process::{exit, Command},
|
||||
sync::{Arc, Mutex},
|
||||
thread,
|
||||
@@ -13,9 +13,9 @@ use std::{
|
||||
use crate::{
|
||||
buffer::BufferView,
|
||||
color::Color,
|
||||
event::{Event, Events, PointerButton, PointerEvent},
|
||||
fonts::FontMap,
|
||||
keyboard::{keysyms, KeyEvent},
|
||||
event::{Event, Events, PointerEvent, PointerButton},
|
||||
utils::desktop::{load_desktop_files, Desktop},
|
||||
widgets::{Geometry, Widget},
|
||||
};
|
||||
@@ -312,8 +312,7 @@ impl InterfaceWidget for Launcher {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
font.auto_draw_text(&mut prompt_line, fg, ">")
|
||||
.unwrap();
|
||||
font.auto_draw_text(&mut prompt_line, fg, ">").unwrap();
|
||||
|
||||
// Draw entries
|
||||
let dimfg = Color::GREY50;
|
||||
@@ -348,8 +347,7 @@ impl InterfaceWidget for Launcher {
|
||||
} else {
|
||||
x_max = max(
|
||||
x_max,
|
||||
font.auto_draw_text(&mut line, dimfg, &m.name)
|
||||
.unwrap(),
|
||||
font.auto_draw_text(&mut line, dimfg, &m.name).unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -452,10 +450,7 @@ impl Calc {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Calc{
|
||||
old,
|
||||
result: None,
|
||||
}
|
||||
Calc { old, result: None }
|
||||
}
|
||||
|
||||
fn sync(&self) {
|
||||
@@ -521,18 +516,18 @@ impl InterfaceWidget for Calc {
|
||||
|
||||
// Draw prompt
|
||||
let font = fonts.get_font(intf.font, intf.size);
|
||||
font
|
||||
.auto_draw_text_with_cursor(
|
||||
&mut prompt_line,
|
||||
fg,
|
||||
&format!(" {} ", &intf.prompt.input),
|
||||
intf.prompt.cursor + 3,
|
||||
)
|
||||
.unwrap();
|
||||
font.auto_draw_text_with_cursor(
|
||||
&mut prompt_line,
|
||||
fg,
|
||||
&format!(" {} ", &intf.prompt.input),
|
||||
intf.prompt.cursor + 3,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
font.auto_draw_text(&mut prompt_line, Color::BUFF, "=")
|
||||
.unwrap();
|
||||
|
||||
prompt_offset -= 16;
|
||||
prompt_offset -= line_height;
|
||||
if let Some(res) = &self.result {
|
||||
let c = if intf.selection == 0 {
|
||||
@@ -555,7 +550,8 @@ impl InterfaceWidget for Calc {
|
||||
};
|
||||
prompt_offset -= line_height;
|
||||
let mut result_line = view.offset((0, prompt_offset));
|
||||
font.auto_draw_text(&mut result_line, c, &format!("{} = {}", input, res)).unwrap();
|
||||
font.auto_draw_text(&mut result_line, c, &format!("{} = {}", input, res))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let content_height = min(
|
||||
@@ -588,9 +584,15 @@ pub struct Interface {
|
||||
}
|
||||
|
||||
impl Interface {
|
||||
pub fn new(events: Arc<Mutex<Events>>, fm: &mut FontMap, font: &'static str, size: f32) -> Interface {
|
||||
pub fn new(
|
||||
events: Arc<Mutex<Events>>,
|
||||
fm: &mut FontMap,
|
||||
font: &'static str,
|
||||
size: f32,
|
||||
) -> Interface {
|
||||
fm.queue_font(
|
||||
font, size,
|
||||
font,
|
||||
size,
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 >=!,.-/()",
|
||||
);
|
||||
|
||||
@@ -708,6 +710,15 @@ impl Widget for Interface {
|
||||
self.inner.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, _fonts: &mut FontMap) -> Geometry {
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 256,
|
||||
height: (self.inner.size.ceil() as u32) * 4 + 16,
|
||||
}
|
||||
}
|
||||
|
||||
fn event(&mut self, event: &Event) {
|
||||
match event {
|
||||
Event::KeyEvent(e) => self.keyboard_input(e),
|
||||
@@ -715,7 +726,7 @@ impl Widget for Interface {
|
||||
Event::LauncherUpdate => {
|
||||
self.inner.dirty = true;
|
||||
self.launcher.update(&self.inner);
|
||||
},
|
||||
}
|
||||
Event::TokenUpdate(t) => self.launcher.next_token = Some(t.to_string()),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
+66
-5
@@ -1,10 +1,6 @@
|
||||
use std::cmp::max;
|
||||
|
||||
use crate::{
|
||||
fonts::FontMap,
|
||||
state::State,
|
||||
widgets::{Geometry},
|
||||
};
|
||||
use crate::{fonts::FontMap, state::State, widgets::Geometry};
|
||||
|
||||
pub trait Layout {
|
||||
fn geometry_update(
|
||||
@@ -13,6 +9,8 @@ pub trait Layout {
|
||||
geometry: &Geometry,
|
||||
state: &mut State,
|
||||
) -> Geometry;
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry;
|
||||
}
|
||||
|
||||
pub struct HorizontalLayout {
|
||||
@@ -46,6 +44,22 @@ impl Layout for HorizontalLayout {
|
||||
geo.height = max_height;
|
||||
geo
|
||||
}
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry {
|
||||
let mut max_width = 0;
|
||||
let mut max_height = 0;
|
||||
for w in self.widgets.iter() {
|
||||
let result = w.minimum_size(fonts, state);
|
||||
max_width += result.x + result.width;
|
||||
max_height = max(result.y + result.height, max_height);
|
||||
}
|
||||
Geometry {
|
||||
width: max_width,
|
||||
height: max_height,
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VerticalLayout {
|
||||
@@ -79,11 +93,28 @@ impl Layout for VerticalLayout {
|
||||
geo.height = max_height;
|
||||
geo
|
||||
}
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry {
|
||||
let mut max_width = 0;
|
||||
let mut max_height = 0;
|
||||
for w in self.widgets.iter() {
|
||||
let result = w.minimum_size(fonts, state);
|
||||
max_width = max(result.x + result.width, max_width);
|
||||
max_height += result.y + result.height;
|
||||
}
|
||||
Geometry {
|
||||
width: max_width,
|
||||
height: max_height,
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WidgetUpdater {
|
||||
fn geometry_update(&mut self, idx: usize, fonts: &mut FontMap, geometry: &Geometry)
|
||||
-> Geometry;
|
||||
fn minimum_size(&mut self, idx: usize, fonts: &mut FontMap) -> Geometry;
|
||||
}
|
||||
|
||||
pub struct IndexedLayout {
|
||||
@@ -105,6 +136,10 @@ impl Layout for IndexedLayout {
|
||||
) -> Geometry {
|
||||
state.geometry_update(self.widget_idx, fonts, geometry)
|
||||
}
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry {
|
||||
state.minimum_size(self.widget_idx, fonts)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Margin {
|
||||
@@ -139,6 +174,16 @@ impl Layout for Margin {
|
||||
height: out.height + self.margin.1 + self.margin.3,
|
||||
}
|
||||
}
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry {
|
||||
let size = self.widget.minimum_size(fonts, state);
|
||||
Geometry {
|
||||
width: size.x + size.width + self.margin.0 + self.margin.2,
|
||||
height: size.y + size.height + self.margin.1 + self.margin.3,
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InvertedHorizontalLayout {
|
||||
@@ -171,4 +216,20 @@ impl Layout for InvertedHorizontalLayout {
|
||||
geo.height = max_height;
|
||||
geo
|
||||
}
|
||||
|
||||
fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry {
|
||||
let mut max_width = 0;
|
||||
let mut max_height = 0;
|
||||
for w in self.widgets.iter() {
|
||||
let result = w.minimum_size(fonts, state);
|
||||
max_width += result.x + result.width;
|
||||
max_height = max(result.y + result.height, max_height);
|
||||
}
|
||||
Geometry {
|
||||
width: max_width,
|
||||
height: max_height,
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -14,7 +14,7 @@ pub struct Line {
|
||||
|
||||
impl Line {
|
||||
pub fn new(thickness: u32) -> Line {
|
||||
Line{
|
||||
Line {
|
||||
geometry: Default::default(),
|
||||
thickness,
|
||||
}
|
||||
@@ -25,10 +25,12 @@ impl Widget for Line {
|
||||
fn geometry(&self) -> Geometry {
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn draw(&mut self, _fonts: &mut FontMap, view: &mut BufferView) -> Geometry {
|
||||
view.memset(Color::WHITE);
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn geometry_update(&mut self, _fonts: &mut FontMap, geometry: &Geometry) -> Geometry {
|
||||
self.geometry = Geometry {
|
||||
x: geometry.x,
|
||||
@@ -38,4 +40,13 @@ impl Widget for Line {
|
||||
};
|
||||
self.geometry
|
||||
}
|
||||
|
||||
fn minimum_size(&mut self, _fonts: &mut FontMap) -> Geometry {
|
||||
Geometry {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: self.thickness,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -1,5 +1,4 @@
|
||||
//mod alsaaudio;
|
||||
mod pulseaudio;
|
||||
mod backlight;
|
||||
mod bar_widget;
|
||||
mod battery;
|
||||
@@ -7,18 +6,22 @@ mod calendar;
|
||||
mod clock;
|
||||
mod date;
|
||||
mod launcher;
|
||||
mod line;
|
||||
mod widget;
|
||||
mod layout;
|
||||
mod line;
|
||||
mod pulseaudio;
|
||||
mod widget;
|
||||
|
||||
//pub use alsaaudio::AlsaAudio;
|
||||
pub use pulseaudio::PulseAudio;
|
||||
pub use backlight::Backlight;
|
||||
pub use battery::Battery;
|
||||
pub use calendar::Calendar;
|
||||
pub use clock::Clock;
|
||||
pub use date::Date;
|
||||
pub use launcher::Interface;
|
||||
pub use layout::{
|
||||
HorizontalLayout, IndexedLayout, InvertedHorizontalLayout, Layout, Margin, VerticalLayout,
|
||||
WidgetUpdater,
|
||||
};
|
||||
pub use line::Line;
|
||||
pub use layout::{VerticalLayout, HorizontalLayout, IndexedLayout, InvertedHorizontalLayout, Layout, Margin, WidgetUpdater};
|
||||
pub use pulseaudio::PulseAudio;
|
||||
pub use widget::{Geometry, Widget};
|
||||
|
||||
+90
-87
@@ -1,16 +1,13 @@
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
error::Error,
|
||||
os::fd::RawFd,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
thread,
|
||||
error::Error,
|
||||
rc::Rc,
|
||||
cell::RefCell,
|
||||
os::fd::RawFd,
|
||||
};
|
||||
|
||||
use nix::unistd::{
|
||||
pipe, write, read,
|
||||
};
|
||||
use nix::unistd::{pipe, read, write};
|
||||
|
||||
use crate::{
|
||||
color::Color,
|
||||
@@ -21,22 +18,19 @@ use crate::{
|
||||
|
||||
use libpulse_binding::volume::ChannelVolumes;
|
||||
|
||||
fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawFd) -> Result<(), Box<dyn Error>> {
|
||||
fn monitor(
|
||||
events: Arc<Mutex<Events>>,
|
||||
inner: Arc<Mutex<InnerAudio>>,
|
||||
pipe: RawFd,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
use libpulse_binding::{
|
||||
mainloop::{
|
||||
self,
|
||||
standard::{
|
||||
IterateResult,
|
||||
},
|
||||
api::Mainloop,
|
||||
events::io::FlagSet as IoFlagSet,
|
||||
},
|
||||
callbacks::ListResult,
|
||||
context::{
|
||||
Context,
|
||||
FlagSet,
|
||||
subscribe::{InterestMaskSet, Facility},
|
||||
State,
|
||||
subscribe::{Facility, InterestMaskSet},
|
||||
Context, FlagSet, State,
|
||||
},
|
||||
mainloop::{
|
||||
self, api::Mainloop, events::io::FlagSet as IoFlagSet, standard::IterateResult,
|
||||
},
|
||||
proplist::{properties, Proplist},
|
||||
volume::Volume,
|
||||
@@ -48,7 +42,9 @@ fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawF
|
||||
.unwrap();
|
||||
|
||||
let mut mainloop = mainloop::standard::Mainloop::new().unwrap();
|
||||
let context = Rc::new(RefCell::new(Context::new_with_proplist(&mainloop, "wldash_context", &proplist).unwrap()));
|
||||
let context = Rc::new(RefCell::new(
|
||||
Context::new_with_proplist(&mainloop, "wldash_context", &proplist).unwrap(),
|
||||
));
|
||||
context.borrow_mut().connect(None, FlagSet::NOFLAGS, None)?;
|
||||
|
||||
loop {
|
||||
@@ -63,33 +59,31 @@ fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawF
|
||||
let local_context = context.clone();
|
||||
let local_inner = inner.clone();
|
||||
let local_events = events.clone();
|
||||
context
|
||||
.borrow_mut()
|
||||
.set_subscribe_callback(Some(Box::new(move |facility, _operation, index| {
|
||||
match facility {
|
||||
Some(Facility::Sink) => {
|
||||
let introspector = local_context.borrow_mut().introspect();
|
||||
let inner = local_inner.clone();
|
||||
let events = local_events.clone();
|
||||
introspector.get_sink_info_by_index(index, move |res| {
|
||||
match res {
|
||||
ListResult::End | ListResult::Error => (),
|
||||
ListResult::Item(sink_info) => if let Some(_) = &sink_info.name {
|
||||
let avg = sink_info.volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
|
||||
let mut inner = inner.lock().unwrap();
|
||||
inner.volume = avg;
|
||||
inner.mute = sink_info.mute;
|
||||
inner.dirty = true;
|
||||
drop(inner);
|
||||
let mut events = events.lock().unwrap();
|
||||
events.add_event(Event::AudioUpdate);
|
||||
},
|
||||
context.borrow_mut().set_subscribe_callback(Some(Box::new(
|
||||
move |facility, _operation, index| match facility {
|
||||
Some(Facility::Sink) => {
|
||||
let introspector = local_context.borrow_mut().introspect();
|
||||
let inner = local_inner.clone();
|
||||
let events = local_events.clone();
|
||||
introspector.get_sink_info_by_index(index, move |res| match res {
|
||||
ListResult::End | ListResult::Error => (),
|
||||
ListResult::Item(sink_info) => {
|
||||
if let Some(_) = &sink_info.name {
|
||||
let avg = sink_info.volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
|
||||
let mut inner = inner.lock().unwrap();
|
||||
inner.volume = avg;
|
||||
inner.mute = sink_info.mute;
|
||||
inner.dirty = true;
|
||||
drop(inner);
|
||||
let mut events = events.lock().unwrap();
|
||||
events.add_event(Event::AudioUpdate);
|
||||
}
|
||||
});
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
})));
|
||||
_ => (),
|
||||
},
|
||||
)));
|
||||
|
||||
context
|
||||
.borrow_mut()
|
||||
@@ -97,10 +91,10 @@ fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawF
|
||||
|
||||
let introspector = context.borrow_mut().introspect();
|
||||
let local_inner = inner.clone();
|
||||
introspector.get_sink_info_by_name("@DEFAULT_SINK@", move |res| {
|
||||
match res {
|
||||
ListResult::End | ListResult::Error => (),
|
||||
ListResult::Item(sink_info) => if let Some(_) = &sink_info.name {
|
||||
introspector.get_sink_info_by_name("@DEFAULT_SINK@", move |res| match res {
|
||||
ListResult::End | ListResult::Error => (),
|
||||
ListResult::Item(sink_info) => {
|
||||
if let Some(_) = &sink_info.name {
|
||||
let avg = sink_info.volume.avg().0 as f32 / Volume::NORMAL.0 as f32;
|
||||
let mut inner = local_inner.lock().unwrap();
|
||||
inner.volume = avg;
|
||||
@@ -110,46 +104,50 @@ fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawF
|
||||
drop(inner);
|
||||
let mut events = events.lock().unwrap();
|
||||
events.add_event(Event::AudioUpdate);
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
drop(introspector);
|
||||
|
||||
let local_context = context.clone();
|
||||
let local_inner = inner.clone();
|
||||
let event_source = mainloop.new_io_event(pipe as i32, IoFlagSet::INPUT, Box::new(move |_, _, _| {
|
||||
let mut buf = [0; 8];
|
||||
_ = read(pipe, &mut buf);
|
||||
let event_source = mainloop.new_io_event(
|
||||
pipe as i32,
|
||||
IoFlagSet::INPUT,
|
||||
Box::new(move |_, _, _| {
|
||||
let mut buf = [0; 8];
|
||||
_ = read(pipe, &mut buf);
|
||||
|
||||
let mut inner = local_inner.lock().unwrap();
|
||||
let mut introspector = local_context.borrow_mut().introspect();
|
||||
match inner.last_click.take() {
|
||||
Some(Change::Volume(volume)) => {
|
||||
// do something
|
||||
let mut vol = inner.channel_volume.unwrap();
|
||||
vol.scale(Volume((volume * Volume::NORMAL.0 as f32).round() as u32));
|
||||
introspector.set_sink_volume_by_name("@DEFAULT_SINK@", &vol, None);
|
||||
},
|
||||
Some(Change::VolumeInc(value)) => {
|
||||
let mut vol = inner.channel_volume.unwrap();
|
||||
// apply step to volumes
|
||||
let step = (value * Volume::NORMAL.0 as f32).round() as i32;
|
||||
if step > 0 {
|
||||
vol.inc_clamp(Volume(step as u32), Volume::NORMAL);
|
||||
} else {
|
||||
vol.decrease(Volume(-step as u32));
|
||||
let mut inner = local_inner.lock().unwrap();
|
||||
let mut introspector = local_context.borrow_mut().introspect();
|
||||
match inner.last_click.take() {
|
||||
Some(Change::Volume(volume)) => {
|
||||
// do something
|
||||
let mut vol = inner.channel_volume.unwrap();
|
||||
vol.scale(Volume((volume * Volume::NORMAL.0 as f32).round() as u32));
|
||||
introspector.set_sink_volume_by_name("@DEFAULT_SINK@", &vol, None);
|
||||
}
|
||||
// HACK: It would be better to only update the volume from feedback, but axis
|
||||
// events fire fast and require the last set volume immediately for reference.
|
||||
inner.channel_volume = Some(vol);
|
||||
introspector.set_sink_volume_by_name("@DEFAULT_SINK@", &vol, None);
|
||||
},
|
||||
Some(Change::ToggleMute) => {
|
||||
introspector.set_sink_mute_by_name("@DEFAULT_SINK@", !inner.mute, None);
|
||||
},
|
||||
None => (),
|
||||
}
|
||||
}));
|
||||
Some(Change::VolumeInc(value)) => {
|
||||
let mut vol = inner.channel_volume.unwrap();
|
||||
// apply step to volumes
|
||||
let step = (value * Volume::NORMAL.0 as f32).round() as i32;
|
||||
if step > 0 {
|
||||
vol.inc_clamp(Volume(step as u32), Volume::NORMAL);
|
||||
} else {
|
||||
vol.decrease(Volume(-step as u32));
|
||||
}
|
||||
// HACK: It would be better to only update the volume from feedback, but axis
|
||||
// events fire fast and require the last set volume immediately for reference.
|
||||
inner.channel_volume = Some(vol);
|
||||
introspector.set_sink_volume_by_name("@DEFAULT_SINK@", &vol, None);
|
||||
}
|
||||
Some(Change::ToggleMute) => {
|
||||
introspector.set_sink_mute_by_name("@DEFAULT_SINK@", !inner.mute, None);
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
loop {
|
||||
match mainloop.iterate(true) {
|
||||
@@ -167,7 +165,7 @@ fn monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawF
|
||||
fn start_monitor(events: Arc<Mutex<Events>>, inner: Arc<Mutex<InnerAudio>>, pipe: RawFd) {
|
||||
thread::Builder::new()
|
||||
.name("audiomon".to_string())
|
||||
.spawn(move || { monitor(events, inner, pipe).unwrap() })
|
||||
.spawn(move || monitor(events, inner, pipe).unwrap())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -191,10 +189,15 @@ pub struct PulseAudio {
|
||||
}
|
||||
|
||||
impl PulseAudio {
|
||||
pub fn new(events: Arc<Mutex<Events>>, fm: &mut FontMap, font: &'static str, size: f32) -> BarWidget {
|
||||
pub fn new(
|
||||
events: Arc<Mutex<Events>>,
|
||||
fm: &mut FontMap,
|
||||
font: &'static str,
|
||||
size: f32,
|
||||
) -> BarWidget {
|
||||
let (a, b) = pipe().unwrap();
|
||||
let audio = PulseAudio {
|
||||
inner: Arc::new(Mutex::new(InnerAudio{
|
||||
inner: Arc::new(Mutex::new(InnerAudio {
|
||||
volume: 0.0,
|
||||
channel_volume: None,
|
||||
mute: false,
|
||||
@@ -229,7 +232,7 @@ impl BarWidgetImpl for PulseAudio {
|
||||
fn click(&mut self, pos: f32, btn: PointerButton) {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
inner.last_click = match btn {
|
||||
PointerButton::Left => Some(Change::Volume(pos)),
|
||||
PointerButton::Left => Some(Change::Volume(pos)),
|
||||
PointerButton::Right => Some(Change::ToggleMute),
|
||||
PointerButton::ScrollVertical(val) => Some(Change::VolumeInc((val / 512.) as f32)),
|
||||
PointerButton::ScrollHorizontal(val) => Some(Change::VolumeInc((val / 100.) as f32)),
|
||||
|
||||
@@ -3,11 +3,7 @@ use std::{
|
||||
fmt,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
buffer::BufferView,
|
||||
fonts::FontMap,
|
||||
event::Event,
|
||||
};
|
||||
use crate::{buffer::BufferView, event::Event, fonts::FontMap};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub struct Geometry {
|
||||
@@ -49,8 +45,10 @@ impl Geometry {
|
||||
}
|
||||
|
||||
pub fn contains(&self, position: (u32, u32)) -> bool {
|
||||
position.0 >= self.x && position.0 < self.x + self.width &&
|
||||
position.1 >= self.y && position.1 < self.y + self.height
|
||||
position.0 >= self.x
|
||||
&& position.0 < self.x + self.width
|
||||
&& position.1 >= self.y
|
||||
&& position.1 < self.y + self.height
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +58,9 @@ pub trait Widget {
|
||||
}
|
||||
fn geometry(&self) -> Geometry;
|
||||
fn geometry_update(&mut self, fonts: &mut FontMap, geometry: &Geometry) -> Geometry;
|
||||
fn minimum_size(&mut self, _fonts: &mut FontMap) -> Geometry {
|
||||
Default::default()
|
||||
}
|
||||
fn draw(&mut self, fonts: &mut FontMap, view: &mut BufferView) -> Geometry;
|
||||
fn event(&mut self, _event: &Event) {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user