wgui: add <macro> support, propagate variables into ParserResult
This commit is contained in:
@@ -20,8 +20,6 @@ use std::{
|
|||||||
rc::Rc,
|
rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
type VarMap = HashMap<Rc<str>, Rc<str>>;
|
|
||||||
|
|
||||||
#[self_referencing]
|
#[self_referencing]
|
||||||
struct XmlDocument {
|
struct XmlDocument {
|
||||||
xml: String,
|
xml: String,
|
||||||
@@ -44,6 +42,8 @@ struct ParserFile {
|
|||||||
|
|
||||||
pub struct ParserResult {
|
pub struct ParserResult {
|
||||||
pub ids: HashMap<Rc<str>, WidgetID>,
|
pub ids: HashMap<Rc<str>, WidgetID>,
|
||||||
|
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
||||||
|
var_map: HashMap<Rc<str>, Rc<str>>,
|
||||||
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,13 @@ impl ParserResult {
|
|||||||
anyhow::bail!("no template named \"{}\" found", template_name);
|
anyhow::bail!("no template named \"{}\" found", template_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ctx = create_default_context(layout);
|
let mut ctx = ParserContext {
|
||||||
|
layout,
|
||||||
|
ids: Default::default(),
|
||||||
|
macro_attribs: self.macro_attribs.clone(), // FIXME: prevent copying
|
||||||
|
var_map: self.var_map.clone(), // FIXME: prevent copying
|
||||||
|
templates: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
let file = ParserFile {
|
let file = ParserFile {
|
||||||
document: template.node_document.clone(),
|
document: template.node_document.clone(),
|
||||||
@@ -75,21 +81,15 @@ impl ParserResult {
|
|||||||
template_parameters: template_parameters.clone(), // FIXME: prevent copying
|
template_parameters: template_parameters.clone(), // FIXME: prevent copying
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = template
|
|
||||||
.node_document
|
|
||||||
.borrow_doc()
|
|
||||||
.get_node(template.node)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
parse_widget_other_internal(
|
parse_widget_other_internal(
|
||||||
template.clone(),
|
template.clone(),
|
||||||
template_parameters,
|
template_parameters,
|
||||||
&file,
|
&file,
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
node,
|
|
||||||
widget_id,
|
widget_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// FIXME?
|
||||||
ctx.ids.into_iter().for_each(|(id, key)| {
|
ctx.ids.into_iter().for_each(|(id, key)| {
|
||||||
self.ids.insert(id, key);
|
self.ids.insert(id, key);
|
||||||
});
|
});
|
||||||
@@ -98,11 +98,17 @@ impl ParserResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct MacroAttribs {
|
||||||
|
attribs: HashMap<Rc<str>, Rc<str>>,
|
||||||
|
}
|
||||||
|
|
||||||
struct ParserContext<'a> {
|
struct ParserContext<'a> {
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
var_map: VarMap,
|
var_map: HashMap<Rc<str>, Rc<str>>,
|
||||||
templates: HashMap<Rc<str>, Rc<Template>>,
|
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
||||||
ids: HashMap<Rc<str>, WidgetID>,
|
ids: HashMap<Rc<str>, WidgetID>,
|
||||||
|
templates: HashMap<Rc<str>, Rc<Template>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a color from a HTML hex string
|
// Parses a color from a HTML hex string
|
||||||
@@ -207,12 +213,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_other_internal<'a>(
|
fn parse_widget_other_internal(
|
||||||
template: Rc<Template>,
|
template: Rc<Template>,
|
||||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||||
file: &'a ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let template_file = ParserFile {
|
let template_file = ParserFile {
|
||||||
@@ -245,16 +250,10 @@ fn parse_widget_other<'a>(
|
|||||||
return Ok(()); // not critical
|
return Ok(()); // not critical
|
||||||
};
|
};
|
||||||
|
|
||||||
let template_parameters: HashMap<Rc<str>, Rc<str>> = iter_attribs(file, ctx, &node).collect();
|
let template_parameters: HashMap<Rc<str>, Rc<str>> =
|
||||||
|
iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
parse_widget_other_internal(
|
parse_widget_other_internal(template.clone(), template_parameters, file, ctx, parent_id)
|
||||||
template.clone(),
|
|
||||||
template_parameters,
|
|
||||||
file,
|
|
||||||
ctx,
|
|
||||||
node,
|
|
||||||
parent_id,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_include<'a>(
|
fn parse_tag_include<'a>(
|
||||||
@@ -333,7 +332,10 @@ pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
|||||||
|
|
||||||
match vars.get(input_var) {
|
match vars.get(input_var) {
|
||||||
Some(replacement) => replacement.clone(),
|
Some(replacement) => replacement.clone(),
|
||||||
None => Rc::from(""),
|
None => {
|
||||||
|
log::warn!("failed to replace var named \"{}\" (not found)", input_var);
|
||||||
|
Rc::from("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -341,31 +343,64 @@ pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::manual_strip)]
|
#[allow(clippy::manual_strip)]
|
||||||
|
fn process_attrib<'a>(
|
||||||
|
file: &'a ParserFile,
|
||||||
|
ctx: &'a ParserContext,
|
||||||
|
key: &str,
|
||||||
|
value: &str,
|
||||||
|
) -> (Rc<str>, Rc<str>) {
|
||||||
|
if value.starts_with("~") {
|
||||||
|
let name = &value[1..];
|
||||||
|
|
||||||
|
(
|
||||||
|
Rc::from(key),
|
||||||
|
match ctx.var_map.get(name) {
|
||||||
|
Some(name) => name.clone(),
|
||||||
|
None => Rc::from("undefined"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
Rc::from(key),
|
||||||
|
replace_vars(value, &file.template_parameters),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn iter_attribs<'a>(
|
fn iter_attribs<'a>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &'a ParserContext,
|
ctx: &'a ParserContext,
|
||||||
node: &roxmltree::Node<'a, 'a>,
|
node: &'a roxmltree::Node<'a, 'a>,
|
||||||
|
is_tag_macro: bool,
|
||||||
) -> impl Iterator<Item = (/*key*/ Rc<str>, /*value*/ Rc<str>)> + 'a {
|
) -> impl Iterator<Item = (/*key*/ Rc<str>, /*value*/ Rc<str>)> + 'a {
|
||||||
node.attributes().map(|attrib| {
|
let mut res = Vec::<(Rc<str>, Rc<str>)>::new();
|
||||||
|
|
||||||
|
if is_tag_macro {
|
||||||
|
// return as-is, no attrib post-processing
|
||||||
|
for attrib in node.attributes() {
|
||||||
|
let (key, value) = (attrib.name(), attrib.value());
|
||||||
|
res.push((Rc::from(key), Rc::from(value)));
|
||||||
|
}
|
||||||
|
return res.into_iter();
|
||||||
|
}
|
||||||
|
|
||||||
|
for attrib in node.attributes() {
|
||||||
let (key, value) = (attrib.name(), attrib.value());
|
let (key, value) = (attrib.name(), attrib.value());
|
||||||
|
|
||||||
if value.starts_with("~") {
|
if key == "macro" {
|
||||||
let name = &value[1..];
|
if let Some(macro_attrib) = ctx.macro_attribs.get(value) {
|
||||||
|
for (macro_key, macro_value) in macro_attrib.attribs.iter() {
|
||||||
(
|
res.push(process_attrib(file, ctx, macro_key, macro_value));
|
||||||
Rc::from(key),
|
}
|
||||||
match ctx.var_map.get(name) {
|
} else {
|
||||||
Some(name) => name.clone(),
|
log::warn!("requested macro named \"{}\" not found!", value);
|
||||||
None => Rc::from("undefined"),
|
}
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(
|
res.push(process_attrib(file, ctx, key, value));
|
||||||
Rc::from(key),
|
|
||||||
replace_vars(value, &file.template_parameters),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
res.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_theme<'a>(
|
fn parse_tag_theme<'a>(
|
||||||
@@ -395,7 +430,7 @@ fn parse_tag_template(
|
|||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut template_name: Option<Rc<str>> = None;
|
let mut template_name: Option<Rc<str>> = None;
|
||||||
|
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
match key.as_ref() {
|
match key.as_ref() {
|
||||||
@@ -424,13 +459,51 @@ fn parse_tag_template(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_tag_macro(
|
||||||
|
file: &ParserFile,
|
||||||
|
ctx: &mut ParserContext,
|
||||||
|
node: roxmltree::Node<'_, '_>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let mut macro_name: Option<Rc<str>> = None;
|
||||||
|
|
||||||
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, true).collect();
|
||||||
|
let mut macro_attribs = HashMap::<Rc<str>, Rc<str>>::new();
|
||||||
|
|
||||||
|
for (key, value) in attribs {
|
||||||
|
match key.as_ref() {
|
||||||
|
"name" => {
|
||||||
|
macro_name = Some(value);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if macro_attribs.insert(key.clone(), value).is_some() {
|
||||||
|
log::warn!("macro attrib \"{}\" already defined!", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(name) = macro_name else {
|
||||||
|
log::error!("Template name not specified, ignoring");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.macro_attribs.insert(
|
||||||
|
name.clone(),
|
||||||
|
MacroAttribs {
|
||||||
|
attribs: macro_attribs,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_universal<'a>(
|
fn parse_universal<'a>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
@@ -485,6 +558,7 @@ fn create_default_context(layout: &mut Layout) -> ParserContext<'_> {
|
|||||||
ids: Default::default(),
|
ids: Default::default(),
|
||||||
var_map: Default::default(),
|
var_map: Default::default(),
|
||||||
templates: Default::default(),
|
templates: Default::default(),
|
||||||
|
macro_attribs: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +578,8 @@ pub fn parse_from_assets(
|
|||||||
let result = ParserResult {
|
let result = ParserResult {
|
||||||
ids: std::mem::take(&mut ctx.ids),
|
ids: std::mem::take(&mut ctx.ids),
|
||||||
templates: std::mem::take(&mut ctx.templates),
|
templates: std::mem::take(&mut ctx.templates),
|
||||||
|
macro_attribs: std::mem::take(&mut ctx.macro_attribs),
|
||||||
|
var_map: std::mem::take(&mut ctx.var_map),
|
||||||
path,
|
path,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -571,6 +647,7 @@ fn parse_document_root(
|
|||||||
"include" => parse_tag_include(&file, ctx, child_node, parent_id)?,
|
"include" => parse_tag_include(&file, ctx, child_node, parent_id)?,
|
||||||
"theme" => parse_tag_theme(ctx, child_node)?,
|
"theme" => parse_tag_theme(ctx, child_node)?,
|
||||||
"template" => parse_tag_template(&file, ctx, child_node)?,
|
"template" => parse_tag_template(&file, ctx, child_node)?,
|
||||||
|
"macro" => parse_tag_macro(&file, ctx, child_node)?,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn style_from_node<'a>(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
match &*key {
|
match &*key {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn parse_widget_label<'a>(
|
|||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut params = TextParams::default();
|
let mut params = TextParams::default();
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
match &*key {
|
match &*key {
|
||||||
"text" => {
|
"text" => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn parse_widget_rectangle<'a>(
|
|||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut params = RectangleParams::default();
|
let mut params = RectangleParams::default();
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
match &*key {
|
match &*key {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn parse_widget_sprite<'a>(
|
|||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut params = SpriteBoxParams::default();
|
let mut params = SpriteBoxParams::default();
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
let mut glyph = None;
|
let mut glyph = None;
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
<layout>
|
<layout>
|
||||||
|
<macro name="keycap_rect"
|
||||||
|
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
||||||
|
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
||||||
|
align_items="center" justify_content="center" />
|
||||||
|
|
||||||
|
<macro name="keycap_div"
|
||||||
|
width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- The keyboard is build from the xkb keymap. This file is for customizing the keycaps. -->
|
<!-- The keyboard is build from the xkb keymap. This file is for customizing the keycaps. -->
|
||||||
|
|
||||||
<!-- Key cap with a single label. -->
|
<!-- Key cap with a single label. -->
|
||||||
<!-- Used for special keys. -->
|
<!-- Used for special keys. -->
|
||||||
<template name="KeySpecial">
|
<template name="KeySpecial">
|
||||||
<div width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}">
|
<div macro="keycap_div">
|
||||||
<rectangle id="${id}"
|
<rectangle id="${id}" macro="keycap_rect">
|
||||||
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
|
||||||
align_items="center"
|
|
||||||
justify_content="center">
|
|
||||||
<sprite color="#FFFFFF" width="32" height="32" src="keyboard/${text}.svg" />
|
<sprite color="#FFFFFF" width="32" height="32" src="keyboard/${text}.svg" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,12 +23,8 @@
|
|||||||
<!-- Key cap with a single label. -->
|
<!-- Key cap with a single label. -->
|
||||||
<!-- Used for letter keys on layouts without AltGr. -->
|
<!-- Used for letter keys on layouts without AltGr. -->
|
||||||
<template name="KeyLetter">
|
<template name="KeyLetter">
|
||||||
<div width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}">
|
<div macro="keycap_div">
|
||||||
<rectangle id="${id}"
|
<rectangle id="${id}" macro="keycap_rect">
|
||||||
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
|
||||||
align_items="center"
|
|
||||||
justify_content="center">
|
|
||||||
<label color="#FFFFFF" text="${text}" size="24" />
|
<label color="#FFFFFF" text="${text}" size="24" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,14 +33,8 @@
|
|||||||
<!-- Key cap with a primary label on top and an AltGr label on bottom. -->
|
<!-- Key cap with a primary label on top and an AltGr label on bottom. -->
|
||||||
<!-- Used for letter keys on layouts with AltGr. -->
|
<!-- Used for letter keys on layouts with AltGr. -->
|
||||||
<template name="KeyLetterAltGr">
|
<template name="KeyLetterAltGr">
|
||||||
<div width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}">
|
<div macro="keycap_div">
|
||||||
<rectangle id="${id}"
|
<rectangle id="${id}" macro="keycap_rect" gap="4">
|
||||||
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
|
||||||
gap="4"
|
|
||||||
flex_direction="column"
|
|
||||||
align_items="center"
|
|
||||||
justify_content="center">
|
|
||||||
<label color="#FFFFFF" text="${text}" size="24" />
|
<label color="#FFFFFF" text="${text}" size="24" />
|
||||||
<label color="#FFFFFF70" text="${text_altgr}" size="24" />
|
<label color="#FFFFFF70" text="${text_altgr}" size="24" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
@@ -49,15 +44,8 @@
|
|||||||
<!-- Key cap with a primary label on bottom and a Shift label on top. -->
|
<!-- Key cap with a primary label on bottom and a Shift label on top. -->
|
||||||
<!-- Used for number & symbol keys on layouts without AltGr. -->
|
<!-- Used for number & symbol keys on layouts without AltGr. -->
|
||||||
<template name="KeySymbol">
|
<template name="KeySymbol">
|
||||||
<div width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}">
|
<div macro="keycap_div">
|
||||||
<rectangle id="${id}"
|
<rectangle id="${id}" macro="keycap_rect" gap="4">
|
||||||
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
|
||||||
gap="4"
|
|
||||||
flex_direction="column"
|
|
||||||
align_items="center"
|
|
||||||
justify_content="center"
|
|
||||||
>
|
|
||||||
<label color="#FFFFFF70" text="${text_shift}" size="24" />
|
<label color="#FFFFFF70" text="${text_shift}" size="24" />
|
||||||
<label color="#FFFFFF" text="${text}" size="24" />
|
<label color="#FFFFFF" text="${text}" size="24" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
@@ -67,14 +55,8 @@
|
|||||||
<!-- Key cap with a primary label on bottom-left, an AltGr label on bottom-right, Shift label on top-left. -->
|
<!-- Key cap with a primary label on bottom-left, an AltGr label on bottom-right, Shift label on top-left. -->
|
||||||
<!-- Used for number & symbol keys on layouts with AltGr. -->
|
<!-- Used for number & symbol keys on layouts with AltGr. -->
|
||||||
<template name="KeySymbolAltGr">
|
<template name="KeySymbolAltGr">
|
||||||
<div width="${width}" height="${height}" min_width="${width}" min_height="${height}" max_width="${width}" max_height="${height}">
|
<div macro="keycap_div">
|
||||||
<rectangle id="${id}"
|
<rectangle id="${id}" macro="keycap_rect" flex_direction="row" flex_wrap="wrap">
|
||||||
margin="2" width="100%" overflow="hidden" box_sizing="border_box"
|
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical"
|
|
||||||
flex_direction="row"
|
|
||||||
flex_wrap="wrap"
|
|
||||||
align_items="center"
|
|
||||||
justify_content="center">
|
|
||||||
<div width="50%" height="50%" align_items="center" justify_content="center">
|
<div width="50%" height="50%" align_items="center" justify_content="center">
|
||||||
<label color="#FFFFFF70" text="${text_shift}" size="24" />
|
<label color="#FFFFFF70" text="${text_shift}" size="24" />
|
||||||
</div>
|
</div>
|
||||||
@@ -89,4 +71,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
Reference in New Issue
Block a user