Simplify PrimitiveValue, add comments for doc-gen
This commit is contained in:
parent
de83f1fb69
commit
c11cfaa26a
7 changed files with 173 additions and 119 deletions
25
src/app.rs
25
src/app.rs
|
@ -33,11 +33,18 @@ pub enum EwwCommand {
|
||||||
PrintState(crossbeam_channel::Sender<String>),
|
PrintState(crossbeam_channel::Sender<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct EwwWindow {
|
||||||
|
pub name: config::WindowName,
|
||||||
|
pub definition: config::EwwWindowDefinition,
|
||||||
|
pub gtk_window: gtk::Window,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(DebugStub)]
|
#[derive(DebugStub)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub eww_state: eww_state::EwwState,
|
pub eww_state: eww_state::EwwState,
|
||||||
pub eww_config: config::EwwConfig,
|
pub eww_config: config::EwwConfig,
|
||||||
pub windows: HashMap<config::WindowName, gtk::Window>,
|
pub windows: HashMap<config::WindowName, EwwWindow>,
|
||||||
pub css_provider: gtk::CssProvider,
|
pub css_provider: gtk::CssProvider,
|
||||||
pub app_evt_send: glib::Sender<EwwCommand>,
|
pub app_evt_send: glib::Sender<EwwCommand>,
|
||||||
#[debug_stub = "ScriptVarHandler(...)"]
|
#[debug_stub = "ScriptVarHandler(...)"]
|
||||||
|
@ -80,7 +87,7 @@ impl App {
|
||||||
.windows
|
.windows
|
||||||
.remove(window_name)
|
.remove(window_name)
|
||||||
.context(format!("No window with name '{}' is running.", window_name))?;
|
.context(format!("No window with name '{}' is running.", window_name))?;
|
||||||
window.close();
|
window.gtk_window.close();
|
||||||
self.eww_state.clear_window_state(window_name);
|
self.eww_state.clear_window_state(window_name);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -146,7 +153,13 @@ impl App {
|
||||||
window.set_keep_below(true);
|
window.set_keep_below(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.windows.insert(window_name.clone(), window);
|
let eww_window = EwwWindow {
|
||||||
|
definition: window_def,
|
||||||
|
gtk_window: window,
|
||||||
|
name: window_name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.windows.insert(window_name.clone(), eww_window);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -163,9 +176,9 @@ impl App {
|
||||||
|
|
||||||
let windows = self.windows.clone();
|
let windows = self.windows.clone();
|
||||||
for (window_name, window) in windows {
|
for (window_name, window) in windows {
|
||||||
let old_pos = window.get_position();
|
let old_pos = window.definition.position;
|
||||||
let old_size = window.get_size();
|
let old_size = window.definition.size;
|
||||||
window.close();
|
window.gtk_window.close();
|
||||||
self.open_window(&window_name, Some(old_pos.into()), Some(old_size.into()))?;
|
self.open_window(&window_name, Some(old_pos.into()), Some(old_size.into()))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl WidgetUse {
|
||||||
XmlNode::Text(text) if PATTERN.is_match(&text.text()) => WidgetUse::from_text_with_var_refs(&text.text()),
|
XmlNode::Text(text) if PATTERN.is_match(&text.text()) => WidgetUse::from_text_with_var_refs(&text.text()),
|
||||||
XmlNode::Text(text) => WidgetUse::simple_text(AttrValue::parse_string(text.text())),
|
XmlNode::Text(text) => WidgetUse::simple_text(AttrValue::parse_string(text.text())),
|
||||||
XmlNode::Element(elem) => WidgetUse {
|
XmlNode::Element(elem) => WidgetUse {
|
||||||
name: elem.tag_name().to_string(),
|
name: elem.tag_name().to_owned(),
|
||||||
children: with_text_pos_context! { elem => elem.children().map(WidgetUse::from_xml_node).collect::<Result<_>>()?}?,
|
children: with_text_pos_context! { elem => elem.children().map(WidgetUse::from_xml_node).collect::<Result<_>>()?}?,
|
||||||
attrs: elem
|
attrs: elem
|
||||||
.attributes()
|
.attributes()
|
||||||
|
@ -98,7 +98,7 @@ impl WidgetUse {
|
||||||
WidgetUse {
|
WidgetUse {
|
||||||
name: "label".to_owned(),
|
name: "label".to_owned(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
attrs: hashmap! { "text".to_string() => text }, // TODO this hardcoded "text" is dumdum
|
attrs: hashmap! { "text".to_owned() => text }, // TODO this hardcoded "text" is dumdum
|
||||||
..WidgetUse::default()
|
..WidgetUse::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ enum StringOrVarRef {
|
||||||
impl StringOrVarRef {
|
impl StringOrVarRef {
|
||||||
fn to_attr_value(self) -> AttrValue {
|
fn to_attr_value(self) -> AttrValue {
|
||||||
match self {
|
match self {
|
||||||
StringOrVarRef::String(x) => AttrValue::Concrete(PrimitiveValue::parse_string(&x)),
|
StringOrVarRef::String(x) => AttrValue::Concrete(PrimitiveValue::from_string(x)),
|
||||||
StringOrVarRef::VarRef(x) => AttrValue::VarRef(VarName(x)),
|
StringOrVarRef::VarRef(x) => AttrValue::VarRef(VarName(x)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,12 +190,12 @@ mod test {
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
fn mk_attr_str(s: &str) -> AttrValue {
|
fn mk_attr_str(s: &str) -> AttrValue {
|
||||||
AttrValue::Concrete(PrimitiveValue::String(s.to_owned()))
|
AttrValue::Concrete(PrimitiveValue::from_string(s.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_text() {
|
fn test_simple_text() {
|
||||||
let expected_attr_value = AttrValue::Concrete(PrimitiveValue::String("my text".to_owned()));
|
let expected_attr_value = AttrValue::Concrete(PrimitiveValue::from_string("my text".to_owned()));
|
||||||
let widget = WidgetUse::simple_text(expected_attr_value.clone());
|
let widget = WidgetUse::simple_text(expected_attr_value.clone());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
widget,
|
widget,
|
||||||
|
@ -244,12 +244,12 @@ mod test {
|
||||||
let expected = WidgetUse {
|
let expected = WidgetUse {
|
||||||
name: "widget_name".to_owned(),
|
name: "widget_name".to_owned(),
|
||||||
attrs: hashmap! {
|
attrs: hashmap! {
|
||||||
"attr1".to_owned() => AttrValue::Concrete(PrimitiveValue::String("hi".to_owned())),
|
"attr1".to_owned() => AttrValue::Concrete(PrimitiveValue::from_string("hi".to_owned())),
|
||||||
"attr2".to_owned() => AttrValue::Concrete(PrimitiveValue::Number(12f64)),
|
"attr2".to_owned() => AttrValue::Concrete(PrimitiveValue::from_string("12".to_owned())),
|
||||||
},
|
},
|
||||||
children: vec![
|
children: vec![
|
||||||
WidgetUse::new("child_widget".to_owned(), Vec::new()),
|
WidgetUse::new("child_widget".to_owned(), Vec::new()),
|
||||||
WidgetUse::simple_text(AttrValue::Concrete(PrimitiveValue::String("foo".to_owned()))),
|
WidgetUse::simple_text(AttrValue::Concrete(PrimitiveValue::from_string("foo".to_owned()))),
|
||||||
],
|
],
|
||||||
..WidgetUse::default()
|
..WidgetUse::default()
|
||||||
};
|
};
|
||||||
|
@ -271,7 +271,7 @@ mod test {
|
||||||
size: Some((12, 20)),
|
size: Some((12, 20)),
|
||||||
structure: WidgetUse {
|
structure: WidgetUse {
|
||||||
name: "layout".to_owned(),
|
name: "layout".to_owned(),
|
||||||
children: vec![WidgetUse::simple_text(AttrValue::Concrete(PrimitiveValue::String(
|
children: vec![WidgetUse::simple_text(AttrValue::Concrete(PrimitiveValue::from_string(
|
||||||
"test".to_owned(),
|
"test".to_owned(),
|
||||||
)))],
|
)))],
|
||||||
attrs: HashMap::new(),
|
attrs: HashMap::new(),
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl ScriptVar {
|
||||||
pub fn initial_value(&self) -> Result<PrimitiveValue> {
|
pub fn initial_value(&self) -> Result<PrimitiveValue> {
|
||||||
match self {
|
match self {
|
||||||
ScriptVar::Poll(x) => Ok(crate::run_command(&x.command)?),
|
ScriptVar::Poll(x) => Ok(crate::run_command(&x.command)?),
|
||||||
ScriptVar::Tail(_) => Ok(PrimitiveValue::String(String::new())),
|
ScriptVar::Tail(_) => Ok(PrimitiveValue::from_string(String::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +126,8 @@ impl EwwConfig {
|
||||||
"var" => {
|
"var" => {
|
||||||
initial_variables.insert(
|
initial_variables.insert(
|
||||||
VarName(node.attr("name")?.to_owned()),
|
VarName(node.attr("name")?.to_owned()),
|
||||||
PrimitiveValue::parse_string(
|
PrimitiveValue::from_string(
|
||||||
&node
|
node.only_child()
|
||||||
.only_child()
|
|
||||||
.map(|c| c.as_text_or_sourcecode())
|
.map(|c| c.as_text_or_sourcecode())
|
||||||
.unwrap_or_else(|_| String::new()),
|
.unwrap_or_else(|_| String::new()),
|
||||||
),
|
),
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl ScriptVarHandler {
|
||||||
handle.read_line(&mut buffer)?;
|
handle.read_line(&mut buffer)?;
|
||||||
evt_send.send(app::EwwCommand::UpdateVar(
|
evt_send.send(app::EwwCommand::UpdateVar(
|
||||||
var_name.clone(),
|
var_name.clone(),
|
||||||
PrimitiveValue::parse_string(&buffer),
|
PrimitiveValue::from_string(buffer),
|
||||||
))?;
|
))?;
|
||||||
} else if event.hangup {
|
} else if event.hangup {
|
||||||
command_out_readers.remove(var_name);
|
command_out_readers.remove(var_name);
|
||||||
|
|
17
src/util.rs
17
src/util.rs
|
@ -5,6 +5,23 @@ use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fmt, path::Path};
|
use std::{fmt, path::Path};
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_many {
|
||||||
|
($trait:ident<$typ:ty> $fn_name:ident{
|
||||||
|
$(
|
||||||
|
for $for:ty => |$var:ident| $code:expr
|
||||||
|
);*;
|
||||||
|
}) => {
|
||||||
|
$(impl $trait<$typ> for $for {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
fn $fn_name($var: $typ) -> Result<Self> {
|
||||||
|
$code
|
||||||
|
}
|
||||||
|
})*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// read an scss file, replace all environment variable references within it and
|
/// read an scss file, replace all environment variable references within it and
|
||||||
/// then parse it into css.
|
/// then parse it into css.
|
||||||
pub fn parse_scss_from_file<P: AsRef<Path>>(path: P) -> Result<String> {
|
pub fn parse_scss_from_file<P: AsRef<Path>>(path: P) -> Result<String> {
|
||||||
|
|
101
src/value.rs
101
src/value.rs
|
@ -6,20 +6,14 @@ use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{convert::TryFrom, fmt};
|
use std::{convert::TryFrom, fmt};
|
||||||
|
|
||||||
|
use crate::impl_many;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Deserialize, Serialize, derive_more::From)]
|
#[derive(Clone, PartialEq, Deserialize, Serialize, derive_more::From)]
|
||||||
pub enum PrimitiveValue {
|
pub struct PrimitiveValue(String);
|
||||||
String(String),
|
|
||||||
Number(f64),
|
|
||||||
Boolean(bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for PrimitiveValue {
|
impl fmt::Display for PrimitiveValue {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
write!(f, "\"{}\"", self.0)
|
||||||
PrimitiveValue::String(s) => write!(f, "\"{}\"", s),
|
|
||||||
PrimitiveValue::Number(n) => write!(f, "{}", n),
|
|
||||||
PrimitiveValue::Boolean(b) => write!(f, "{}", b),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Debug for PrimitiveValue {
|
impl fmt::Debug for PrimitiveValue {
|
||||||
|
@ -34,80 +28,60 @@ impl std::str::FromStr for PrimitiveValue {
|
||||||
/// parses the value, trying to turn it into a number and a boolean first,
|
/// parses the value, trying to turn it into a number and a boolean first,
|
||||||
/// before deciding that it is a string.
|
/// before deciding that it is a string.
|
||||||
fn from_str(s: &str) -> Result<Self> {
|
fn from_str(s: &str) -> Result<Self> {
|
||||||
Ok(PrimitiveValue::parse_string(s))
|
Ok(PrimitiveValue::from_string(s.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_surrounding(s: &str, surround: char) -> &str {
|
impl_many!(TryFrom<PrimitiveValue> try_from {
|
||||||
s.strip_prefix(surround).unwrap_or(s).strip_suffix(surround).unwrap_or(s)
|
for String => |x| x.as_string();
|
||||||
}
|
for f64 => |x| x.as_f64();
|
||||||
|
for bool => |x| x.as_bool();
|
||||||
|
});
|
||||||
|
|
||||||
impl TryFrom<PrimitiveValue> for String {
|
impl From<i32> for PrimitiveValue {
|
||||||
type Error = anyhow::Error;
|
fn from(x: i32) -> Self {
|
||||||
|
PrimitiveValue(format!("{}", x))
|
||||||
fn try_from(x: PrimitiveValue) -> Result<Self> {
|
|
||||||
x.as_string()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<PrimitiveValue> for f64 {
|
impl From<bool> for PrimitiveValue {
|
||||||
type Error = anyhow::Error;
|
fn from(x: bool) -> Self {
|
||||||
|
PrimitiveValue(format!("{}", x))
|
||||||
fn try_from(x: PrimitiveValue) -> Result<Self> {
|
|
||||||
x.as_f64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<PrimitiveValue> for bool {
|
|
||||||
type Error = anyhow::Error;
|
|
||||||
|
|
||||||
fn try_from(x: PrimitiveValue) -> Result<Self> {
|
|
||||||
x.as_bool()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for PrimitiveValue {
|
impl From<&str> for PrimitiveValue {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
PrimitiveValue::String(s.to_string())
|
PrimitiveValue(s.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrimitiveValue {
|
impl PrimitiveValue {
|
||||||
/// parses the value, trying to turn it into a number and a boolean first,
|
pub fn from_string(s: String) -> Self {
|
||||||
/// before deciding that it is a string.
|
PrimitiveValue(s.to_string())
|
||||||
pub fn parse_string(s: &str) -> Self {
|
|
||||||
s.parse()
|
|
||||||
.map(PrimitiveValue::Number)
|
|
||||||
.or_else(|_| s.parse().map(PrimitiveValue::Boolean))
|
|
||||||
.unwrap_or_else(|_| PrimitiveValue::String(remove_surrounding(s, '\'').to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This will never fail
|
||||||
pub fn as_string(&self) -> Result<String> {
|
pub fn as_string(&self) -> Result<String> {
|
||||||
match self {
|
Ok(self.0.to_owned())
|
||||||
PrimitiveValue::String(x) => Ok(x.clone()),
|
|
||||||
PrimitiveValue::Number(x) => Ok(format!("{}", x)),
|
|
||||||
PrimitiveValue::Boolean(x) => Ok(format!("{}", x)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_f64(&self) -> Result<f64> {
|
pub fn as_f64(&self) -> Result<f64> {
|
||||||
match self {
|
self.0
|
||||||
PrimitiveValue::Number(x) => Ok(*x),
|
|
||||||
PrimitiveValue::String(x) => x
|
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| anyhow!("couldn't convert string {:?} to f64: {}", &self, e)),
|
.map_err(|e| anyhow!("couldn't convert {:?} to f64: {}", &self, e))
|
||||||
_ => Err(anyhow!("{:?} is not an f64", &self)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_i32(&self) -> Result<i32> {
|
||||||
|
self.0
|
||||||
|
.parse()
|
||||||
|
.map_err(|e| anyhow!("couldn't convert {:?} to i32: {}", &self, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_bool(&self) -> Result<bool> {
|
pub fn as_bool(&self) -> Result<bool> {
|
||||||
match self {
|
self.0
|
||||||
PrimitiveValue::Boolean(x) => Ok(*x),
|
|
||||||
PrimitiveValue::String(x) => x
|
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| anyhow!("couldn't convert string {:?} to bool: {}", &self, e)),
|
.map_err(|e| anyhow!("couldn't convert {:?} to bool: {}", &self, e))
|
||||||
_ => Err(anyhow!("{:?} is not a string", &self)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,21 +122,28 @@ pub enum AttrValue {
|
||||||
impl AttrValue {
|
impl AttrValue {
|
||||||
pub fn as_string(&self) -> Result<String> {
|
pub fn as_string(&self) -> Result<String> {
|
||||||
match self {
|
match self {
|
||||||
AttrValue::Concrete(x) => Ok(x.as_string()?),
|
AttrValue::Concrete(x) => x.as_string(),
|
||||||
_ => Err(anyhow!("{:?} is not a string", self)),
|
_ => Err(anyhow!("{:?} is not a string", self)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_f64(&self) -> Result<f64> {
|
pub fn as_f64(&self) -> Result<f64> {
|
||||||
match self {
|
match self {
|
||||||
AttrValue::Concrete(x) => Ok(x.as_f64()?),
|
AttrValue::Concrete(x) => x.as_f64(),
|
||||||
_ => Err(anyhow!("{:?} is not an f64", self)),
|
_ => Err(anyhow!("{:?} is not an f64", self)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_i32(&self) -> Result<i32> {
|
||||||
|
match self {
|
||||||
|
AttrValue::Concrete(x) => x.as_i32(),
|
||||||
|
_ => Err(anyhow!("{:?} is not an i32", self)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_bool(&self) -> Result<bool> {
|
pub fn as_bool(&self) -> Result<bool> {
|
||||||
match self {
|
match self {
|
||||||
AttrValue::Concrete(x) => Ok(x.as_bool()?),
|
AttrValue::Concrete(x) => x.as_bool(),
|
||||||
_ => Err(anyhow!("{:?} is not a bool", self)),
|
_ => Err(anyhow!("{:?} is not a bool", self)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +165,7 @@ impl AttrValue {
|
||||||
if let Some(ref_name) = PATTERN.captures(&s).and_then(|cap| cap.get(1)).map(|x| x.as_str()) {
|
if let Some(ref_name) = PATTERN.captures(&s).and_then(|cap| cap.get(1)).map(|x| x.as_str()) {
|
||||||
AttrValue::VarRef(VarName(ref_name.to_owned()))
|
AttrValue::VarRef(VarName(ref_name.to_owned()))
|
||||||
} else {
|
} else {
|
||||||
AttrValue::Concrete(PrimitiveValue::String(s))
|
AttrValue::Concrete(PrimitiveValue::from_string(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
use gtk::{prelude::*, ImageExt};
|
use gtk::{prelude::*, ImageExt};
|
||||||
use std::{cell::RefCell, path::Path, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use gdk_pixbuf;
|
use gdk_pixbuf;
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@ use gdk_pixbuf;
|
||||||
pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<Option<gtk::Widget>> {
|
pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<Option<gtk::Widget>> {
|
||||||
let gtk_widget = match bargs.widget.name.as_str() {
|
let gtk_widget = match bargs.widget.name.as_str() {
|
||||||
"box" => build_gtk_box(bargs)?.upcast(),
|
"box" => build_gtk_box(bargs)?.upcast(),
|
||||||
"slider" => build_gtk_scale(bargs)?.upcast(),
|
"scale" => build_gtk_scale(bargs)?.upcast(),
|
||||||
"image" => build_gtk_image(bargs)?.upcast(),
|
"image" => build_gtk_image(bargs)?.upcast(),
|
||||||
"button" => build_gtk_button(bargs)?.upcast(),
|
"button" => build_gtk_button(bargs)?.upcast(),
|
||||||
"label" => build_gtk_label(bargs)?.upcast(),
|
"label" => build_gtk_label(bargs)?.upcast(),
|
||||||
"text" => build_gtk_text(bargs)?.upcast(),
|
"text" => build_gtk_text(bargs)?.upcast(),
|
||||||
"aspect" => build_gtk_aspect_frame(bargs)?.upcast(),
|
|
||||||
"literal" => build_gtk_literal(bargs)?.upcast(),
|
"literal" => build_gtk_literal(bargs)?.upcast(),
|
||||||
"input" => build_gtk_input(bargs)?.upcast(),
|
"input" => build_gtk_input(bargs)?.upcast(),
|
||||||
"calendar" => build_gtk_calendar(bargs)?.upcast(),
|
"calendar" => build_gtk_calendar(bargs)?.upcast(),
|
||||||
|
@ -32,6 +31,7 @@ pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<Option<gtk
|
||||||
}
|
}
|
||||||
|
|
||||||
/// attributes that apply to all widgets
|
/// attributes that apply to all widgets
|
||||||
|
/// @widget !widget
|
||||||
pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Widget) {
|
pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Widget) {
|
||||||
let css_provider = gtk::CssProvider::new();
|
let css_provider = gtk::CssProvider::new();
|
||||||
|
|
||||||
|
@ -53,21 +53,30 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Wi
|
||||||
let on_hover_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_hover_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop class - css class name
|
||||||
prop(class: as_string) { gtk_widget.get_style_context().add_class(&class) },
|
prop(class: as_string) { gtk_widget.get_style_context().add_class(&class) },
|
||||||
|
// @prop valign - how to align this vertically. possible values: $alignment
|
||||||
prop(valign: as_string) { gtk_widget.set_valign(parse_align(&valign)?) },
|
prop(valign: as_string) { gtk_widget.set_valign(parse_align(&valign)?) },
|
||||||
|
// @prop halign - how to align this horizontally. possible values: $alignment
|
||||||
prop(halign: as_string) { gtk_widget.set_halign(parse_align(&halign)?) },
|
prop(halign: as_string) { gtk_widget.set_halign(parse_align(&halign)?) },
|
||||||
prop(width: as_f64 ) { gtk_widget.set_size_request(width as i32, gtk_widget.get_allocated_height()) },
|
// @prop width - width of this element. note that this can not restrict the size if the contents stretch it
|
||||||
prop(height: as_f64 ) { gtk_widget.set_size_request(gtk_widget.get_allocated_width(), height as i32) },
|
prop(width: as_f64) { gtk_widget.set_size_request(width as i32, gtk_widget.get_allocated_height()) },
|
||||||
|
// @prop height - height of this element. note that this can not restrict the size if the contents stretch it
|
||||||
|
prop(height: as_f64) { gtk_widget.set_size_request(gtk_widget.get_allocated_width(), height as i32) },
|
||||||
|
// @prop active - If this widget can be interacted with
|
||||||
prop(active: as_bool = true) { gtk_widget.set_sensitive(active) },
|
prop(active: as_bool = true) { gtk_widget.set_sensitive(active) },
|
||||||
|
// @prop visible - visibility of the widget
|
||||||
prop(visible: as_bool = true) {
|
prop(visible: as_bool = true) {
|
||||||
// TODO how do i call this only after the widget has been mapped? this is actually an issue,....
|
// TODO how do i call this only after the widget has been mapped? this is actually an issue,....
|
||||||
if visible { gtk_widget.show(); } else { gtk_widget.hide(); }
|
if visible { gtk_widget.show(); } else { gtk_widget.hide(); }
|
||||||
},
|
},
|
||||||
|
// @prop style - inline css style applied to the widget
|
||||||
prop(style: as_string) {
|
prop(style: as_string) {
|
||||||
gtk_widget.reset_style();
|
gtk_widget.reset_style();
|
||||||
css_provider.load_from_data(format!("* {{ {} }}", style).as_bytes())?;
|
css_provider.load_from_data(format!("* {{ {} }}", style).as_bytes())?;
|
||||||
gtk_widget.get_style_context().add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION)
|
gtk_widget.get_style_context().add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||||
},
|
},
|
||||||
|
// @prop onscroll - event to execute when the user scrolls with the mouse over the widget
|
||||||
prop(onscroll: as_string) {
|
prop(onscroll: as_string) {
|
||||||
gtk_widget.add_events(gdk::EventMask::SCROLL_MASK);
|
gtk_widget.add_events(gdk::EventMask::SCROLL_MASK);
|
||||||
gtk_widget.add_events(gdk::EventMask::SMOOTH_SCROLL_MASK);
|
gtk_widget.add_events(gdk::EventMask::SMOOTH_SCROLL_MASK);
|
||||||
|
@ -79,6 +88,7 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Wi
|
||||||
));
|
));
|
||||||
old_id.map(|id| gtk_widget.disconnect(id));
|
old_id.map(|id| gtk_widget.disconnect(id));
|
||||||
},
|
},
|
||||||
|
// @prop onhover - event to execute when the user hovers over the widget
|
||||||
prop(onhover: as_string) {
|
prop(onhover: as_string) {
|
||||||
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
||||||
let old_id = on_hover_handler_id.replace(Some(
|
let old_id = on_hover_handler_id.replace(Some(
|
||||||
|
@ -92,23 +102,29 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Wi
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// attributes that apply to all container widgets
|
/// @widget !container
|
||||||
pub(super) fn resolve_container_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Container) {
|
pub(super) fn resolve_container_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Container) {
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop vexpand - should this container expand vertically
|
||||||
prop(vexpand: as_bool = false) { gtk_widget.set_vexpand(vexpand) },
|
prop(vexpand: as_bool = false) { gtk_widget.set_vexpand(vexpand) },
|
||||||
|
// @prop hexpand - should this container expand horizontally
|
||||||
prop(hexpand: as_bool = false) { gtk_widget.set_hexpand(hexpand) },
|
prop(hexpand: as_bool = false) { gtk_widget.set_hexpand(hexpand) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget !range
|
||||||
pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||||
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
gtk_widget.set_sensitive(false);
|
gtk_widget.set_sensitive(false);
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
prop(value : as_f64) { gtk_widget.set_value(value)},
|
// @prop value - the value
|
||||||
prop(min : as_f64) { gtk_widget.get_adjustment().set_lower(min)},
|
prop(value: as_f64) { gtk_widget.set_value(value)},
|
||||||
prop(max : as_f64) { gtk_widget.get_adjustment().set_upper(max)},
|
// @prop min - the minimum value
|
||||||
prop(orientation : as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
|
prop(min: as_f64) { gtk_widget.get_adjustment().set_lower(min)},
|
||||||
prop(onchange : as_string) {
|
// @prop max - the maximum value
|
||||||
|
prop(max: as_f64) { gtk_widget.get_adjustment().set_upper(max)},
|
||||||
|
// @prop onchange - command executed once the value is changes. The placeholder `{}`, used in the command will be replaced by the new value.
|
||||||
|
prop(onchange: as_string) {
|
||||||
gtk_widget.set_sensitive(true);
|
gtk_widget.set_sensitive(true);
|
||||||
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
||||||
let old_id = on_change_handler_id.replace(Some(
|
let old_id = on_change_handler_id.replace(Some(
|
||||||
|
@ -122,26 +138,35 @@ pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Ran
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget !orientable
|
||||||
pub(super) fn resolve_orientable_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
pub(super) fn resolve_orientable_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop orientation - orientation of the widget. Possible values: $orientation
|
||||||
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
|
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// concrete widgets
|
// concrete widgets
|
||||||
|
|
||||||
|
/// @widget scale extends range
|
||||||
|
/// @desc a slider.
|
||||||
fn build_gtk_scale(bargs: &mut BuilderArgs) -> Result<gtk::Scale> {
|
fn build_gtk_scale(bargs: &mut BuilderArgs) -> Result<gtk::Scale> {
|
||||||
let gtk_widget = gtk::Scale::new(
|
let gtk_widget = gtk::Scale::new(
|
||||||
gtk::Orientation::Horizontal,
|
gtk::Orientation::Horizontal,
|
||||||
Some(>k::Adjustment::new(0.0, 0.0, 100.0, 1.0, 1.0, 1.0)),
|
Some(>k::Adjustment::new(0.0, 0.0, 100.0, 1.0, 1.0, 1.0)),
|
||||||
);
|
);
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop flipped - flip the direction
|
||||||
prop(flipped: as_bool) { gtk_widget.set_inverted(flipped) },
|
prop(flipped: as_bool) { gtk_widget.set_inverted(flipped) },
|
||||||
|
|
||||||
|
// @prop draw-value - draw the value of the property
|
||||||
prop(draw_value: as_bool = false) { gtk_widget.set_draw_value(draw_value) },
|
prop(draw_value: as_bool = false) { gtk_widget.set_draw_value(draw_value) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget input
|
||||||
|
/// @desc an input field that doesn't yet really work
|
||||||
fn build_gtk_input(bargs: &mut BuilderArgs) -> Result<gtk::Entry> {
|
fn build_gtk_input(bargs: &mut BuilderArgs) -> Result<gtk::Entry> {
|
||||||
let gtk_widget = gtk::Entry::new();
|
let gtk_widget = gtk::Entry::new();
|
||||||
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
|
@ -162,10 +187,12 @@ fn build_gtk_input(bargs: &mut BuilderArgs) -> Result<gtk::Entry> {
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget button extends container
|
||||||
fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
||||||
let gtk_widget = gtk::Button::new();
|
let gtk_widget = gtk::Button::new();
|
||||||
let on_click_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_click_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop onclick - a command that get's run when the button is clicked
|
||||||
prop(onclick: as_string) {
|
prop(onclick: as_string) {
|
||||||
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
gtk_widget.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
|
||||||
let old_id = on_click_handler_id.replace(Some(
|
let old_id = on_click_handler_id.replace(Some(
|
||||||
|
@ -178,38 +205,47 @@ fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget image
|
||||||
fn build_gtk_image(bargs: &mut BuilderArgs) -> Result<gtk::Image> {
|
fn build_gtk_image(bargs: &mut BuilderArgs) -> Result<gtk::Image> {
|
||||||
let gtk_widget = gtk::Image::new();
|
let gtk_widget = gtk::Image::new();
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
prop(path: as_string) {
|
// @prop path - path to the image file
|
||||||
gtk_widget.set_from_file(Path::new(&path));
|
// @prop width - width of the image
|
||||||
},
|
// @prop height - height of the image
|
||||||
prop(path: as_string, width: as_f64, height: as_f64) {
|
prop(path: as_string, width: as_i32 = 10000, height: as_i32 = 10000) {
|
||||||
let pixbuf = gdk_pixbuf::Pixbuf::from_file_at_size(std::path::PathBuf::from(path), width as i32, height as i32)?;
|
let pixbuf = gdk_pixbuf::Pixbuf::from_file_at_size(std::path::PathBuf::from(path), width, height)?;
|
||||||
gtk_widget.set_from_pixbuf(Some(&pixbuf));
|
gtk_widget.set_from_pixbuf(Some(&pixbuf));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget box extends container
|
||||||
|
/// @desc the main layout container
|
||||||
fn build_gtk_box(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
fn build_gtk_box(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||||
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
prop(spacing: as_f64 = 0.0) { gtk_widget.set_spacing(spacing as i32) },
|
// @prop spacing - spacing between elements
|
||||||
|
prop(spacing: as_i32 = 0) { gtk_widget.set_spacing(spacing) },
|
||||||
|
// @prop orientation - orientation of the box. possible values: $orientation
|
||||||
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
|
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
|
||||||
|
// @prop space-evenly - space the widgets evenly.
|
||||||
prop(space_evenly: as_bool = true) { gtk_widget.set_homogeneous(space_evenly) },
|
prop(space_evenly: as_bool = true) { gtk_widget.set_homogeneous(space_evenly) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget label
|
||||||
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
||||||
let gtk_widget = gtk::Label::new(None);
|
let gtk_widget = gtk::Label::new(None);
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop - the text to display
|
||||||
prop(text: as_string) { gtk_widget.set_text(&text) },
|
prop(text: as_string) { gtk_widget.set_text(&text) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget text
|
||||||
fn build_gtk_text(_bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
fn build_gtk_text(_bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||||
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||||
gtk_widget.set_halign(gtk::Align::Center);
|
gtk_widget.set_halign(gtk::Align::Center);
|
||||||
|
@ -217,12 +253,15 @@ fn build_gtk_text(_bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget literal
|
||||||
|
/// @desc a tag that allows you to render arbitrary XML.
|
||||||
fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
|
fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
|
||||||
let gtk_widget = gtk::Frame::new(None);
|
let gtk_widget = gtk::Frame::new(None);
|
||||||
// TODO these clones here are dumdum
|
// TODO these clones here are dumdum
|
||||||
let window_name = bargs.window_name.clone();
|
let window_name = bargs.window_name.clone();
|
||||||
let widget_definitions = bargs.widget_definitions.clone();
|
let widget_definitions = bargs.widget_definitions.clone();
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop - inline Eww XML that will be rendered as a widget.
|
||||||
prop(content: as_string) {
|
prop(content: as_string) {
|
||||||
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
||||||
if !content.is_empty() {
|
if !content.is_empty() {
|
||||||
|
@ -243,18 +282,26 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Frame> {
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @widget calendar
|
||||||
fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result<gtk::Calendar> {
|
fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result<gtk::Calendar> {
|
||||||
let gtk_widget = gtk::Calendar::new();
|
let gtk_widget = gtk::Calendar::new();
|
||||||
let on_click_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_click_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
|
// @prop day - the selected day
|
||||||
prop(day: as_f64) { gtk_widget.set_property_day(day as i32) },
|
prop(day: as_f64) { gtk_widget.set_property_day(day as i32) },
|
||||||
|
// @prop month - the selected month
|
||||||
prop(month: as_f64) { gtk_widget.set_property_day(month as i32) },
|
prop(month: as_f64) { gtk_widget.set_property_day(month as i32) },
|
||||||
|
// @prop year - the selected year
|
||||||
prop(year: as_f64) { gtk_widget.set_property_day(year as i32) },
|
prop(year: as_f64) { gtk_widget.set_property_day(year as i32) },
|
||||||
|
// @prop show-details - show details
|
||||||
prop(show_details: as_bool) { gtk_widget.set_property_show_details(show_details) },
|
prop(show_details: as_bool) { gtk_widget.set_property_show_details(show_details) },
|
||||||
prop(show_heading: as_bool) { gtk_widget.set_property_show_details(show_heading) },
|
// @prop show-heading - show heading line
|
||||||
prop(show_day_names: as_bool) { gtk_widget.set_property_show_day_names(show_day_names) },
|
|
||||||
prop(show_week_numbers: as_bool) { gtk_widget.set_property_show_week_numbers(show_week_numbers) },
|
|
||||||
prop(show_heading: as_bool) { gtk_widget.set_property_show_heading(show_heading) },
|
prop(show_heading: as_bool) { gtk_widget.set_property_show_heading(show_heading) },
|
||||||
|
// @prop show-day-names - show names of days
|
||||||
|
prop(show_day_names: as_bool) { gtk_widget.set_property_show_day_names(show_day_names) },
|
||||||
|
// @prop show-week-numbers - show week numbers
|
||||||
|
prop(show_week_numbers: as_bool) { gtk_widget.set_property_show_week_numbers(show_week_numbers) },
|
||||||
|
// @prop onclick - command to run when the user selects a date. The `{}` placeholder will be replaced by the selected date.
|
||||||
prop(onclick: as_string) {
|
prop(onclick: as_string) {
|
||||||
let old_id = on_click_handler_id.replace(Some(
|
let old_id = on_click_handler_id.replace(Some(
|
||||||
gtk_widget.connect_day_selected(move |w| {
|
gtk_widget.connect_day_selected(move |w| {
|
||||||
|
@ -272,11 +319,7 @@ fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result<gtk::Calendar> {
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_aspect_frame(_bargs: &mut BuilderArgs) -> Result<gtk::AspectFrame> {
|
/// @var orientation - "vertical", "v", "horizontal", "h"
|
||||||
let gtk_widget = gtk::AspectFrame::new(None, 0.5, 0.5, 1.0, true);
|
|
||||||
Ok(gtk_widget)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_orientation(o: &str) -> Result<gtk::Orientation> {
|
fn parse_orientation(o: &str) -> Result<gtk::Orientation> {
|
||||||
Ok(match o {
|
Ok(match o {
|
||||||
"vertical" | "v" => gtk::Orientation::Vertical,
|
"vertical" | "v" => gtk::Orientation::Vertical,
|
||||||
|
@ -285,6 +328,7 @@ fn parse_orientation(o: &str) -> Result<gtk::Orientation> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @var align - "fill", "baseline", "center", "start", "end"
|
||||||
fn parse_align(o: &str) -> Result<gtk::Align> {
|
fn parse_align(o: &str) -> Result<gtk::Align> {
|
||||||
Ok(match o {
|
Ok(match o {
|
||||||
"fill" => gtk::Align::Fill,
|
"fill" => gtk::Align::Fill,
|
||||||
|
|
Loading…
Add table
Reference in a new issue