Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Close and Fullscreen buttons for IDE in the cloud #1511

Merged
merged 24 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
# Next Release

<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)

<br/>![New Features](/docs/assets/tags/new_features.svg)

#### Visual Environment

- [Window management buttons.][1511]. The IDE now has components for
"fullscreen" nad "close" buttons. They will be available only when running IDE
in a cloud environment.

<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)

#### Visual Environment

#### EnsoGL (rendering engine)

#### Enso Compiler

If you're interested in the enhancements and fixes made to the Enso compiler,
you can find their release notes
[here](https://github.com/enso-org/enso/blob/main/RELEASES.md).

[1511]: https://github.com/enso-org/ide/pull/1511

<br/>

# Enso 2.0.0-alpha.3 (2020-04-13)

<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
Expand Down Expand Up @@ -175,6 +203,9 @@ you can find their release notes
[1438]: https://github.com/enso-org/ide/pull/1438
[1367]: https://github.com/enso-org/ide/pull/1367
[1445]: https://github.com/enso-org/ide/pull/1445
[1447]: https://github.com/enso-org/ide/pull/1447
[1471]: https://github.com/enso-org/ide/pull/1471
[1511]: https://github.com/enso-org/ide/pull/1511

<br/>

Expand Down
16 changes: 8 additions & 8 deletions src/js/lib/client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,14 +496,14 @@ function createWindow() {
}

let urlCfg = {
platform : process.platform,
frame : args.frame,
theme : args.theme,
dark_theme : Electron.nativeTheme.shouldUseDarkColors,
high_contrast : Electron.nativeTheme.shouldUseHighContrastColors,
crashReportHost : args.crashReportHost,
noDataGathering : args.noDataGathering,
node_labels : args.nodeLabels,
platform : process.platform,
frame : args.frame,
theme : args.theme,
dark_theme : Electron.nativeTheme.shouldUseDarkColors,
high_contrast : Electron.nativeTheme.shouldUseHighContrastColors,
crash_report_host : args.crashReportHost,
no_data_gathering : args.noDataGathering,
mwu-tow marked this conversation as resolved.
Show resolved Hide resolved
node_labels : args.nodeLabels,
}

if (args.project) { urlCfg.project = args.project }
Expand Down
15 changes: 8 additions & 7 deletions src/js/lib/content/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ function showCrashBanner(message) {
}

async function reportCrash(message) {
const crashReportHost = API[globalConfig.windowAppScopeConfigName].crashReportHost
const crashReportHost = API[globalConfig.windowAppScopeConfigName].crash_report_host
await fetch(`http://${crashReportHost}/`, {
method: 'POST',
mode: 'no-cors',
Expand Down Expand Up @@ -441,18 +441,19 @@ function ok(value) {
/// Main entry point. Loads WASM, initializes it, chooses the scene to run.
API.main = async function (inputConfig) {
let defaultConfig = {
use_loader : true,
wasm_url : '/assets/ide.wasm',
wasm_glue_url : '/assets/wasm_imports.js',
crashReportHost: cfg.defaultLogServerHost,
noDataGathering: false,
use_loader : true,
wasm_url : '/assets/ide.wasm',
wasm_glue_url : '/assets/wasm_imports.js',
crash_report_host : cfg.defaultLogServerHost,
no_data_gathering : false,
is_in_cloud : false,
}
let urlParams = new URLSearchParams(window.location.search);
let urlConfig = Object.fromEntries(urlParams.entries())
let config = Object.assign(defaultConfig,inputConfig,urlConfig)
API[globalConfig.windowAppScopeConfigName] = config

if (config.noDataGathering) {
if (config.no_data_gathering) {
API.remoteLog = function (_event, _data) {}
} else {
let logger = new MixpanelLogger
Expand Down
1 change: 1 addition & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/ensogl/example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod dom_symbols;
pub mod easing_animator;
pub mod glyph_system;
pub mod list_view;
pub mod mouse_events;
pub mod shape_system;
pub mod complex_shape_system;
pub mod sprite_system;
Expand Down
150 changes: 150 additions & 0 deletions src/rust/ensogl/example/src/mouse_events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//! Example scene showing simple shape component that logs all its mouse events.
mwu-tow marked this conversation as resolved.
Show resolved Hide resolved

use ensogl_core::prelude::*;
use wasm_bindgen::prelude::*;

use ensogl_core::system::web;
use ensogl_core::application;
use ensogl_core::application::Application;
use ensogl_core::data::color;
use ensogl_core::define_shape_system;
use ensogl_core::display;
use ensogl_core::display::navigation::navigator::Navigator;
use ensogl_core::display::object::ObjectOps;
use ensogl_core::display::shape::*;

use enso_frp as frp;
use ensogl_text_msdf_sys::run_once_initialized;

// ==============
// === Shapes ===
// ==============

mod shape {
use super::*;

define_shape_system! {
() {
Circle(100.px()).fill(color::Rgb(1.0,0.0,0.0)).into()
}
}
}



// =============
// === Model ===
// =============

#[derive(Clone,CloneRef,Debug)]
struct Model {
app : Application,
logger : DefaultTraceLogger,
display_object : display::object::Instance,
shape : shape::View,
}

impl Model {
fn new(app:&Application) -> Self {
let app = app.clone_ref();
let logger = DefaultTraceLogger::new("Button");
let display_object = display::object::Instance::new(&logger);
let shape = shape::View::new(&logger);
shape.size.set(Vector2::new(100.0, 100.0));
display_object.add_child(&shape);
Self{app,logger,display_object,shape}
}
}



// ===========
// === FRP ===
// ===========

ensogl_core::define_endpoints! { [TRACE_ALL]
Input {
}
Output {
}
}



// ============
// === View ===
// ============

#[derive(Clone,CloneRef,Debug)]
struct View {
frp : Frp,
model : Model,
}

impl View {
/// Constructor.
pub fn new(app: &Application) -> Self {
let frp = Frp::new();
let model = Model::new(app);
let events = &model.shape.events;
let network = &events.network;
frp::extend! { network
// FIXME [mwu] Currently only `mouse_over` and `mouse_out` events are delivered.
// See: https://github.com/enso-org/ide/issues/1477
trace model.shape.events.mouse_up;
trace model.shape.events.mouse_down;
trace model.shape.events.mouse_over;
trace model.shape.events.mouse_out;
trace model.shape.events.on_drop;
}

Self {frp,model }
}
}

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 application::command::FrpNetworkProvider for View {
fn network(&self) -> &frp::Network { &self.frp.network }
}

impl application::View for View {
fn label() -> &'static str { "Circul" }
fn new(app:&Application) -> Self { View::new(app) }
fn app(&self) -> &Application { &self.model.app }
}


// ===================
// === Entry Point ===
// ===================

/// The example entry point.
#[wasm_bindgen]
#[allow(dead_code)]
pub fn entry_point_mouse_events() {
web::forward_panic_hook_to_console();
web::set_stdout();
run_once_initialized(|| {
let app = Application::new(&web::get_html_element_by_id("root").unwrap());

let shape:View = app.new_view();
shape.model.shape.size.set(Vector2::new(300.0, 300.0));
app.display.add_child(&shape);

let scene = app.display.scene();
let camera = scene.camera().clone_ref();
let navigator = Navigator::new(&scene,&camera);

std::mem::forget(shape);
std::mem::forget(navigator);
mem::forget(app);
});
}
9 changes: 9 additions & 0 deletions src/rust/ensogl/lib/core/src/data/color/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ impl<D> Deref for Color<D> {
}


// === DerefMut ===

impl<D> DerefMut for Color<D> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}


// === Color Model ===

/// Type family for accessing color models.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ mod tests {
// This should not happen (probably).
// https://github.com/enso-org/ide/issues/1403
#[test]
#[allow(unused_variables)]
fn test_rgb_to_and_from_lch() {
for r in 0 .. 10 {
for g in 0 .. 10 {
Expand Down
5 changes: 5 additions & 0 deletions src/rust/ensogl/lib/core/src/data/color/space/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ define_color_spaces! {
// ===========

impl Rgb {
/// Construct RGB color by mapping [0 – 255] value range into [0.0 – 1.0].
pub fn from_integral_range(r:impl Into<f32>, g:impl Into<f32>, b:impl Into<f32>) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont understand the name. Wjy there is "rannge" in name? We are consturctng colors not from a range, but from a 255-integer color encoding. I just think that the "range" word is very confusing here

Self::new(r.into() / 255.0, g.into() / 255.0, b.into() / 255.0)
}

/// Converts the color to `LinearRgb` representation.
pub fn into_linear(self) -> LinearRgb {
self.into()
Expand Down
48 changes: 48 additions & 0 deletions src/rust/ensogl/lib/core/src/display/shape/primitive/def/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,26 @@ pub enum Var<T> {

// === Constructors ===

impl Var<Pixels> {
/// Get the current shape's sizes.
pub fn canvas_size() -> Var<Vector2<Pixels>> {
"input_size".into()
}
}

impl Var<color::Rgba> {
/// Build a color from its components.
pub fn srgba(r:impl Into<Var<f32>>, g:impl Into<Var<f32>>, b:impl Into<Var<f32>>, a:impl Into<Var<f32>>)
-> Var<color::Rgba> {
format!("srgba({},{},{},{})",
r.into().glsl(),
g.into().glsl(),
b.into().glsl(),
a.into().glsl()
).into()
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be implemented as .glsl() method on colors instead imo. This is how we are converting all values there. Moreover, I see inconsistency here - srgba is a name used in GLSL due to convention there. However, in Rust, the counterpart of srgba is color::Rgba, while the counterpart of GLSL's rgba is color::LinearRgba. So the name srgba in Rust can be confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cannot be a glsl method, as the purpose is to construct Var<color:Rgba>, not Glsl.
Also, it cannot be on color, as there is no color, just the variables with its components.


impl<T,S> From<T> for Var<S>
where T : VarInitializer<Var<S>> {
default fn from(t:T) -> Self {
Expand Down Expand Up @@ -127,6 +147,34 @@ where T:Abs {
}
}

impl<T> Min for Var<T>
where T:Min+Into<Glsl> {
fn min(a:Self, b:Self) -> Self {
match (a,b) {
(Var::Static(a), Var::Static(b)) => Var::Static(Min::min(a,b)),
(a,b) => {
let a:Glsl = a.into();
let b:Glsl = b.into();
Var::Dynamic(format!("min({},{})", a.glsl(), b.glsl()).into())
},
}
}
}

impl<T> Max for Var<T>
where T:Max+Into<Glsl> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alignment + these two impls are so similar, that you should create macro for them.

fn max(a:Self, b:Self) -> Self {
match (a,b) {
(Var::Static(a), Var::Static(b)) => Var::Static(Max::max(a,b)),
(a,b) => {
let a:Glsl = a.into();
let b:Glsl = b.into();
Var::Dynamic(format!("max({},{})", a.glsl(), b.glsl()).into())
},
}
}
}

impl<T:Scalar> HasComponents for Var<Vector2<T>> {
type Component = Var<T>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ impl StyleWatchFrp {
source.emit(current);
sampler
}

/// Queries style sheet number.
pub fn get_number_or<T:Into<Path>>(&self, path:T, fallback:f32) -> frp::Sampler<f32> {
let network = &self.network;
let (source,current) = self.get_internal(path);
frp::extend! { network
value <- source.map(move |t| t.number().unwrap_or(fallback));
sampler <- value.sampler();
}
source.emit(current);
sampler
}
}


Expand Down
2 changes: 1 addition & 1 deletion src/rust/ensogl/lib/core/src/display/style/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ mod tests {
let handle = var.on_change(f!([val](v:&Option<Data>) *val.borrow_mut() = v.clone()));
assert_query_sheet_count(&sheet,1,2);
{
let var2 = sheet.var("button.size");
let _var2 = sheet.var("button.size");
assert_query_sheet_count(&sheet,1,2);
}
assert_query_sheet_count(&sheet,1,2);
Expand Down
Loading