Renamed `map_to_text` to `map_to_txt`.
Finished button docs. Implemented `Command::on_event` that subscribes to the command too, not just the command event.
This commit is contained in:
parent
c35a070e75
commit
6cabab4d5a
|
@ -1,6 +1,7 @@
|
|||
* Test touch context menu.
|
||||
* Add description tooltip (with shortcut) for command button.
|
||||
* Finish documenting button module.
|
||||
* `StyleMix` does not capture `extend_style`/`replace_style` on the same widget, so it ends-up ignored. Need
|
||||
to promote this pattern.
|
||||
|
||||
# Documentation
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ fn app_main() {
|
|||
Window! {
|
||||
title = if std::env::var("MOVE-TO").is_err() { "Config Example" } else { "Config Example - Other Process" };
|
||||
widget::background = Text! {
|
||||
txt = CONFIG.status().map_to_text();
|
||||
txt = CONFIG.status().map_to_txt();
|
||||
margin = 10;
|
||||
font_family = "monospace";
|
||||
align = Align::TOP_LEFT;
|
||||
|
|
|
@ -437,7 +437,7 @@ fn text_editor_window(is_open: ArcVar<bool>) -> WindowRoot {
|
|||
child_bottom = Text! {
|
||||
margin = (0, 4);
|
||||
align = Align::RIGHT;
|
||||
txt = editor.caret_status.map_to_text();
|
||||
txt = editor.caret_status.map_to_txt();
|
||||
}, 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ fn background_color_example(color: impl Var<Rgba>) -> impl UiNode {
|
|||
background_color = c.clone();
|
||||
size = (16, 16);
|
||||
},
|
||||
Text!(c.map_to_text()),
|
||||
Text!(c.map_to_txt()),
|
||||
];
|
||||
};
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ fn exclusive_mode() -> impl UiNode {
|
|||
tooltip = Tip!(Text!("Exclusive video mode"));
|
||||
|
||||
child = Text! {
|
||||
txt = WINDOW.vars().video_mode().map_to_text();
|
||||
txt = WINDOW.vars().video_mode().map_to_txt();
|
||||
txt_align = Align::CENTER;
|
||||
padding = 2;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{
|
||||
any::TypeId,
|
||||
collections::{hash_map, HashMap},
|
||||
mem,
|
||||
mem, ops,
|
||||
};
|
||||
|
||||
use crate::{shortcut::CommandShortcutExt, update::UpdatesTrace, widget::info::WidgetInfo, window::WindowId, APP};
|
||||
|
@ -424,6 +424,40 @@ impl Command {
|
|||
))
|
||||
}
|
||||
|
||||
/// Creates a preview event handler for the command.
|
||||
///
|
||||
/// This is similar to [`Event::on_pre_event`], but `handler` is only called if the command
|
||||
/// scope matches and a command subscription exists for the lifetime of the handler.
|
||||
///
|
||||
/// The `enabled` parameter defines the initial state of the command subscription, the subscription
|
||||
/// handle is available in the handler args.
|
||||
pub fn on_pre_event<H>(&self, enabled: bool, handler: H) -> EventHandle
|
||||
where
|
||||
H: AppHandler<AppCommandArgs>,
|
||||
{
|
||||
self.event().on_pre_event(CmdAppHandler {
|
||||
handler,
|
||||
handle: Arc::new(self.subscribe(enabled)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates an event handler for the command.
|
||||
///
|
||||
/// This is similar to [`Event::on_event`], but `handler` is only called if the command
|
||||
/// scope matches and a command subscription exists for the lifetime of the handler.
|
||||
///
|
||||
/// The `enabled` parameter defines the initial state of the command subscription, the subscription
|
||||
/// handle is available in the handler args.
|
||||
pub fn on_event<H>(&self, enabled: bool, handler: H) -> EventHandle
|
||||
where
|
||||
H: AppHandler<AppCommandArgs>,
|
||||
{
|
||||
self.event().on_event(CmdAppHandler {
|
||||
handler,
|
||||
handle: Arc::new(self.subscribe(enabled)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Update state vars, returns if the command must be retained.
|
||||
#[must_use]
|
||||
pub(crate) fn update_state(&self) -> bool {
|
||||
|
@ -474,6 +508,20 @@ impl PartialEq for Command {
|
|||
}
|
||||
impl Eq for Command {}
|
||||
|
||||
struct CmdAppHandler<H> {
|
||||
handler: H,
|
||||
handle: Arc<CommandHandle>,
|
||||
}
|
||||
impl<H: AppHandler<AppCommandArgs>> AppHandler<CommandArgs> for CmdAppHandler<H> {
|
||||
fn event(&mut self, args: &CommandArgs, handler_args: &AppHandlerArgs) {
|
||||
let args = AppCommandArgs {
|
||||
args: args.clone(),
|
||||
handle: self.handle.clone(),
|
||||
};
|
||||
self.handler.event(&args, handler_args);
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the scope of a [`Command`].
|
||||
///
|
||||
/// The command scope defines the targets of its event and the context of its metadata.
|
||||
|
@ -578,6 +626,44 @@ impl CommandArgs {
|
|||
}
|
||||
}
|
||||
|
||||
/// Arguments for [`Command::on_event`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppCommandArgs {
|
||||
/// The command args.
|
||||
pub args: CommandArgs,
|
||||
/// The command handle held by the event handler.
|
||||
pub handle: Arc<CommandHandle>,
|
||||
}
|
||||
impl ops::Deref for AppCommandArgs {
|
||||
type Target = CommandArgs;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.args
|
||||
}
|
||||
}
|
||||
impl AnyEventArgs for AppCommandArgs {
|
||||
fn clone_any(&self) -> Box<dyn AnyEventArgs> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> Instant {
|
||||
self.args.timestamp()
|
||||
}
|
||||
|
||||
fn delivery_list(&self, list: &mut UpdateDeliveryList) {
|
||||
self.args.delivery_list(list)
|
||||
}
|
||||
|
||||
fn propagation(&self) -> &EventPropagationHandle {
|
||||
self.args.propagation()
|
||||
}
|
||||
}
|
||||
impl EventArgs for AppCommandArgs {}
|
||||
|
||||
/// A handle to a [`Command`].
|
||||
///
|
||||
/// Holding the command handle indicates that the command is relevant in the current app state.
|
||||
|
|
|
@ -1416,7 +1416,7 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
|
|||
/// [`map`]: Var::map
|
||||
/// [`Txt`]: Txt
|
||||
/// [`ToTxt`]: ToTxt
|
||||
fn map_to_text(&self) -> Self::Map<Txt>
|
||||
fn map_to_txt(&self) -> Self::Map<Txt>
|
||||
where
|
||||
T: ToTxt,
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@ license = "Apache-2.0"
|
|||
[dependencies]
|
||||
zero-ui-var = { path = "../zero-ui-var" }
|
||||
zero-ui-app = { path = "../zero-ui-app" }
|
||||
zero-ui-ext-font = { path = "../zero-ui-ext-font" }
|
||||
zero-ui-wgt = { path = "../zero-ui-wgt" }
|
||||
zero-ui-wgt-container = { path = "../zero-ui-wgt-container" }
|
||||
zero-ui-wgt-style = { path = "../zero-ui-wgt-style" }
|
||||
|
@ -15,4 +16,5 @@ zero-ui-wgt-input = { path = "../zero-ui-wgt-input" }
|
|||
zero-ui-wgt-access = { path = "../zero-ui-wgt-access" }
|
||||
zero-ui-wgt-fill = { path = "../zero-ui-wgt-fill" }
|
||||
zero-ui-wgt-filter = { path = "../zero-ui-wgt-filter" }
|
||||
zero-ui-wgt-text = { path = "../zero-ui-wgt-text" }
|
||||
zero-ui-wgt-text = { path = "../zero-ui-wgt-text" }
|
||||
zero-ui-wgt-tooltip = { path = "../zero-ui-wgt-tooltip" }
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
zero_ui_wgt::enable_widget_macros!();
|
||||
|
||||
use std::ops;
|
||||
|
||||
use zero_ui_app::event::CommandParam;
|
||||
use zero_ui_var::ReadOnlyContextVar;
|
||||
use zero_ui_wgt::{border, corner_radius, is_disabled, prelude::*};
|
||||
|
@ -21,6 +23,8 @@ use zero_ui_wgt_input::{
|
|||
CursorIcon,
|
||||
};
|
||||
use zero_ui_wgt_style::{Style, StyleFn, StyleMix};
|
||||
use zero_ui_wgt_text::Text;
|
||||
use zero_ui_wgt_tooltip::{tooltip, tooltip_fn, Tip, TooltipArgs};
|
||||
|
||||
/// A clickable container.
|
||||
///
|
||||
|
@ -67,7 +71,8 @@ impl Button {
|
|||
|
||||
let on_click = wgt.property(property_id!(Self::on_click)).is_none();
|
||||
let on_disabled_click = wgt.property(property_id!(on_disabled_click)).is_none();
|
||||
if on_click || on_disabled_click {
|
||||
let tooltip = wgt.property(property_id!(tooltip)).is_none() && wgt.property(property_id!(tooltip_fn)).is_none();
|
||||
if on_click || on_disabled_click || tooltip {
|
||||
wgt.push_intrinsic(
|
||||
NestGroup::EVENT,
|
||||
"cmd-event",
|
||||
|
@ -106,6 +111,19 @@ impl Button {
|
|||
)
|
||||
.boxed();
|
||||
}
|
||||
if tooltip {
|
||||
child = self::tooltip_fn(
|
||||
child,
|
||||
merge_var!(cmd, CMD_TOOLTIP_FN_VAR, |cmd, tt_fn| {
|
||||
if tt_fn.is_nil() {
|
||||
WidgetFn::nil()
|
||||
} else {
|
||||
wgt_fn!(cmd, tt_fn, |tooltip| { tt_fn(CmdTooltipArgs { tooltip, cmd }) })
|
||||
}
|
||||
}),
|
||||
)
|
||||
.boxed();
|
||||
}
|
||||
child
|
||||
}),
|
||||
);
|
||||
|
@ -142,12 +160,60 @@ context_var! {
|
|||
/// Widget function used when `cmd` is set and `child` is not.
|
||||
pub static CMD_CHILD_FN_VAR: WidgetFn<Command> = WidgetFn::new(default_cmd_child_fn);
|
||||
|
||||
/// Widget function used when `cmd` is set and `tooltip_fn`, `tooltip` are not set.
|
||||
pub static CMD_TOOLTIP_FN_VAR: WidgetFn<CmdTooltipArgs> = WidgetFn::new(default_cmd_tooltip_fn);
|
||||
|
||||
static CMD_VAR: Option<Command> = None;
|
||||
}
|
||||
|
||||
/// Arguments for [`cmd_tooltip_fn`].
|
||||
///
|
||||
/// [`cmd_tooltip_fn`]: fn@cmd_tooltip_fn
|
||||
#[derive(Clone)]
|
||||
pub struct CmdTooltipArgs {
|
||||
/// The tooltip arguments.
|
||||
pub tooltip: TooltipArgs,
|
||||
/// The command.
|
||||
pub cmd: Command,
|
||||
}
|
||||
impl ops::Deref for CmdTooltipArgs {
|
||||
type Target = TooltipArgs;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.tooltip
|
||||
}
|
||||
}
|
||||
|
||||
/// Default [`CMD_CHILD_FN_VAR`].
|
||||
pub fn default_cmd_child_fn(cmd: Command) -> impl UiNode {
|
||||
zero_ui_wgt_text::Text!(cmd.name())
|
||||
Text!(cmd.name())
|
||||
}
|
||||
|
||||
/// Default [`CMD_TOOLTIP_FN_VAR`].
|
||||
pub fn default_cmd_tooltip_fn(args: CmdTooltipArgs) -> impl UiNode {
|
||||
let info = args.cmd.info();
|
||||
let has_info = info.map(|s| !s.is_empty());
|
||||
let shortcut = args.cmd.shortcut().map(|s| match s.first() {
|
||||
Some(s) => s.to_txt(),
|
||||
None => Txt::from(""),
|
||||
});
|
||||
let has_shortcut = shortcut.map(|s| !s.is_empty());
|
||||
Tip! {
|
||||
child = Text! {
|
||||
zero_ui_wgt::visibility = has_info.map_into();
|
||||
txt = info;
|
||||
};
|
||||
child_bottom = {
|
||||
insert: Text! {
|
||||
font_weight = zero_ui_ext_font::FontWeight::BOLD;
|
||||
zero_ui_wgt::visibility = has_shortcut.map_into();
|
||||
txt = shortcut;
|
||||
},
|
||||
spacing: 4,
|
||||
};
|
||||
|
||||
zero_ui_wgt::visibility = expr_var!((*#{has_info} || *#{has_shortcut}).into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the [`Command`] the button represents.
|
||||
|
@ -155,12 +221,15 @@ pub fn default_cmd_child_fn(cmd: Command) -> impl UiNode {
|
|||
/// When this is set the button widget sets these properties if they are not set:
|
||||
///
|
||||
/// * [`child`]: Set to an widget produced by [`cmd_child_fn`](fn@cmd_child_fn), by default is `Text!(cmd.name())`.
|
||||
/// * [`tooltip_fn`]: Set to a widget function provided by [`cmd_tooltip_fn`](fn@cmd_tooltip_fn), by default it
|
||||
/// shows the command info and first shortcut.
|
||||
/// * [`enabled`]: Set to `cmd.is_enabled()`.
|
||||
/// * [`visibility`]: Set to `cmd.has_handlers().into()`.
|
||||
/// * [`on_click`]: Set to a handler that notifies the command if `cmd.is_enabled()`.
|
||||
/// * [`on_disabled_click`]: Set to a handler that notifies the command if `!cmd.is_enabled()`.
|
||||
///
|
||||
/// [`child`]: struct@Button#child
|
||||
/// [`tooltip_fn`]: fn@tooltip_fn
|
||||
/// [`Command`]: zero_ui_app::event::Command
|
||||
/// [`enabled`]: fn@zero_ui_wgt::enabled
|
||||
/// [`visibility`]: fn@zero_ui_wgt::visibility
|
||||
|
@ -186,6 +255,14 @@ pub fn cmd_child_fn(child: impl UiNode, cmd_child: impl IntoVar<WidgetFn<Command
|
|||
with_context_var(child, CMD_CHILD_FN_VAR, cmd_child)
|
||||
}
|
||||
|
||||
/// Sets the widget function used to produce the button tooltip when [`cmd`] is set and tooltip is not.
|
||||
///
|
||||
/// [`cmd`]: fn@cmd
|
||||
#[property(CONTEXT, default(CMD_TOOLTIP_FN_VAR), widget_impl(Button))]
|
||||
pub fn cmd_tooltip_fn(child: impl UiNode, cmd_tooltip: impl IntoVar<WidgetFn<CmdTooltipArgs>>) -> impl UiNode {
|
||||
with_context_var(child, CMD_TOOLTIP_FN_VAR, cmd_tooltip)
|
||||
}
|
||||
|
||||
/// Sets the [`BASE_COLORS_VAR`] that is used to compute all background and border colors in the button style.
|
||||
#[property(CONTEXT, default(BASE_COLORS_VAR), widget_impl(DefaultStyle))]
|
||||
pub fn base_colors(child: impl UiNode, color: impl IntoVar<ColorPair>) -> impl UiNode {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use zero_ui_ext_clipboard::COPY_CMD;
|
||||
use zero_ui_wgt::prelude::*;
|
||||
use zero_ui_wgt_button::Button;
|
||||
use zero_ui_wgt_input::focus::FocusableMix;
|
||||
use zero_ui_wgt_menu::{
|
||||
self as menu,
|
||||
|
@ -9,7 +10,6 @@ use zero_ui_wgt_menu::{
|
|||
};
|
||||
use zero_ui_wgt_style::{Style, StyleFn, StyleMix};
|
||||
use zero_ui_wgt_text::{self as text, *};
|
||||
use zero_ui_wgt_button::Button;
|
||||
|
||||
/// Styleable read-only text widget that can be selected and copied to clipboard.
|
||||
#[widget($crate::selectable::SelectableText)]
|
||||
|
@ -70,10 +70,7 @@ impl DefaultStyle {
|
|||
/// [`DefaultStyle!`]: struct@DefaultStyle
|
||||
pub fn default_context_menu(args: menu::context::ContextMenuArgs) -> impl UiNode {
|
||||
let id = args.anchor_id;
|
||||
ContextMenu!(ui_vec![
|
||||
Button!(COPY_CMD.scoped(id)),
|
||||
Button!(text::cmd::SELECT_ALL_CMD.scoped(id)),
|
||||
])
|
||||
ContextMenu!(ui_vec![Button!(COPY_CMD.scoped(id)), Button!(text::cmd::SELECT_ALL_CMD.scoped(id)),])
|
||||
}
|
||||
|
||||
/// Selection toolbar set by the [`DefaultStyle!`].
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use zero_ui_ext_clipboard::{COPY_CMD, CUT_CMD, PASTE_CMD};
|
||||
use zero_ui_wgt::{align, is_disabled, margin, prelude::*};
|
||||
use zero_ui_wgt_access::{access_role, AccessRole};
|
||||
use zero_ui_wgt_button::Button;
|
||||
use zero_ui_wgt_data::{DataNoteLevel, DataNotes, DATA};
|
||||
use zero_ui_wgt_fill::foreground_highlight;
|
||||
use zero_ui_wgt_filter::{child_opacity, saturate};
|
||||
|
@ -18,7 +19,6 @@ use zero_ui_wgt_size_offset::{offset, y};
|
|||
use zero_ui_wgt_style::{Style, StyleFn, StyleMix};
|
||||
use zero_ui_wgt_text::{self as text, *};
|
||||
use zero_ui_wgt_undo::{undo_scope, UndoMix};
|
||||
use zero_ui_wgt_button::Button;
|
||||
|
||||
/// Simple text editor widget.
|
||||
///
|
||||
|
|
|
@ -433,6 +433,7 @@ pub fn access_tooltip_duration(child: impl UiNode, duration: impl IntoVar<Durati
|
|||
}
|
||||
|
||||
/// Arguments for tooltip widget functions.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TooltipArgs {
|
||||
/// ID of the widget the tooltip is anchored to.
|
||||
pub anchor_id: WidgetId,
|
||||
|
|
|
@ -83,7 +83,7 @@ impl<D: VarValue> ViewArgs<D> {
|
|||
/// Text! {
|
||||
/// font_size = 28;
|
||||
/// // bind data, same view will be used for all n > 0 values.
|
||||
/// txt = a.data().map_to_text();
|
||||
/// txt = a.data().map_to_txt();
|
||||
/// }
|
||||
/// } else {
|
||||
/// // finished view
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
//!
|
||||
//! A simple clickable container widget, it can be used by directly handling the click events or by setting it to
|
||||
//! operate a [`Command`].
|
||||
//!
|
||||
//!
|
||||
//! [`Command`]: crate::event::Command
|
||||
//!
|
||||
//!
|
||||
//! # Click Events
|
||||
//!
|
||||
//!
|
||||
//! The button widget implements the [`gesture::on_click`] event so you can use it directly, but like any
|
||||
//! other widget all events can be set. The example below demonstrates both ways of setting events.
|
||||
//!
|
||||
//!
|
||||
//! [`gesture::on_click`]: fn@crate::gesture::on_click
|
||||
//!
|
||||
//!
|
||||
//! ```
|
||||
//! use zero_ui::prelude::*;
|
||||
//!
|
||||
|
@ -36,16 +36,16 @@
|
|||
//! }
|
||||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! # Command
|
||||
//!
|
||||
//!
|
||||
//! Instead of handling events directly the button widget can be set to represents a command.
|
||||
//! If the [`cmd`](struct@Button#cmd) property is set the button widget will automatically set properties
|
||||
//! from command metadata, you can manually set some of these properties to override the command default.
|
||||
//!
|
||||
//!
|
||||
//! ```
|
||||
//! use zero_ui::prelude::*;
|
||||
//!
|
||||
//!
|
||||
//! # let _scope = APP.defaults();
|
||||
//! # let _ =
|
||||
//! Stack!(left_to_right, 5, ui_vec![
|
||||
|
@ -59,48 +59,66 @@
|
|||
//! ])
|
||||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//! The properties a command button sets are documented in the [`cmd`](struct@Button#cmd) property docs.
|
||||
//!
|
||||
//! <details>
|
||||
//! <summary>Equivalent command button.</summary>
|
||||
//!
|
||||
//! This example shows an equivalent command button implementation, for a single command.
|
||||
//! There are some differences, the real `cmd` is a variable so commands can dynamically change and
|
||||
//! the handlers also pass on the[`cmd_param`](struct@Button#cmd_param) if set.
|
||||
//!
|
||||
//! The properties a command button sets are documented in the [`cmd`](struct@Button#cmd) property docs.
|
||||
//! Of particular importance is the [`widget::visibility`], it is set so that the button is only visible if
|
||||
//! the command has any handlers, enabled or disabled, this is done because commands are considered irrelevant
|
||||
//! in the current context if they don't even have a disabled handler. The example above will only be
|
||||
//! visible if you set handlers for those commands.
|
||||
//!
|
||||
//! ```
|
||||
//! # use zero_ui::prelude::*;
|
||||
//! let cmd = zero_ui::clipboard::COPY_CMD;
|
||||
//! # let _scope = APP.defaults(); let _ =
|
||||
//! Button! {
|
||||
//! child = Text!(cmd.name());
|
||||
//! widget::enabled = cmd.is_enabled();
|
||||
//! widget::visibility = cmd.has_handlers().map_into();
|
||||
//! on_click = hn!(|args: &gesture::ClickArgs| {
|
||||
//! if cmd.is_enabled_value() {
|
||||
//! args.propagation().stop();
|
||||
//! cmd.notify();
|
||||
//! }
|
||||
//! });
|
||||
//! gesture::on_disabled_click = hn!(|args: &gesture::ClickArgs| {
|
||||
//! if !cmd.is_enabled_value() {
|
||||
//! args.propagation().stop();
|
||||
//! cmd.notify();
|
||||
//! }
|
||||
//! });
|
||||
//! # let _scope = APP.defaults();
|
||||
//! # fn cmd_btn_example() -> impl UiNode { widget::node::NilUiNode }
|
||||
//! # let _ =
|
||||
//! zero_ui::clipboard::COPY_CMD.on_event(true, app_hn!(|_, _| { println!("copy") })).perm();
|
||||
//! zero_ui::clipboard::PASTE_CMD.on_event(true, app_hn!(|_, _| { println!("paste") })).perm();
|
||||
//! Window! {
|
||||
//! child = cmd_btn_example();
|
||||
//! }
|
||||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//! </details>
|
||||
//!
|
||||
//!
|
||||
//! [`widget::visibility`]: fn@crate::widget::visibility
|
||||
//!
|
||||
//! # Style
|
||||
//!
|
||||
//! TODO, also mention BUTTON.cmd.
|
||||
//!
|
||||
//!
|
||||
//! The button widget is styleable and implements the [extend/replace] pattern, the [`extend_style`] property can be
|
||||
//! set in any parent widget or the button itself to add to the button style, the [`replace_style`] property
|
||||
//! can be set to fully replace the style.
|
||||
//!
|
||||
//! [extend/replace]: crate::style#extend-replace
|
||||
//! [`extend_style`]: fn@extend_style
|
||||
//! [`replace_style`]: fn@replace_style
|
||||
//!
|
||||
//! ## Base Colors
|
||||
//!
|
||||
//!
|
||||
//! The default style derive all colors from the [`base_colors`](fn@base_colors), so if you
|
||||
//! only want to change color of buttons you can use this property.
|
||||
//!
|
||||
//! The example below extends the button style to change the button color to red when it represents
|
||||
//! an specific command.
|
||||
//!
|
||||
//! ```
|
||||
//! use zero_ui::prelude::*;
|
||||
//! use zero_ui::button;
|
||||
//!
|
||||
//! # let _scope = APP.defaults(); let _ =
|
||||
//! Window! {
|
||||
//! button::extend_style = Style! {
|
||||
//! when *#{button::BUTTON.cmd()} == Some(window::cmd::CLOSE_CMD) {
|
||||
//! button::base_colors = color::ColorPair {
|
||||
//! // dark theme base
|
||||
//! dark: colors::BLACK.with_alpha(80.pct()).mix_normal(colors::RED),
|
||||
//! // light theme base
|
||||
//! light: colors::WHITE.with_alpha(80.pct()).mix_normal(colors::RED),
|
||||
//! };
|
||||
//! }
|
||||
//! };
|
||||
//! }
|
||||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//! # Full API
|
||||
//!
|
||||
//! See [`zero_ui_wgt_button`] for the full widget API.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
//! Style mix-in and types.
|
||||
//!
|
||||
//! # Extend/Replace
|
||||
//!
|
||||
//! A common pattern implemented by styleable widgets is to declare two properties, `extend_style` and `replace_style`.
|
||||
|
||||
pub use zero_ui_wgt_style::{style_fn, with_style_extension, Style, StyleArgs, StyleBuilder, StyleFn, StyleMix};
|
||||
|
|
Loading…
Reference in New Issue