mirror of
https://github.com/enso-org/enso.git
synced 2024-12-31 17:55:35 +03:00
Add dashboard button (#6474)
Closes #6399: Adding a button to the top bar in the project view to return to the dashboard. Note that this just fires a DOM event (see #6399). To test it, you can add an event listener: `document.addEventListener('show-dashboard', console.log)` https://user-images.githubusercontent.com/607786/235687669-ab04339f-0f07-439a-9cd3-59d96815edaa.mp4
This commit is contained in:
parent
cbc3568cf3
commit
8e62ed60e9
@ -172,6 +172,8 @@
|
||||
it is now referenced via the `Main` namespace instead of the project
|
||||
namespace,][6719] e.g. `Main.func1` instead of `MyProject.func1`. This makes
|
||||
it robust against project name changes.
|
||||
- [Added a button to return from an opened project back to the project
|
||||
dashboard.][6474]
|
||||
|
||||
[6279]: https://github.com/enso-org/enso/pull/6279
|
||||
[6421]: https://github.com/enso-org/enso/pull/6421
|
||||
@ -181,6 +183,7 @@
|
||||
[6663]: https://github.com/enso-org/enso/pull/6663
|
||||
[6752]: https://github.com/enso-org/enso/pull/6752
|
||||
[6719]: https://github.com/enso-org/enso/pull/6719
|
||||
[6474]: https://github.com/enso-org/enso/pull/6474
|
||||
|
||||
#### EnsoGL (rendering engine)
|
||||
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3265,6 +3265,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-frp",
|
||||
"ensogl-core",
|
||||
"ensogl-hardcoded-theme",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -276,7 +276,8 @@ pub fn register_views(app: &Application) {
|
||||
app.views.register::<ensogl_component::list_view::ListView<PlaceholderEntryType>>();
|
||||
|
||||
if enso_config::ARGS.groups.startup.options.platform.value == "web" {
|
||||
app.views.register::<ide_view::window_control_buttons::View>();
|
||||
app.views
|
||||
.register::<ide_view::project::project_view_top_bar::window_control_buttons::View>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,6 +329,16 @@ impl Model {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn show_dashboard(&self) {
|
||||
match enso_web::Event::new("show-dashboard") {
|
||||
Ok(event) =>
|
||||
if let Err(error) = enso_web::document.dispatch_event(&event) {
|
||||
error!("Failed to dispatch event to show the dashboard. {error:?}");
|
||||
},
|
||||
Err(error) => error!("Failed to create event to show the dashboard. {error:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -429,6 +439,8 @@ impl Project {
|
||||
view.set_read_only <+ view.toggle_read_only.map(f_!(model.toggle_read_only()));
|
||||
eval graph_view.execution_environment((env) model.execution_environment_changed(*env));
|
||||
eval_ graph_view.execution_environment_play_button_pressed( model.trigger_clean_live_execution());
|
||||
|
||||
eval_ view.go_to_dashboard_button_pressed (model.show_dashboard());
|
||||
}
|
||||
|
||||
let graph_controller = self.model.graph_controller.clone_ref();
|
||||
|
@ -12,7 +12,8 @@ use ensogl::display;
|
||||
use ensogl_component::toggle_button;
|
||||
use ensogl_component::toggle_button::ColorableShape;
|
||||
use ensogl_component::toggle_button::ToggleButton;
|
||||
use ensogl_hardcoded_theme as theme;
|
||||
use ensogl_hardcoded_theme::graph_editor::node::actions as theme;
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
@ -135,13 +136,6 @@ impl Icons {
|
||||
self.freeze.frp.set_read_only(read_only);
|
||||
self.skip.frp.set_read_only(read_only);
|
||||
}
|
||||
|
||||
fn set_color_scheme(&self, color_scheme: &toggle_button::ColorScheme) {
|
||||
self.visibility.frp.set_color_scheme(color_scheme);
|
||||
self.context_switch.set_color_scheme(color_scheme);
|
||||
self.freeze.frp.set_color_scheme(color_scheme);
|
||||
self.skip.frp.set_color_scheme(color_scheme);
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for Icons {
|
||||
@ -378,10 +372,10 @@ impl ActionBar {
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let model = Rc::new(Model::new(app));
|
||||
let frp = Frp::new();
|
||||
ActionBar { frp, model }.init_frp()
|
||||
ActionBar { frp, model }.init_frp(app)
|
||||
}
|
||||
|
||||
fn init_frp(self) -> Self {
|
||||
fn init_frp(self, app: &Application) -> Self {
|
||||
let network = &self.frp.network;
|
||||
let frp = &self.frp;
|
||||
let model = &self.model;
|
||||
@ -459,20 +453,11 @@ impl ActionBar {
|
||||
);
|
||||
}
|
||||
|
||||
use theme::graph_editor::node::actions;
|
||||
let color_scheme = toggle_button::ColorScheme {
|
||||
non_toggled: Some(model.styles.get_color(actions::button::non_toggled).into()),
|
||||
toggled: Some(model.styles.get_color(actions::button::toggled).into()),
|
||||
hovered: Some(model.styles.get_color(actions::button::hovered).into()),
|
||||
..default()
|
||||
};
|
||||
let scene = &app.display.default_scene;
|
||||
let context_switch_color_scheme = toggle_button::ColorScheme {
|
||||
non_toggled: Some(model.styles.get_color(actions::context_switch::non_toggled).into()),
|
||||
toggled: Some(model.styles.get_color(actions::context_switch::toggled).into()),
|
||||
hovered: Some(model.styles.get_color(actions::context_switch::hovered).into()),
|
||||
..default()
|
||||
toggled: Some(model.styles.get_color(theme::context_switch::toggled).into()),
|
||||
..toggle_button::default_color_scheme(&scene.style_sheet)
|
||||
};
|
||||
model.icons.set_color_scheme(&color_scheme);
|
||||
model.icons.context_switch.set_color_scheme(&context_switch_color_scheme);
|
||||
|
||||
frp.show_on_hover.emit(true);
|
||||
|
@ -146,7 +146,8 @@ impl Button {
|
||||
/// Constructs a new button for toggling the editor's view mode.
|
||||
pub fn new(app: &Application) -> Button {
|
||||
let scene = &app.display.default_scene;
|
||||
let styles = StyleWatchFrp::new(&scene.style_sheet);
|
||||
let style_sheet = &scene.style_sheet;
|
||||
let styles = StyleWatchFrp::new(style_sheet);
|
||||
let frp = Frp::new();
|
||||
let network = &frp.network;
|
||||
|
||||
@ -154,7 +155,6 @@ impl Button {
|
||||
.with_placement(tooltip::Placement::Left);
|
||||
let button = ToggleButton::<icon::Shape>::new(app, tooltip_style);
|
||||
scene.layers.panel.add(&button);
|
||||
button.set_visibility(true);
|
||||
button.frp.set_size(Vector2(32.0, 32.0));
|
||||
|
||||
frp::extend! { network
|
||||
@ -179,21 +179,20 @@ impl Button {
|
||||
// === Color ===
|
||||
|
||||
use ensogl_hardcoded_theme::graph_editor::profiling_button as button_theme;
|
||||
let non_toggled_color = styles.get_color(button_theme::non_toggled);
|
||||
let toggled_color = styles.get_color(button_theme::toggled);
|
||||
let hovered_color = styles.get_color(button_theme::hovered);
|
||||
let toggled_hovered_color = styles.get_color(button_theme::toggled_hovered);
|
||||
init_color_scheme <- source::<()>();
|
||||
button.set_color_scheme <+ all_with5(&non_toggled_color,&toggled_color,&hovered_color
|
||||
,&toggled_hovered_color,&init_color_scheme
|
||||
,|&non_toggled,&toggled,&hovered,&toggled_hovered,_|
|
||||
button.set_color_scheme <+ all_with3(
|
||||
&toggled_color,
|
||||
&toggled_hovered_color,
|
||||
&init_color_scheme,
|
||||
f!([style_sheet] (&toggled, &toggled_hovered, _)
|
||||
toggle_button::ColorScheme {
|
||||
non_toggled : Some(non_toggled.into()),
|
||||
toggled : Some(toggled.into()),
|
||||
hovered : Some(hovered.into()),
|
||||
toggled_hovered : Some(toggled_hovered.into()),
|
||||
..default()
|
||||
..toggle_button::default_color_scheme(&style_sheet)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -41,12 +41,13 @@ pub fn init_frp(frp: &Frp, model: &GraphEditorModelWithNetwork) {
|
||||
// === Layout ===
|
||||
|
||||
init <- source::<()>();
|
||||
size_update <- all(init,selector.size,inputs.space_for_window_buttons);
|
||||
eval size_update ([model]((_,size,gap_size)) {
|
||||
size_update <- all(init, selector.size, inputs.graph_editor_top_bar_offset_x);
|
||||
eval size_update ([model] ((_, size, graph_editor_top_bar_offset_x)) {
|
||||
let y_offset = MACOS_TRAFFIC_LIGHTS_VERTICAL_CENTER;
|
||||
let traffic_light_width = traffic_lights_gap_width();
|
||||
|
||||
let execution_environment_selector_x = gap_size.x + traffic_light_width;
|
||||
let execution_environment_selector_x =
|
||||
graph_editor_top_bar_offset_x + traffic_light_width;
|
||||
model.execution_environment_selector.set_x(execution_environment_selector_x);
|
||||
let breadcrumb_gap_width =
|
||||
execution_environment_selector_x + size.x + TOP_BAR_ITEM_MARGIN;
|
||||
|
@ -111,7 +111,8 @@ const MACOS_TRAFFIC_LIGHTS_CONTENT_WIDTH: f32 = 52.0;
|
||||
const MACOS_TRAFFIC_LIGHTS_CONTENT_HEIGHT: f32 = 12.0;
|
||||
/// Horizontal and vertical offset between traffic lights and window border
|
||||
const MACOS_TRAFFIC_LIGHTS_SIDE_OFFSET: f32 = 13.0;
|
||||
const MACOS_TRAFFIC_LIGHTS_VERTICAL_CENTER: f32 =
|
||||
/// The vertical center of the traffic lights, relative to the window border.
|
||||
pub const MACOS_TRAFFIC_LIGHTS_VERTICAL_CENTER: f32 =
|
||||
-MACOS_TRAFFIC_LIGHTS_SIDE_OFFSET - MACOS_TRAFFIC_LIGHTS_CONTENT_HEIGHT / 2.0;
|
||||
const MAX_ZOOM: f32 = 1.0;
|
||||
/// Space between items in the top bar.
|
||||
@ -124,7 +125,7 @@ fn traffic_lights_gap_width() -> f32 {
|
||||
if is_macos && !ARGS.groups.window.options.frame.value {
|
||||
MACOS_TRAFFIC_LIGHTS_CONTENT_WIDTH + MACOS_TRAFFIC_LIGHTS_SIDE_OFFSET
|
||||
} else {
|
||||
TOP_BAR_ITEM_MARGIN
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,7 +452,10 @@ ensogl::define_endpoints_2! {
|
||||
|
||||
|
||||
// === Layout ===
|
||||
space_for_window_buttons (Vector2<f32>),
|
||||
|
||||
/// The offset in the x-axis at which the part of the top bar of the graph editor should
|
||||
/// start.
|
||||
graph_editor_top_bar_offset_x (f32),
|
||||
|
||||
|
||||
// === Read-only mode ===
|
||||
|
@ -38,7 +38,6 @@ pub mod project_list;
|
||||
pub mod root;
|
||||
pub mod searcher;
|
||||
pub mod status_bar;
|
||||
pub mod window_control_buttons;
|
||||
|
||||
pub use ide_view_component_browser as component_browser;
|
||||
pub use ide_view_documentation as documentation;
|
||||
|
@ -24,12 +24,19 @@ use ensogl::application::shortcut;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display;
|
||||
use ensogl::system::web;
|
||||
use ensogl::system::web::dom;
|
||||
use ensogl::DEPRECATED_Animation;
|
||||
use ensogl_component::text;
|
||||
use ensogl_component::text::selection::Selection;
|
||||
use ensogl_hardcoded_theme::Theme;
|
||||
use ide_view_graph_editor::NodeSource;
|
||||
use project_view_top_bar::ProjectViewTopBar;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub mod project_view_top_bar;
|
||||
|
||||
|
||||
|
||||
@ -127,6 +134,7 @@ ensogl::define_endpoints! {
|
||||
fullscreen_visualization_shown (bool),
|
||||
drop_files_enabled (bool),
|
||||
debug_mode (bool),
|
||||
go_to_dashboard_button_pressed (),
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,22 +146,20 @@ ensogl::define_endpoints! {
|
||||
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
struct Model {
|
||||
app: Application,
|
||||
display_object: display::object::Instance,
|
||||
/// These buttons are present only in a cloud environment.
|
||||
window_control_buttons: Immutable<Option<crate::window_control_buttons::View>>,
|
||||
graph_editor: Rc<GraphEditor>,
|
||||
searcher: component_browser::View,
|
||||
code_editor: code_editor::View,
|
||||
fullscreen_vis: Rc<RefCell<Option<visualization::fullscreen::Panel>>>,
|
||||
project_list: Rc<ProjectList>,
|
||||
debug_mode_popup: debug_mode_popup::View,
|
||||
popup: popup::View,
|
||||
app: Application,
|
||||
display_object: display::object::Instance,
|
||||
project_view_top_bar: ProjectViewTopBar,
|
||||
graph_editor: Rc<GraphEditor>,
|
||||
searcher: component_browser::View,
|
||||
code_editor: code_editor::View,
|
||||
fullscreen_vis: Rc<RefCell<Option<visualization::fullscreen::Panel>>>,
|
||||
project_list: Rc<ProjectList>,
|
||||
debug_mode_popup: debug_mode_popup::View,
|
||||
popup: popup::View,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
fn new(app: &Application) -> Self {
|
||||
let scene = &app.display.default_scene;
|
||||
let display_object = display::object::Instance::new();
|
||||
let searcher = app.new_view::<component_browser::View>();
|
||||
let graph_editor = app.new_view::<GraphEditor>();
|
||||
@ -161,14 +167,7 @@ impl Model {
|
||||
let fullscreen_vis = default();
|
||||
let debug_mode_popup = debug_mode_popup::View::new(app);
|
||||
let popup = popup::View::new(app);
|
||||
let runs_in_web = ARGS.groups.startup.options.platform.value == "web";
|
||||
let window_control_buttons = runs_in_web.as_some_from(|| {
|
||||
let window_control_buttons = app.new_view::<crate::window_control_buttons::View>();
|
||||
display_object.add_child(&window_control_buttons);
|
||||
scene.layers.panel.add(&window_control_buttons);
|
||||
window_control_buttons
|
||||
});
|
||||
let window_control_buttons = Immutable(window_control_buttons);
|
||||
let project_view_top_bar = ProjectViewTopBar::new(app);
|
||||
let project_list = Rc::new(ProjectList::new(app));
|
||||
|
||||
display_object.add_child(&graph_editor);
|
||||
@ -176,6 +175,7 @@ impl Model {
|
||||
display_object.add_child(&searcher);
|
||||
display_object.add_child(&debug_mode_popup);
|
||||
display_object.add_child(&popup);
|
||||
display_object.add_child(&project_view_top_bar);
|
||||
display_object.remove_child(&searcher);
|
||||
|
||||
let app = app.clone_ref();
|
||||
@ -183,7 +183,7 @@ impl Model {
|
||||
Self {
|
||||
app,
|
||||
display_object,
|
||||
window_control_buttons,
|
||||
project_view_top_bar,
|
||||
graph_editor,
|
||||
searcher,
|
||||
code_editor,
|
||||
@ -263,12 +263,18 @@ impl Model {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_dom_shape_changed(&self, shape: &dom::shape::Shape) {
|
||||
// Top buttons must always stay in top-left corner.
|
||||
if let Some(window_control_buttons) = &*self.window_control_buttons {
|
||||
let pos = Vector2(-shape.width, shape.height) / 2.0;
|
||||
window_control_buttons.set_xy(pos);
|
||||
}
|
||||
fn position_project_view_top_bar(
|
||||
&self,
|
||||
scene_shape: &display::scene::Shape,
|
||||
project_view_top_bar_size: Vector2,
|
||||
) {
|
||||
let top_left = Vector2(-scene_shape.width, scene_shape.height) / 2.0;
|
||||
let project_view_top_bar_origin = Vector2(
|
||||
0.0,
|
||||
crate::graph_editor::MACOS_TRAFFIC_LIGHTS_VERTICAL_CENTER
|
||||
- project_view_top_bar_size.y / 2.0,
|
||||
);
|
||||
self.project_view_top_bar.set_xy(top_left + project_view_top_bar_origin);
|
||||
}
|
||||
|
||||
fn on_close_clicked(&self) {
|
||||
@ -368,6 +374,7 @@ impl View {
|
||||
let frp = Frp::new();
|
||||
let network = &frp.network;
|
||||
let searcher = &model.searcher.frp();
|
||||
let project_view_top_bar = &model.project_view_top_bar;
|
||||
let graph = &model.graph_editor.frp;
|
||||
let code_editor = &model.code_editor;
|
||||
let project_list = &model.project_list;
|
||||
@ -378,27 +385,36 @@ impl View {
|
||||
model.set_style(theme);
|
||||
let input_change_delay = frp::io::timer::Timeout::new(network);
|
||||
|
||||
if let Some(window_control_buttons) = &*model.window_control_buttons {
|
||||
let initial_size = &window_control_buttons.size.value();
|
||||
model.graph_editor.input.space_for_window_buttons(initial_size);
|
||||
frp::extend! { network
|
||||
graph.space_for_window_buttons <+ window_control_buttons.size;
|
||||
eval_ window_control_buttons.close (model.on_close_clicked());
|
||||
eval_ window_control_buttons.fullscreen (model.on_fullscreen_clicked());
|
||||
}
|
||||
}
|
||||
|
||||
let shape = scene.shape().clone_ref();
|
||||
|
||||
frp::extend! { network
|
||||
init <- source::<()>();
|
||||
shape <- all(shape, init)._0();
|
||||
eval shape ((shape) model.on_dom_shape_changed(shape));
|
||||
init <- source_();
|
||||
|
||||
eval_ frp.show_graph_editor(model.show_graph_editor());
|
||||
eval_ frp.hide_graph_editor(model.hide_graph_editor());
|
||||
|
||||
|
||||
// === Project View Top Bar ===
|
||||
|
||||
let window_control_buttons = &project_view_top_bar.window_control_buttons;
|
||||
eval_ window_control_buttons.close (model.on_close_clicked());
|
||||
eval_ window_control_buttons.fullscreen (model.on_fullscreen_clicked());
|
||||
let go_to_dashboard_button = &project_view_top_bar.go_to_dashboard_button;
|
||||
frp.source.go_to_dashboard_button_pressed <+
|
||||
go_to_dashboard_button.is_pressed.on_true();
|
||||
|
||||
let project_view_top_bar_display_object = project_view_top_bar.display_object();
|
||||
_eval <- all_with3(
|
||||
&init,
|
||||
scene.shape(),
|
||||
&project_view_top_bar_display_object.on_resized,
|
||||
f!((_, scene_shape, project_view_top_bar_size)
|
||||
model.position_project_view_top_bar(scene_shape, *project_view_top_bar_size)
|
||||
)
|
||||
);
|
||||
project_view_top_bar_width <-
|
||||
project_view_top_bar_display_object.on_resized.map(|new_size| new_size.x);
|
||||
graph.graph_editor_top_bar_offset_x <+ project_view_top_bar_width;
|
||||
|
||||
|
||||
// === Read-only mode ===
|
||||
|
||||
graph.set_read_only <+ frp.set_read_only;
|
||||
|
72
app/gui/view/src/project/project_view_top_bar.rs
Normal file
72
app/gui/view/src/project/project_view_top_bar.rs
Normal file
@ -0,0 +1,72 @@
|
||||
//! Defines a UI container for the window control buttons and the "go to dashboard" button. This is
|
||||
//! merely here to make use of the auto-layout functionality.
|
||||
|
||||
use ensogl::prelude::*;
|
||||
|
||||
use enso_config::ARGS;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display;
|
||||
|
||||
|
||||
|
||||
mod go_to_dashboard_button;
|
||||
pub mod window_control_buttons;
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
|
||||
/// The gap in pixels between the various components of the project view top bar.
|
||||
const GAP: f32 = 16.0;
|
||||
/// The padding left of the project view top bar.
|
||||
const PADDING_LEFT: f32 = 19.0;
|
||||
|
||||
|
||||
|
||||
// ============================
|
||||
// === Project View Top Bar ===
|
||||
// ============================
|
||||
|
||||
/// Defines a UI container for the window control buttons and the "go to dashboard" button. This is
|
||||
/// merely here to make use of the auto-layout functionality.
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct ProjectViewTopBar {
|
||||
root: display::object::Instance,
|
||||
/// These buttons are only visible in a cloud environment.
|
||||
pub window_control_buttons: window_control_buttons::View,
|
||||
pub go_to_dashboard_button: go_to_dashboard_button::View,
|
||||
}
|
||||
|
||||
impl ProjectViewTopBar {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let root = display::object::Instance::new_named("ProjectViewTopBar");
|
||||
let window_control_buttons = app.new_view::<window_control_buttons::View>();
|
||||
let go_to_dashboard_button = go_to_dashboard_button::View::new(app);
|
||||
|
||||
if ARGS.groups.startup.options.platform.value == "web" {
|
||||
root.add_child(&window_control_buttons);
|
||||
}
|
||||
root.add_child(&go_to_dashboard_button);
|
||||
root.use_auto_layout()
|
||||
.set_gap((GAP, 0.0))
|
||||
.set_padding_left(PADDING_LEFT)
|
||||
// We use `GAP` as the right padding since it delimits the space to the part of the top
|
||||
// bar that's defined in the graph editor.
|
||||
.set_padding_right(GAP)
|
||||
.set_children_alignment_center();
|
||||
|
||||
app.display.default_scene.layers.panel.add(&root);
|
||||
|
||||
Self { root, window_control_buttons, go_to_dashboard_button }
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for ProjectViewTopBar {
|
||||
fn display_object(&self) -> &display::object::Instance {
|
||||
&self.root
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
//! Provides a button to switch back from the project view to the dashboard.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use ensogl::application::tooltip;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display;
|
||||
use ensogl::display::style;
|
||||
use ensogl_component::toggle_button;
|
||||
use ensogl_component::toggle_button::ToggleButton;
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
|
||||
/// The width and height of the button.
|
||||
pub const SIZE: f32 = 16.0;
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Icon ===
|
||||
// ============
|
||||
|
||||
/// Defines an icon for returning to the dashboard. It looks like a hamburger button.
|
||||
mod icon {
|
||||
use super::*;
|
||||
|
||||
use ensogl::data::color;
|
||||
use ensogl_component::toggle_button::ColorableShape;
|
||||
|
||||
ensogl::shape! {
|
||||
(style: Style, color_rgba: Vector4<f32>) {
|
||||
let fill_color = Var::<color::Rgba>::from(color_rgba);
|
||||
let width = Var::<Pixels>::from("input_size.x");
|
||||
let height = Var::<Pixels>::from("input_size.y");
|
||||
let unit = &width / SIZE;
|
||||
let mid_bar = Rect((&unit * 12.0, &unit * 3.0)).corners_radius(&unit);
|
||||
let top_bar = mid_bar.translate_y(&unit * -5.0);
|
||||
let bottom_bar = mid_bar.translate_y(&unit * 5.0);
|
||||
let all_bars = top_bar + mid_bar + bottom_bar;
|
||||
let shape = all_bars.fill(fill_color);
|
||||
let hover_area = Rect((&width, &height)).fill(INVISIBLE_HOVER_COLOR);
|
||||
(shape + hover_area).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorableShape for Shape {
|
||||
fn set_color(&self, color: color::Rgba) {
|
||||
self.color_rgba.set(Vector4::new(color.red, color.green, color.blue, color.alpha));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === View ===
|
||||
// ============
|
||||
|
||||
/// Provides a button to switch back from the project view to the dashboard.
|
||||
#[derive(Debug, Clone, CloneRef, Deref)]
|
||||
pub struct View {
|
||||
button: ToggleButton<icon::Shape>,
|
||||
}
|
||||
|
||||
impl View {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let scene = &app.display.default_scene;
|
||||
|
||||
let tooltip_style = tooltip::Style::set_label("Dashboard".to_owned())
|
||||
.with_placement(tooltip::Placement::Right);
|
||||
let button = ToggleButton::<icon::Shape>::new(app, tooltip_style);
|
||||
scene.layers.panel.add(&button);
|
||||
|
||||
button.set_color_scheme(Self::color_scheme(&scene.style_sheet));
|
||||
button.set_size(Vector2(SIZE, SIZE));
|
||||
|
||||
Self { button }
|
||||
}
|
||||
|
||||
fn color_scheme(style_sheet: &style::Sheet) -> toggle_button::ColorScheme {
|
||||
let default_color_scheme = toggle_button::default_color_scheme(style_sheet);
|
||||
toggle_button::ColorScheme {
|
||||
// Make it look like a normal button (as opposed to a toggle button) by not having a
|
||||
// toggled state visually.
|
||||
toggled: default_color_scheme.non_toggled,
|
||||
toggled_hovered: default_color_scheme.hovered,
|
||||
..default_color_scheme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for View {
|
||||
fn display_object(&self) -> &display::object::Instance {
|
||||
self.button.display_object()
|
||||
}
|
||||
}
|
@ -0,0 +1,199 @@
|
||||
//! The component with buttons in the top left corner. See [[View]].
|
||||
|
||||
use ensogl::display::shape::*;
|
||||
use ensogl::prelude::*;
|
||||
|
||||
use enso_frp as frp;
|
||||
use ensogl::application;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display;
|
||||
use ensogl::display::object::ObjectOps;
|
||||
use ensogl::shape;
|
||||
use ensogl_hardcoded_theme::application::window_control_buttons as theme;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub mod close;
|
||||
pub mod fullscreen;
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Shapes ===
|
||||
// ==============
|
||||
|
||||
mod shape {
|
||||
use super::*;
|
||||
shape! {
|
||||
alignment = center;
|
||||
(style: Style) {
|
||||
Plane().fill(INVISIBLE_HOVER_COLOR).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Model ===
|
||||
// =============
|
||||
|
||||
/// An internal model of Status Bar component
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
pub struct Model {
|
||||
app: Application,
|
||||
display_object: display::object::Instance,
|
||||
shape: shape::View,
|
||||
close: close::View,
|
||||
fullscreen: fullscreen::View,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let app = app.clone_ref();
|
||||
let display_object = display::object::Instance::new_named("WindowControlButtons");
|
||||
|
||||
ensogl::shapes_order_dependencies! {
|
||||
app.display.default_scene => {
|
||||
shape -> close::shape;
|
||||
shape -> fullscreen::shape;
|
||||
}
|
||||
};
|
||||
let close = close::View::new(&app);
|
||||
display_object.add_child(&close);
|
||||
|
||||
let fullscreen = fullscreen::View::new(&app);
|
||||
display_object.add_child(&fullscreen);
|
||||
|
||||
let shape = shape::View::new();
|
||||
display_object.add_child(&shape);
|
||||
|
||||
app.display.default_scene.layers.panel.add(&display_object);
|
||||
|
||||
Self { app, display_object, shape, close, fullscreen }
|
||||
}
|
||||
|
||||
/// Updates positions of the buttons and sizes of the mouse area.
|
||||
pub fn set_layout(&self, spacing: f32) {
|
||||
let close_size = self.close.size.value();
|
||||
let fullscreen_size = self.fullscreen.size.value();
|
||||
let fullscreen_offset = Vector2(close_size.x + spacing, 0.0);
|
||||
self.fullscreen.set_xy(fullscreen_offset);
|
||||
let width = fullscreen_offset.x + fullscreen_size.x;
|
||||
let height = max(close_size.y, fullscreen_size.y);
|
||||
let size = Vector2(width, height);
|
||||
self.shape.set_size(size);
|
||||
self.display_object.set_size(size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===========
|
||||
// === FRP ===
|
||||
// ===========
|
||||
|
||||
ensogl::define_endpoints! {
|
||||
Input {
|
||||
enabled (bool),
|
||||
}
|
||||
Output {
|
||||
close(),
|
||||
fullscreen(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === View ===
|
||||
// ============
|
||||
|
||||
/// The Top Buttons Panel component.
|
||||
///
|
||||
/// The panel contains two buttons: one for closing IDE and one for toggling the fullscreen mode.
|
||||
/// The panel is meant to be displayed only when IDE runs in a cloud environment.
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
pub struct View {
|
||||
#[allow(missing_docs)]
|
||||
pub frp: Frp,
|
||||
model: Model,
|
||||
style: StyleWatchFrp,
|
||||
}
|
||||
|
||||
impl View {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let frp = Frp::new();
|
||||
let model = Model::new(app);
|
||||
let network = &frp.network;
|
||||
|
||||
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||
let radius = style.get_number(theme::radius);
|
||||
let spacing = style.get_number(theme::spacing);
|
||||
|
||||
frp::extend! { network
|
||||
// Layout
|
||||
button_size <- radius.map(|&r| Vector2(2.0 * r, 2.0 * r));
|
||||
model.close.set_size <+ button_size;
|
||||
model.fullscreen.set_size <+ button_size;
|
||||
button_resized <- any_(&model.close.size, &model.fullscreen.size);
|
||||
_eval <- all_with(&button_resized, &spacing,
|
||||
f!((_, spacing) model.set_layout(*spacing))
|
||||
);
|
||||
|
||||
// Handle the panel-wide hover
|
||||
mouse_near_buttons <- bool(
|
||||
&model.shape.events_deprecated.mouse_out,
|
||||
&model.shape.events_deprecated.mouse_over
|
||||
);
|
||||
mouse_on_any_buttton <- model.close.is_hovered.or(&model.fullscreen.is_hovered);
|
||||
mouse_nearby <- mouse_near_buttons.or(&mouse_on_any_buttton);
|
||||
model.close.mouse_nearby <+ mouse_nearby;
|
||||
model.fullscreen.mouse_nearby <+ mouse_nearby;
|
||||
|
||||
// === Handle buttons' clicked events ===
|
||||
frp.source.close <+ model.close.clicked;
|
||||
frp.source.fullscreen <+ model.fullscreen.clicked;
|
||||
}
|
||||
|
||||
model.set_layout(spacing.value());
|
||||
|
||||
Self { frp, model, style }
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for View {
|
||||
fn display_object(&self) -> &display::object::Instance {
|
||||
&self.model.display_object
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for View {
|
||||
type Target = Frp;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.frp
|
||||
}
|
||||
}
|
||||
|
||||
impl FrpNetworkProvider for View {
|
||||
fn network(&self) -> &frp::Network {
|
||||
&self.frp.network
|
||||
}
|
||||
}
|
||||
|
||||
impl application::View for View {
|
||||
fn label() -> &'static str {
|
||||
"TopButtons"
|
||||
}
|
||||
fn new(app: &Application) -> Self {
|
||||
View::new(app)
|
||||
}
|
||||
fn app(&self) -> &Application {
|
||||
&self.model.app
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ pub mod shape {
|
||||
use super::*;
|
||||
|
||||
ensogl::shape! {
|
||||
alignment = center;
|
||||
(style: Style, background_color: Vector4<f32>, icon_color: Vector4<f32>) {
|
||||
let size = Var::canvas_size();
|
||||
let radius = Min::min(size.x(),size.y()) / 2.0;
|
@ -20,7 +20,6 @@ pub use ensogl_hardcoded_theme::application::window_control_buttons::fullscreen
|
||||
pub mod shape {
|
||||
use super::*;
|
||||
ensogl::shape! {
|
||||
alignment = center;
|
||||
(style: Style, background_color: Vector4<f32>, icon_color: Vector4<f32>) {
|
||||
let size = Var::canvas_size();
|
||||
let radius = Min::min(size.x(),size.y()) / 2.0;
|
@ -1,301 +0,0 @@
|
||||
//! The component with buttons in the top left corner. See [[View]].
|
||||
|
||||
use ensogl::display::shape::*;
|
||||
use ensogl::prelude::*;
|
||||
|
||||
use enso_frp as frp;
|
||||
use ensogl::application;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display;
|
||||
use ensogl::display::object::ObjectOps;
|
||||
use ensogl::shape;
|
||||
use ensogl_hardcoded_theme::application::window_control_buttons as theme;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub mod close;
|
||||
pub mod fullscreen;
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Shapes ===
|
||||
// ==============
|
||||
|
||||
mod shape {
|
||||
use super::*;
|
||||
shape! {
|
||||
alignment = center;
|
||||
(style: Style) {
|
||||
Plane().fill(INVISIBLE_HOVER_COLOR).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Layout ===
|
||||
// ==============
|
||||
|
||||
/// Information on how to layout shapes in the top buttons panel, as defined in the theme.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct LayoutParams<T> {
|
||||
pub spacing: T,
|
||||
pub padding_left: T,
|
||||
pub padding_top: T,
|
||||
pub padding_right: T,
|
||||
pub padding_bottom: T,
|
||||
}
|
||||
|
||||
impl Default for LayoutParams<f32> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
spacing: 8.0,
|
||||
padding_left: 13.0,
|
||||
padding_top: 13.0,
|
||||
padding_right: 13.0,
|
||||
padding_bottom: 13.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> LayoutParams<T> {
|
||||
/// Applies a given function over all stored values and return layout with resulting values.
|
||||
pub fn map<U>(&self, f: impl Fn(&T) -> U) -> LayoutParams<U> {
|
||||
LayoutParams {
|
||||
spacing: f(&self.spacing),
|
||||
padding_left: f(&self.padding_left),
|
||||
padding_top: f(&self.padding_top),
|
||||
padding_right: f(&self.padding_right),
|
||||
padding_bottom: f(&self.padding_bottom),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LayoutParams<frp::Sampler<f32>> {
|
||||
/// Get layout from theme. Each layout parameter will be an frp sampler.
|
||||
pub fn from_theme(style: &StyleWatchFrp) -> Self {
|
||||
let default = LayoutParams::default();
|
||||
let spacing = style.get_number_or(theme::spacing, default.spacing);
|
||||
let padding_left = style.get_number_or(theme::padding::left, default.padding_left);
|
||||
let padding_top = style.get_number_or(theme::padding::top, default.padding_top);
|
||||
let padding_right = style.get_number_or(theme::padding::right, default.padding_right);
|
||||
let padding_bottom = style.get_number_or(theme::padding::bottom, default.padding_bottom);
|
||||
Self { spacing, padding_left, padding_top, padding_right, padding_bottom }
|
||||
}
|
||||
|
||||
/// Take values from the parameters' samplers.
|
||||
pub fn value(&self) -> LayoutParams<f32> {
|
||||
self.map(|sampler| sampler.value())
|
||||
}
|
||||
|
||||
/// Join all member frp streams into a single stream with aggregated values.
|
||||
pub fn flatten(&self, network: &frp::Network) -> frp::Stream<LayoutParams<f32>> {
|
||||
/// Helper method that puts back LayoutParams from its fields.
|
||||
/// Be careful, as the arguments must be in the same order as they are in `all_with5`
|
||||
/// invocation below.
|
||||
// We intentionally take references to f32 for seamless usage in FRP.
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
fn to_layout(
|
||||
spacing: &f32,
|
||||
padding_left: &f32,
|
||||
padding_top: &f32,
|
||||
padding_right: &f32,
|
||||
padding_bottom: &f32,
|
||||
) -> LayoutParams<f32> {
|
||||
let ret =
|
||||
LayoutParams { spacing, padding_left, padding_top, padding_right, padding_bottom };
|
||||
ret.map(|v| **v)
|
||||
}
|
||||
|
||||
network.all_with5(
|
||||
"TopButtonsLayoutStyle",
|
||||
&self.spacing,
|
||||
&self.padding_left,
|
||||
&self.padding_top,
|
||||
&self.padding_right,
|
||||
&self.padding_bottom,
|
||||
to_layout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Model ===
|
||||
// =============
|
||||
|
||||
/// An internal model of Status Bar component
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
pub struct Model {
|
||||
app: Application,
|
||||
display_object: display::object::Instance,
|
||||
shape: shape::View,
|
||||
close: close::View,
|
||||
fullscreen: fullscreen::View,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let app = app.clone_ref();
|
||||
let display_object = display::object::Instance::new();
|
||||
|
||||
ensogl::shapes_order_dependencies! {
|
||||
app.display.default_scene => {
|
||||
shape -> close::shape;
|
||||
shape -> fullscreen::shape;
|
||||
}
|
||||
};
|
||||
let close = close::View::new(&app);
|
||||
display_object.add_child(&close);
|
||||
|
||||
let fullscreen = fullscreen::View::new(&app);
|
||||
display_object.add_child(&fullscreen);
|
||||
|
||||
let shape = shape::View::new();
|
||||
display_object.add_child(&shape);
|
||||
|
||||
Self { app, display_object, shape, close, fullscreen }
|
||||
}
|
||||
|
||||
/// Updates positions of the buttons and sizes of the mouse area.
|
||||
/// Returns the new size of the panel (being also the size of mouse area).
|
||||
pub fn set_layout(&self, layout: LayoutParams<f32>) -> Vector2 {
|
||||
let LayoutParams { spacing, padding_left, padding_top, padding_right, padding_bottom } =
|
||||
layout;
|
||||
let close_size = self.close.size.value();
|
||||
let fullscreen_size = self.fullscreen.size.value();
|
||||
let padding_offset = Vector2(padding_left, -padding_top);
|
||||
let origin_offset = |size: Vector2| Vector2(size.x / 2.0, -size.y / 2.0);
|
||||
|
||||
self.close.set_xy(padding_offset + origin_offset(close_size));
|
||||
let fullscreen_x = padding_left + close_size.x + spacing;
|
||||
self.fullscreen
|
||||
.set_xy(Vector2(fullscreen_x, -padding_top) + origin_offset(fullscreen_size));
|
||||
|
||||
let width = fullscreen_x + fullscreen_size.x + padding_right;
|
||||
let height = padding_top + max(close_size.y, fullscreen_size.y) + padding_bottom;
|
||||
|
||||
let size = Vector2(width, height);
|
||||
self.shape.set_xy(Vector2(size.x, -size.y) / 2.0);
|
||||
self.shape.set_size(size);
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===========
|
||||
// === FRP ===
|
||||
// ===========
|
||||
|
||||
ensogl::define_endpoints! {
|
||||
Input {
|
||||
enabled (bool),
|
||||
}
|
||||
Output {
|
||||
close(),
|
||||
fullscreen(),
|
||||
size(Vector2<f32>),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === View ===
|
||||
// ============
|
||||
|
||||
/// The Top Buttons Panel component.
|
||||
///
|
||||
/// The panel contains two buttons: one for closing IDE and one for toggling the fullscreen mode.
|
||||
/// The panel is meant to be displayed only when IDE runs in a cloud environment.
|
||||
#[derive(Clone, CloneRef, Debug)]
|
||||
pub struct View {
|
||||
frp: Frp,
|
||||
model: Model,
|
||||
style: StyleWatchFrp,
|
||||
}
|
||||
|
||||
impl View {
|
||||
/// Constructor.
|
||||
pub fn new(app: &Application) -> Self {
|
||||
let frp = Frp::new();
|
||||
let model = Model::new(app);
|
||||
let network = &frp.network;
|
||||
|
||||
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||
let style_frp = LayoutParams::from_theme(&style);
|
||||
let layout_style = style_frp.flatten(network);
|
||||
let radius = style.get_number(theme::radius);
|
||||
|
||||
frp::extend! { network
|
||||
// Layout
|
||||
button_size <- radius.map(|&r| Vector2(2.0 * r, 2.0 * r));
|
||||
model.close.set_size <+ button_size;
|
||||
model.fullscreen.set_size <+ button_size;
|
||||
button_resized <- any_(&model.close.size,&model.fullscreen.size);
|
||||
layout_on_button_change <- sample(&layout_style,&button_resized);
|
||||
need_relayout <- any(&layout_style,&layout_on_button_change);
|
||||
frp.source.size <+ need_relayout.map(f!((layout) model.set_layout(*layout)));
|
||||
|
||||
// Handle the panel-wide hover
|
||||
mouse_near_buttons <- bool(
|
||||
&model.shape.events_deprecated.mouse_out,
|
||||
&model.shape.events_deprecated.mouse_over
|
||||
);
|
||||
mouse_on_any_buttton <- model.close.is_hovered.or(&model.fullscreen.is_hovered);
|
||||
mouse_nearby <- mouse_near_buttons.or(&mouse_on_any_buttton);
|
||||
model.close.mouse_nearby <+ mouse_nearby;
|
||||
model.fullscreen.mouse_nearby <+ mouse_nearby;
|
||||
|
||||
// === Handle buttons' clicked events ===
|
||||
frp.source.close <+ model.close.clicked;
|
||||
frp.source.fullscreen <+ model.fullscreen.clicked;
|
||||
}
|
||||
|
||||
let initial_style = style_frp.value();
|
||||
let initial_size = model.set_layout(initial_style);
|
||||
frp.source.size.emit(initial_size);
|
||||
|
||||
Self { frp, model, style }
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for View {
|
||||
fn display_object(&self) -> &display::object::Instance {
|
||||
&self.model.display_object
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for View {
|
||||
type Target = Frp;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.frp
|
||||
}
|
||||
}
|
||||
|
||||
impl FrpNetworkProvider for View {
|
||||
fn network(&self) -> &frp::Network {
|
||||
&self.frp.network
|
||||
}
|
||||
}
|
||||
|
||||
impl application::View for View {
|
||||
fn label() -> &'static str {
|
||||
"TopButtons"
|
||||
}
|
||||
fn new(app: &Application) -> Self {
|
||||
View::new(app)
|
||||
}
|
||||
fn app(&self) -> &Application {
|
||||
&self.model.app
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
# Options intended to be common for all developers.
|
||||
|
||||
wasm-size-limit: 15.87 MiB
|
||||
wasm-size-limit: 15.88 MiB
|
||||
|
||||
required-versions:
|
||||
# NB. The Rust version is pinned in rust-toolchain.toml.
|
||||
|
@ -405,12 +405,6 @@ define_themes! { [light:0, dark:1]
|
||||
window_control_buttons {
|
||||
radius = 6.5, 6.5;
|
||||
spacing = application::window_control_buttons::radius, application::window_control_buttons::radius;
|
||||
padding {
|
||||
left = 13.0, 13.0;
|
||||
top = 13.0, 13.0;
|
||||
right = 13.0, 13.0;
|
||||
bottom = 13.0, 13.0;
|
||||
}
|
||||
|
||||
close {
|
||||
normal {
|
||||
@ -526,15 +520,8 @@ define_themes! { [light:0, dark:1]
|
||||
selection = Lcha(0.7,0.0,0.125,0.7) , Lcha(0.7,0.0,0.125,0.7);
|
||||
}
|
||||
actions {
|
||||
button {
|
||||
non_toggled = Lcha(0.0,0.0,0.0,0.3) , Lcha(0.4,0.0,0.0,1.0);
|
||||
toggled = Lcha(0.0,0.0,0.0,0.7) , Lcha(1.0,0.0,0.0,0.7);
|
||||
hovered = Lcha(0.0,0.0,0.0,0.45) , Lcha(1.0,0.0,0.0,0.7);
|
||||
}
|
||||
context_switch {
|
||||
non_toggled = Lcha(0.0,0.0,0.0,0.3) , Lcha(0.4,0.0,0.0,1.0);
|
||||
toggled = Lcha(0.58, 0.67, 0.0825, 1.0), Lcha(0.58, 0.67, 0.0825, 1.0);
|
||||
hovered = Lcha(0.0,0.0,0.0,0.45) , Lcha(1.0,0.0,0.0,0.7);
|
||||
}
|
||||
}
|
||||
vcs {
|
||||
@ -620,11 +607,7 @@ define_themes! { [light:0, dark:1]
|
||||
}
|
||||
}
|
||||
profiling_button {
|
||||
non_toggled = graph_editor::node::actions::button::non_toggled
|
||||
,graph_editor::node::actions::button::non_toggled;
|
||||
toggled = Lcha(0.7,0.5,0.12,1.0) , Lcha(0.7,0.5,0.12,1.0);
|
||||
hovered = graph_editor::node::actions::button::hovered
|
||||
,graph_editor::node::actions::button::hovered;
|
||||
toggled_hovered = Lcha(0.55,0.5,0.12,1.0) , Lcha(0.85,0.5,0.12,1.0);
|
||||
}
|
||||
add_node_button {
|
||||
@ -726,6 +709,11 @@ define_themes! { [light:0, dark:1]
|
||||
scale = 1.0, 1.0;
|
||||
}
|
||||
}
|
||||
toggle_button {
|
||||
non_toggled = Lcha(0.0,0.0,0.0,0.3), Lcha(0.4,0.0,0.0,1.0);
|
||||
toggled = Lcha(0.0,0.0,0.0,0.7), Lcha(1.0,0.0,0.0,0.7);
|
||||
hovered = Lcha(0.0,0.0,0.0,0.45), Lcha(1.0,0.0,0.0,0.7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,3 +7,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
enso-frp = { path = "../../../frp" }
|
||||
ensogl-core = { path = "../../core" }
|
||||
ensogl-hardcoded-theme = { path = "../../app/theme/hardcoded" }
|
||||
|
@ -18,6 +18,7 @@
|
||||
#![warn(unused_import_braces)]
|
||||
#![warn(unused_qualifications)]
|
||||
|
||||
use ensogl_core::display::shape::*;
|
||||
use ensogl_core::prelude::*;
|
||||
|
||||
use enso_frp as frp;
|
||||
@ -27,7 +28,9 @@ use ensogl_core::data::color;
|
||||
use ensogl_core::display;
|
||||
use ensogl_core::display::shape::system::Shape;
|
||||
use ensogl_core::display::shape::system::ShapeWithDefaultableData;
|
||||
use ensogl_core::display::style;
|
||||
use ensogl_core::gui::component::ShapeView;
|
||||
use ensogl_hardcoded_theme::component::toggle_button as theme;
|
||||
|
||||
|
||||
|
||||
@ -159,6 +162,18 @@ impl ColorScheme {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the default color scheme for the given style sheet.
|
||||
pub fn default_color_scheme(style_sheet: &style::Sheet) -> ColorScheme {
|
||||
let styles = StyleWatch::new(style_sheet);
|
||||
ColorScheme {
|
||||
non_toggled: Some(styles.get_color(theme::non_toggled).into()),
|
||||
toggled: Some(styles.get_color(theme::toggled).into()),
|
||||
hovered: Some(styles.get_color(theme::hovered).into()),
|
||||
..default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// === Getters ===
|
||||
|
||||
@ -283,7 +298,9 @@ impl<Shape: ColorableShape + 'static> ToggleButton<Shape> {
|
||||
}
|
||||
|
||||
frp.set_state.emit(false);
|
||||
color.target_alpha.emit(0.0);
|
||||
frp.set_visibility.emit(true);
|
||||
let color_scheme = default_color_scheme(&app.display.default_scene.style_sheet);
|
||||
frp.set_color_scheme.emit(color_scheme);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -532,6 +532,7 @@ mock_data! { Document => EventTarget
|
||||
fn create_element(&self, local_name: &str) -> Result<Element, JsValue>;
|
||||
fn get_element_by_id(&self, element_id: &str) -> Option<Element>;
|
||||
fn create_text_node(&self, data: &str) -> Text;
|
||||
fn dispatch_event(&self, event: &Event) -> Result<bool, JsValue>;
|
||||
}
|
||||
|
||||
|
||||
@ -575,6 +576,7 @@ impl AddEventListenerOptions {
|
||||
|
||||
// === Event ===
|
||||
mock_data! { Event => Object
|
||||
fn new(type_: &str) -> Result<Event, JsValue>;
|
||||
fn prevent_default(&self);
|
||||
fn stop_propagation(&self);
|
||||
fn current_target(&self) -> Option<EventTarget>;
|
||||
|
Loading…
Reference in New Issue
Block a user