Giter VIP home page Giter VIP logo

scenic's People

Contributors

adkron avatar am-kantox avatar amclain avatar axelson avatar boydm avatar connorrigby avatar crertel avatar gprimola avatar grahamhay avatar gregmefford avatar harlantwood avatar hassanshaikley avatar jb3 avatar jediluke avatar jjcarstens avatar josevalim avatar kottkrig avatar lmarlow avatar milmazz avatar mobileoverlord avatar nschulzke avatar pragdave avatar pragtob avatar seb3s avatar shritesh avatar tapickell avatar thejohncotton avatar vacarsu avatar yordis avatar zacck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scenic's Issues

GLFW error 65543: GLX: Failed to create context: BadValue (integer parameter out of range for operation)

Generated my_scenic_app app
GLFW error 65543: GLX: Failed to create context: BadValue (integer parameter out of range for operation)
12:12:11.458 [error] dirty close

Versions and Environment

Elixir:

Elixir 1.7.2 (compiled with Erlang/OTP 19)

Erlang:

Erlang/OTP 21 [erts-10.0.5] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]

Eshell V10.0.5  (abort with ^G)

Scenic:

* parse_trans 3.2.0 (Hex package) (rebar3)
  locked at 3.2.0 (parse_trans) 2adfa4da
  ok
* mimerl 1.0.2 (Hex package) (rebar3)
  locked at 1.0.2 (mimerl) 993f9b0e
  ok
* metrics 1.0.1 (Hex package) (rebar3)
  locked at 1.0.1 (metrics) 25f094de
  ok
* unicode_util_compat 0.3.1 (Hex package) (rebar3)
  locked at 0.3.1 (unicode_util_compat) a1f612a7
  ok
* idna 5.1.2 (Hex package) (rebar3)
  locked at 5.1.2 (idna) e21cb58a
  ok
* gettext 0.16.0 (Hex package) (mix)
  locked at 0.16.0 (gettext) 4a7e9040
  ok
* ssl_verify_fun 1.1.1 (Hex package) (rebar)
  locked at 1.1.1 (ssl_verify_fun) 28a4d65b
  ok
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
  ok
* combine 0.10.0 (Hex package) (mix)
  locked at 0.10.0 (combine) eff8224e
  ok
* elixir_make 0.4.2 (Hex package) (mix)
  locked at 0.4.2 (elixir_make) 332c649d
  ok
* certifi 2.3.1 (Hex package) (rebar3)
  locked at 2.3.1 (certifi) d0f42423
  ok
* hackney 1.13.0 (Hex package) (rebar3)
  locked at 1.13.0 (hackney) 24edc8cd
  ok
* tzdata 0.5.19 (Hex package) (mix)
  locked at 0.5.19 (tzdata) 7962a399
  ok
* timex 3.3.0 (Hex package) (mix)
  locked at 3.3.0 (timex) e0695aa0
  ok
* scenic_math 0.7.1 (Hex package) (mix)
  locked at 0.7.1 (scenic_math) 131ef7cf
  ok
* scenic 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic) fa93041f
  ok
* scenic_driver_glfw 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_driver_glfw) e9051384
  ok
* scenic_clock 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_clock) 645bfd0f
  ok

OS:

Distributor ID: Ubuntu
Description:    Ubuntu 18.04.1 LTS
Release:        18.04
Codename:       bionic

Linux olafura-GS73-Stealth-8RF 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Steps to reproduce

sudo apt-get install pkgconf libglfw3 libglfw3-dev libglew2.0 libglew-dev
mix archive.install hex scenic_new
mix scenic.new my_scenic_app
cd my_scenic_app
mix scenic.run

Deleting a group does not delete group members

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir & Erlang:

Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.7.4 (compiled with Erlang/OTP 21)

Scenic:

* scenic 0.9.0 (Hex package) (mix)
  locked at 0.9.0 (scenic) 129594f9
  ok
* scenic_driver_glfw 0.9.1 (Hex package) (mix)
  locked at 0.9.1 (scenic_driver_glfw) b64d3459
  ok

OS:

MacOS10.14

Steps to reproduce

mix scenic.new stest
modify home.ex as follows
mix scenic.run

defmodule Stest.Scene.Home do
  use Scenic.Scene

  alias Scenic.Graph

  import Scenic.Primitives
  import Scenic.Components

  @note """
    This is a very simple starter application.

    If you want a more full-on example, please start from:

    mix scenic.new.example
  """

  @graph Graph.build(font: :roboto, font_size: 24)
   |> text(@note, translate: {20, 60})
   |> group(
     fn g ->
       g
       |> text("testing", translate: {15, 250}, id: :testtxt)
       |> button("hi", translate: {90, 250}, id: :testbtn)
     end,
     font: :roboto_mono,
     font_size: 24,
     id: :testgrp
   )

  def init(_, _) do
    push_graph(@graph)
    {:ok, @graph}
  end

  def filter_event({:click, id}, _context, graph) do
    IO.inspect(graph)
    IO.puts("===============")

    g =
      Graph.delete(graph, :testgrp)
      |> IO.inspect()
      |> push_graph()

    {:stop, g}
  end
end

Pressing the button yields an inspection of the graph before and after deleting the group.

Before:

%Scenic.Graph{
  add_to: 0,
  ids: %{_root_: [0], testbtn: [4], testgrp: [2], testtxt: [3]},
  next_uid: 5,
  primitives: %{
    0 => %{
      __struct__: Scenic.Primitive,
      data: [1, 2],
      module: Scenic.Primitive.Group,
      parent_uid: -1,
      styles: %{font: :roboto, font_size: 24}
    },
    1 => %{
      __struct__: Scenic.Primitive,
      data: "  This is a very simple starter application.\n\n  If you want a more full-on example, please start from:\n\n  mix scenic.new.example\n",
      module: Scenic.Primitive.Text,
      parent_uid: 0,
      transforms: %{translate: {20, 60}}
    },
    2 => %{
      __struct__: Scenic.Primitive,
      data: [3, 4],
      id: :testgrp,
      module: Scenic.Primitive.Group,
      parent_uid: 0,
      styles: %{font: :roboto_mono, font_size: 24}
    },
    3 => %{
      __struct__: Scenic.Primitive,
      data: "testing",
      id: :testtxt,
      module: Scenic.Primitive.Text,
      parent_uid: 2,
      transforms: %{translate: {15, 250}}
    },
    4 => %{
      __struct__: Scenic.Primitive,
      data: {Scenic.Component.Button, "hi"},
      id: :testbtn,
      module: Scenic.Primitive.SceneRef,
      parent_uid: 2,
      transforms: %{translate: {90, 250}}
    }
  }
}

after deletion:

%Scenic.Graph{
  add_to: 0,
  ids: %{_root_: [0], testbtn: [4], testtxt: [3]},
  next_uid: 5,
  primitives: %{
    0 => %{
      __struct__: Scenic.Primitive,
      data: [1],
      module: Scenic.Primitive.Group,
      parent_uid: -1,
      styles: %{font: :roboto, font_size: 24}
    },
    1 => %{
      __struct__: Scenic.Primitive,
      data: "  This is a very simple starter application.\n\n  If you want a more full-on example, please start from:\n\n  mix scenic.new.example\n",
      module: Scenic.Primitive.Text,
      parent_uid: 0,
      transforms: %{translate: {20, 60}}
    },
    3 => %{
      __struct__: Scenic.Primitive,
      data: "testing",
      id: :testtxt,
      module: Scenic.Primitive.Text,
      parent_uid: 2,
      transforms: %{translate: {15, 250}}
    },
    4 => %{
      __struct__: Scenic.Primitive,
      data: {Scenic.Component.Button, "hi"},
      id: :testbtn,
      module: Scenic.Primitive.SceneRef,
      parent_uid: 2,
      transforms: %{translate: {90, 250}}
    }
  }
}

Expected Behavior

I would expect an inspection of the graph to show that the group with id :testgroup would be removed from the graph (it is) along with its children. This is in accordance with the docs.

Actual Behavior

Children are not removed.

Additional Comments

I can probably figure out how to fix this. I've never contributed to a github project before, so I need to figure that out.

I'm not sure if this intentional or not, but it appears as though text is rendered going up from Y, while buttons are rendered going down from Y:

screen shot 2019-02-08 at 4 52 32 pm

Circular(ish) dependency on glfw

I'm trying to test an updated version of scenic_new with a correspondingly updated version of scenic.

The problem is that the code generated by scenic_new includes

{:scenic, github: "pragdave/scenic", branch: "add-specs"},
{:scenic_driver_glfw, "~> 0.9"}

But :scenic_driver_glfw also has a dependency on scenic, which it satisfies from hex. As a result, I get an error on deps.get

When I try to use :override to force just my version to be used, I get explosions inside glfw

20:46:42.323 [error] GenServer :glfw terminating
** (UndefinedFunctionError) function Scenic.Cache.request_notification/1 is undefined or private
    (scenic) Scenic.Cache.request_notification(:cache_put)
    (scenic_driver_glfw) lib/glfw.ex:82: Scenic.Driver.Glfw.init/3
    (scenic) lib/scenic/view_port/driver.ex:153: Scenic.ViewPort.Driver.handle_cast/2
    (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:686: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:after_init, #PID<0.4413.0>, {700, 600}, %{module: Scenic.Driver.Glfw, name: :glfw, opts: [resizeable: false, title: "dave"]}}}
State: nil

Is there some magic I'm missing?

Add typespec to all the functions

Type specs are quite useful for understanding the data structures being used on the functions and so on.

Better to add it now than later

Fill in Documentation

Many of the components are not yet documented.

If you would like to help out, as you get familiar with Scenic, please pick a module that needs documentation. Submit an issue here to claim that you are working on it, then go for it.

I will be working on as many of these (and the guides) as I can over the next few weeks. There is still quite a bit tho.

Wrongly scaled output on Arch Linux/Wayland

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 21 [erts-10.0.8] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.7.3 (compiled with Erlang/OTP 21)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.0.8] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Scenic:

# mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic) 44bffa47
* scenic_driver_glfw 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic_driver_glfw) 710e0256
* scenic_clock 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic_clock) fc144430

OS:

# uname -a
Arch Linux 4.18.9-arch1-1-ARCH #1 SMP PREEMPT Wed Sep 19 21:19:17 UTC 2018 x86_64 GNU/Linux
*with wayland*

Steps to reproduce

  • install dependencies (I was just missing community/glfw-wayland 3.2.1-1)
  • generate a new app with mix scenic.new
  • run mix deps.get
  • run scenic.run

Expected Behavior

The example app window shows up with correct positioning.

Actual Behavior

screenshot from 2018-09-27 16-43-12
screenshot from 2018-09-27 16-34-39

The rendered output only takes up a quarter of the whole window. The areas for buttons and drop downs are positioned correctly which means to have to click into the empty black part of the window to hit something.

Stack Trace

Sadly there is not a lot to see here, just a single message from GLFW.

mix scenic.run        
GLFW error 65544: Wayland: Focusing a window requires user interaction

Additional Comments

  • I have a 4k screen, maybe thats a problem?

Missing :id option on Scenic.child_spec/1

Versions and Environment

Elixir:

# elixir -v
Elixir 1.7.3 (compiled with Erlang/OTP 19)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Scenic:

# mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic_math 0.7.1 (Hex package) (mix)
  locked at 0.7.1 (scenic_math) 131ef7cf
* scenic 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic) fa93041f
* scenic_driver_glfw 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_driver_glfw) e9051384
* scenic_clock 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_clock) 645bfd0f

OS:

Linux parrot 4.18.0-parrot8-amd64 #1 SMP Parrot 4.18.6-1parrot8 (2018-09-07) x86_64 GNU/Linux

Steps to reproduce

(alternatively clone this repo and check the commits.

  1. Create a new application using mix scenic.new example.

  2. Edit the application file to use Application:

defmodule Example do
  @moduledoc """
  Starter application using the Scenic framework.
  """

  use Application

  def start(_type, _args) do
    # import Supervisor.Spec, warn: false

    # load the viewport configuration from config
    main_viewport_config = Application.get_env(:example, :viewport)

    # start the application with the viewport
    # removed `supervisor/2` wrapper
    children = [
      Example.Sensor.Supervisor,
      {Scenic, [viewports: [main_viewport_config]]}, 
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
  end
end
  1. Add argument on Example.Sensor.Supervisor.start_link:
...
  def start_link(_args) do
    Supervisor.start_link(__MODULE__, :ok)
  end
...

Expected Behavior

The application should have started normally.

Actual Behavior

The application didn't started because Scenic.child_spec/1 doesn't specify an :id.

Stack Trace

** (Mix) Could not start application example: Example.start(:normal, []) returned an error: bad child specification, got: :missing_id

Additional Comments

This issue can be fixed by adding the :id option to the list returned by Scenic.child_spec/1:

...
  def child_spec(opts) do
    %{
      id: __MODULE__, # adding this option
      start: {__MODULE__, :start_link, [opts]},
      type: :supervisor,
      restart: :permanent,
      shutdown: 500
    }
  end
...

Update Image in graph

Is there a method to produce an image (in my case QR Code which is rendered to a png) and then have it displayed via the normal fill method (fill: {:img}) currently i can get it to render once but it takes ~4secs for the png to render correctly so nothing is displayed on the second attempt

Alternatively, I have the output of the QR Code as binary, is there a method to render a group of rectangles given a list? i.e i have a list:

[1,1,1,0] it should render three white squares and one black square next to it. Digging around in the core library yesterday i played with grouping etc, but i think i need a little more info for it

text_input width doesn't alter the actual width

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir: 1.7
Erlang: 21

Scenic:

    scenic 0.9.0 (Hex package) (mix)
    locked at 0.9.0 (scenic) 129594f9
    scenic_driver_glfw 0.9.0 (Hex package) (mix)
    locked at 0.9.0 (scenic_driver_glfw) 4c7a8300

OS: Ubuntu 16.04

Steps to reproduce

text_field("", id: :text, width: 40, hint: "Type here...", t: {200, 160})

Expected Behavior

Width of the component to be 40

Actual Behavior

Defaults to 240

Struct From Inspection:

  data: {Scenic.Component.Input.TextField, ""},
  id: :key_input,
  module: Scenic.Primitive.SceneRef,
  parent_uid: 1,
  styles: %{
    fontsize: 15,
    height: 20,
    hint: "Paste Private Key or Pneumonic",
    t: {100, 200},
    w: 1000
  },
  transforms: %{translate: {100, 200}}
}

Additional Comments

Any Width inputted doesn't change the width, I've used :w and :width as per the docs

Document Cache Module

I noticed that the cache module doesn't have documentation, opening this issue as a notification of intent

see #5 for more details

Credo Appeasement: Code Readability

Next chunk of credo issues to resolve are modules missing a @moduledoc tag.

This issue is about adding in ones--probably @moduledoc false for now--to shutup credo and give people a place to start writing in more documentation.

Bug: message handling delays in the GLFW driver after crashing scenes, sub-scenes and waiting

The repro is vague, but goes something like this:

  1. Go to the Components Scene in the demo app. Hit the Crash button a few times. (that crashes the entire scene)
  2. use observer to crash the radio group scene as well a few times.
  3. wait a few minutes.
  4. click a radio button without moving the mouse. Notice that the updates are not flowing through correctly. If you wait, it works eventually. Or if you use the mouse (or create any user input) it works right away.

Have not figured this out yet. I suspect there is some sort of blocking read or write between the driver (in erlang space) and the port that does the rendering. Don't know yet why that should be triggered by crashes in scenes, which is pretty orthogonal to the driver.

If you use observer to crash the driver, the problem goes away.

Needs investigation.

Text Wrapping behavior is unexpected

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 21 [erts-10.0.7] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]

Elixir 1.7.4 (compiled with Erlang/OTP 21)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.0.7] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]

Eshell V10.0.7  (abort with ^G)

Scenic:

# mix deps | grep scenic
* scenic 0.9.0 (https://github.com/boydm/scenic.git) (mix)
* scenic_driver_glfw 0.9.0 (https://github.com/boydm/scenic_driver_glfw.git) (mix)

OS:

Arch Linux

Steps to reproduce

Create a text field with many words

long_text = "a b c <etc>"
Scenic.Primitives.text(graph, long_text)

Expected Behavior

Text to wrapping to be controllable

Actual Behavior

Text wraps around 1500px all the time (but appears to wrap at a word boundary which is nice)

Stack Trace

N/A

Additional Comments

#106 seemed like it might be related but adding width: 100 to the text call didn't appear to make a difference.

Trouble with clear_color and theming

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 21 [erts-10.0.5] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]    

Elixir 1.7.2 (compiled with Erlang/OTP 19)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.0.5] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]    

Eshell V10.0.5  (abort with ^G)

Scenic:

# mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic) 44bffa47
* scenic_driver_glfw 0.8.1 (Hex package) (mix)
  locked at 0.8.1 (scenic_driver_glfw) 4fceea7b
* scenic_clock 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic_clock) fc144430

OS:

# uname -a
Linux 4.15.0-33-generic #36~16.04.1-Ubuntu SMP Wed Aug 15 17:21:05 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Steps to reproduce

  • install dependencies
  • generate a new app with mix scenic.new
  • run the app with mix scenic.run
  • change Graph.build() in lib/scenes/splash.ex:22 to Graph.build(clear_color: :white) and/or change theme: :dark to theme: :light in lib/scenes/transforms.ex:21.
  • run the app again with mix scenic.run

Expected Behavior

The background fill in the parrot splash screen is changed from black to white, and/or the theme colors in the transforms screen are changed to brighter tones.

Actual Behavior

The colors are unchanged, and the screens are visually the same.

Stack Trace

n/a

Additional Comments

  • GLEW and GLFW were pulled from apt-get.
  • Tried to define a custom theme with theme: %{background: :white} with no success either. Other color-related options such as :fill are working as expected.

Text area control

Should support word wrap, scrolling. Non-goals for initial version: RTF-like styling. Requires Issue #6

TextArea component

Looking to create a simple notepad app but didn't see a text area. Does this exist or is it possible somehow to get a large text input?

Issue rendering scene immediately after switching the root scene

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 21 [erts-10.0.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Elixir 1.7.3 (compiled with Erlang/OTP 21)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.0.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.0.7  (abort with ^G)

Scenic:

# mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic 0.9.0 (Hex package) (mix)
  locked at 0.9.0 (scenic) 129594f9
* scenic_clock 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic_clock) fc144430

OS:

Arch Linux

Steps to reproduce

  1. In one scene run ViewPort.set_root/2
  2. In the newly run scene, render the graph with push_graph in the init/1 callback

Expected Behavior

The new scene/graph should be rendered

Actual Behavior

I only see a black screen (unless I add a delay to the push_graph call of around 100ms)

Additional Comments

I'm not sure if I'm misunderstanding something (although that is definitely possible). For testing I'm actually using the Splash Scene from scenic_new so I don't think it is an issue with the scene transition (although I did look into it, which is why I was looking for the existence of release_graph).

Feature Request: fill with gradient

What problem does this feature solve?

I often find myself wanting to apply a gradient to a shape, rather than just a single color.

What is your proposed solution?

Maybe an API like this:

graph
|> rectangle( {100, 200}, fill: {:gradient, [0x6db1ec, 0x35a274], 90})

where fill's options are {:gradient, list_of_colors, angle}

Default font and font_size options

Currently each Graph that has text primitives must explicitly set both the font and font_size styles. The graph should have a sensible default if these styles are not supplied.

Suggestions:
font default should be :roboto
font_size default should be: 24

Desktop use: Auto-scale

What problem does this feature solve?

Hi there. :)

I just see this video and you say at 33:26 that Scenic has no auto-scale solution.

In the readme on this page, you say Scenic works well with my desktop

Desktops have different screen sizes.

What is your proposed solution?

Add optional auto-scaling.

Improve docs

From the list of Helpful Guides

We need to make sure that the order of the guidelines helps the user.

  • Make sure that at the end of each guideline we point to the next guideline
  • Settle on the order
  • Move config section from scenic.ex into getting_started If you read the doc right now it is quite confusing to see that info before you do those steps first. Also better to keep documentation of scenic.ex related to what the module does (supervisor stuff).
  • Considerate to create a landing page for the main page instead of using scenic.ex. This landing page will have the order of how you should read the documentation. That way we keep clean order of how to get started.
  • Finish Lifecycle of a Scene
  • Styles Overview
  • Standard Components
  • Graph Overview
  • ViewPort Overview
  • Driver Overview
  • Primitives
  • Styles
  • Transforms
  • Nerves

Updating creation date to ISO-8601 format

The structure and format of the commented out lines of metadata at the top of files is currently inconsistent, and in some cases incomplete, or missing.

As a first step in establishing a canonical structure and format for the metadata at the top of files - the various date formats used for the creation date have been re-written in an ISO-8601 compliant format.

This will allow an automated pass over the files in the repository to identify files where the metadata is currently inconsistent, incomplete, or missing.

An Issue (to be raised after this one) will propose for adoption if found to be satisfactory - a simple structure and format for the metadata at the top of files.

Note: The choice of the ISO-8601 date format is to eliminate the several ambiguities that arise from the inevitable mixed use of US mm/dd/yy formats and other formats used around the globe.

Installing Courier New font gives invalid name error

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

~/elixir -v
Erlang/OTP 21 [erts-10.2.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.8.1 (compiled with Erlang/OTP 21)
~/

Scenic:

  • scenic (Hex package) (mix)
    locked at 0.9.0 (scenic) 129594f9

OS:

OSX


Steps to reproduce

https://github.com/QuantumProductions/scenic_font_test

Expected Behavior

I tried to install a Courier New font following https://github.com/boydm/scenic/blob/master/guides/custom_fonts.md

Actual Behavior

In GameOver.ex there is

  @font_folder :code.priv_dir(:play) |> Path.join("/static/fonts")
  @custom_font_hash "UYe2ryfLUpczug9LKyrTxPYGSYTimnPHzpSMbC6UF0M"
  @custom_metrics_path :code.priv_dir(:scenic_example)
           |> Path.join("/static/fonts/Courier New.ttf.metrics")
  @custom_metrics_hash Scenic.Cache.Support.Hash.file!(@custom_metrics_path, :sha)

Stack Trace

==> play
make: Nothing to be done for `all'.
Compiling 4 files (.ex)

== Compilation error in file lib/scenes/game_over.ex ==
** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1    
    
    The following arguments were given to IO.chardata_to_string/1:
    
        # 1
        {:error, :bad_name}
    
    Attempted function clauses (showing 2 out of 2):
    
        def chardata_to_string(string) when is_binary(string)
        def chardata_to_string(list) when is_list(list)
    
    (elixir) lib/io.ex:461: IO.chardata_to_string/1
    (elixir) lib/path.ex:512: Path.join/2
    lib/scenes/game_over.ex:9: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
could not compile dependency :play, "mix compile" failed. You can recompile this dependency with "mix deps.compile play", update it with "mix deps.update play" or clean it with "mix deps.clean play"

Name of font does not seem to be accepted. I downloaded from https://www.wfonts.com/font/courier-new

Additional Comments

Fix linting errors

If you want to contribute to this project, probably a good first issue to solve would be reducing the number of warnings, refactoring opportunities, code readability issues, or software design suggestions reported by credo.

Now the report includes the following findings:

screen shot 2018-09-19 at 10 21 03 am

So, that's too much work for just one person (@boydm) to handle.

If you haven't use credo before, you can do the following:

cd scenic
mix deps.get
mix credo

If you want to find more suggestions you can try:

mix credo --strict

For more information, please check credo project.

Replace the Makefile for static assets with the new :build_embedded option in mix.ex

I don't remember exactly what José said, but it was something about a new :build_embedded option in the mix.ex file of an application that would take care of the priv static assets without needing a Makefile to do it.

Investigate this and, if it works, replace the Makefile with the build options.

Must work on both the Desktop and Nerves versions. (thats the tricky part)

def group(graph_or_primitive, builder, opts \\ []) has no function definition for primitive

other functions with the same argument graph_or_primitive also have a definition with a Primitive struct, but it seems this is not implemented for group.

I'm not sure if group should not expect a primitive or if it's just not implemented?

Next to stating the issue, I'm also adding my problem here. I'm trying to use Graph.modify to update a complete group but I have no idea how to do it.

This is some simplified code:

Graph.build()
|> ....
|> group(
  fn g -> builds_many(g), id: :sample
)

def builds_many(g) do
  g
  |> rrect(...)
end

And on an update I want to basically replace the group sample by doing builds_many again.

These are the things I tried:

  • Using Graph.modify, but this has the problem that I get a primitive (a group) and rrect can only take a Primitive of round_rect not group.
  • First deleting the old Primitive with Graph.delete, then building a new graph (It's not possible to just create a group from nothing), creating a new group and then try to add this graph to the main graph, but Graph.add expects a primitive so this doesn't work
  • using Graph.map, but this action also passes a Primitive

I'm probably missing something here, but I'm still struggling with it, and that's the reason I stumbled on this issue.

Add internal functionality for scenic to know character dimensions for a given font

A scenic font should provide functionality to lookup incremental width that a character ads to a group of characters.

Should be kerning and styling aware.

Question: does height matter or is that a constant for the font.

Non goals: support for letter spacing.

This will support a number of features, notably text flow, wrapping, center positioning, and justifying.

Fonts do not show on nerves deployment

The hashing scheme described in the docs does evaluate the paths at compile time, which is usually the development machine’s paths and not the deployed (nerves) one. That leads to a problem where fonts do no show on nerves devices, since the resource path is different.

I “fixed” it for now by differentiating a bit more and hardcoding the nerves path (bad!):

  @font_hash_path :code.priv_dir(:my_app) |> Path.join("/static/fonts/myfont.otf")

  if @target == "host" do
    @font_path @font_hash_path
  else
    @font_path "/srv/erlang/lib/my_app-0.1.0/priv/static/fonts/myfont.otf"
  end

  @font_hash Scenic.Cache.Hash.file!(@font_hash_path, :sha)

and in init/2

def init(_, opts) do
  Scenic.Cache.File.load(@font_path, @font_hash)
...

I guess thats also the problem with the built-in fonts not showing in nerves. Probably a documentation issue first and foremost.

Slider loses tracking outside of widget

What problem does this feature solve?

This is a user experience thing I noticed while playing with the example (solid instructions for getting up and running, by the way, good job).

The slider elements (dragging a marker on a line) stop tracking your mouse's horizontal position if you move outside of the bounds of the widget. It stops dragging but will resume if you re-enter the bounds.

This felt awkward so I verified with some system components and at least on Mac (volume settings for example) they will, as I suspected keep tracking even if you go somewhere else vertically. As long as you keep the button pressed you have control of the slider.

I think this will mostly make the widget feel better. But it should also improve accessibility since it will no longer require the user to be quite as precise. So I think this would be a better default behavior.

What is your proposed solution?

Once you press down on the element to grab a hold of it you should keep that hold until you release, even if you go out-of-bonds on the vertical axis. I have not checked if this would straight forward or more complex in the code yet. This way just something I noticed while trying the feel of the widgets.

Let me know if anything seems unclear and I'll try to clarify :)

Add master style and transforms to the ViewPort

The root scene should inherit both a style map and a transforms that have been set on the ViewPort via it's configuration record.

In this way, you can set something like a :scale transform on the ViewPort and all scene's it shows would be zoomed in or repositioned or whatever.

Same for supplying ViewPort specific defaults for the styles.

Add/finish the text/font metrics system

It would be useful for the scene to be able to obtain the metrics (width, height, etc) of a string of text before it gets rendered. For example, the Button component could use this to automatically size the button to fit the string. Any future (optional) layout engine would also need it.

This should NOT parse fonts at runtime. Interpreting fonts should remain the purview of the Drivers. In the future I want to support other font types than *.ttf and the core Scenic library should not have a dependency on that format.

Instead, I want to back the font metric information into separate format offline that can be easily loaded and inspected by a scene. No C code should be invoked at that time. This work is under way, but has been lower priority as most (all) scenes so far simply don't need it.

Rendering glitch seen on MacOS

Rendering glitch shows up from time to time with the example app (scenic_new repo), sensor scene, :temperature text component.

Checklist

  • Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 21 [erts-10.1.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.7.4 (compiled with Erlang/OTP 21)

Erlang:

# erl -v
Erlang/OTP 21 [erts-10.1.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Eshell V10.1.2  (abort with ^G)

Scenic:

# mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic 0.9.0 (Hex package) (mix)
  locked at 0.9.0 (scenic) 129594f9
* scenic_driver_glfw 0.9.0 (Hex package) (mix)
  locked at 0.9.0 (scenic_driver_glfw) 4c7a8300
* scenic_clock 0.8.0 (Hex package) (mix)
  locked at 0.8.0 (scenic_clock) fc144430

OS:

MacOS Mojave 10.14.1 

Steps to reproduce

  • Create the scenic example using mix scenic.new.example
  • Compile and run
  • Stay on the sensor scene, do nothing special
  • Glitch mostly when temperature between 72.7° and 73°

Expected Behavior

It should show the temperature as usual. Here's what it looks like before the issue:

capture d ecran 2018-11-17 a 21 36 47

Actual Behavior

But then his happens (here when displaying 72.8°):

capture d ecran 2018-11-17 a 21 25 55

It looks like texts around it get mixed up.

It lasts only a few milliseconds (captured from a video recording of the screen), then things go back to normal.

I can reproduce the issue most of the times.

Stack Trace

n/a

Additional Comments

I checked with IO.inspect the text given to the component (temperature), it's correct. Looks like the issue is from scenic, not the example project itself.

Feature request: Add support for image fill sampling and scaling

What problem does this feature solve?

So, I'm trying to build a simple little animated sprite renderer (similar to what you'd see in a game). This is done by using a sprite sheet, and by using the existing API to render.

Doing this, you call something like:

      |> rect( {vp_width, vp_height},
                id: :image_root,
                fill: {:image, {@image_hash, 255}})

And later, if you want to be more specific, you do:

      |> rect( {vp_width, vp_height},
                id: :image_root,
                fill: {:image, {@image_hash, start_x, start_y, image_width, image_height, theta, alpha, 255}})

(note)
Why is alpha on [0-255] instead of just the normal [0-1]? Theta (the rotation) is in radians as it should be. We should try to make this API unsurprising for people who've done graphics. :(
(end note)

So, the problem here is that if I want to scale up my little image rectangle, I have to scale the rectangle instead of the image--the texture sample isn't automatically stretched to fit the rectangle in Scenic, which is again unexpected from normal graphics conventions.

My source image is basically this:

image

And when I render it with the following code (cribbed from other scenic examples and modified):

def init(_, opts) do
    viewport = opts[:viewport]
    IO.inspect ViewPort.info(viewport), label: "viewport info"

    # calculate the transform that centers the parrot in the viewport
    {:ok, %ViewPort.Status{size: {vp_width, vp_height}}} = ViewPort.info(viewport)

    Scenic.Cache.File.load(@image_path, @image_hash)

    graph =
      @root_image_graph
      |> rect( {vp_width, vp_height},
                id: :image_root,
                fill: {:image, {@image_hash, 0,0,100,100,0,255}})
      |> group(
        fn g ->
          g
          |> line({{-10,0},{10,0}}, stroke: {2, :magenta})
          |> line({{0,-10},{0,10}}, stroke: {2, :magenta})
        end,
        id: :cursor_lines,
        transform: {0,0})
      |> push_graph()

    state = %{
      viewport: viewport,
      graph: graph,
      cursor_pos: {0,0},
      in_drag: false,
      start_point: nil,
      end_point: nil
    }

    {:ok, state}
  end

it renders something like this:

image

So, it looks like it's trying to scale the image down into a sub-rectangle which may or may not be transformed in the Scenic rectangle.

Additionally, you can kinda see image streaks: I'd suggest that that's because of an incorrect GL texture sampling mode, and that nanovg is deciding to clamp to edge. That's fine, but it's nice to be able to do other things (see glTexParameter for GL's take on this). At the least clamp to border would probably be the reasonable choice, or mirroring/repeating.

What is your proposed solution?

So, I'd like to propose a couple of things:

Change the image fill semantics for rectangles to stretch the entire image across the rectangle, always. There's no convenient way to, say, update the image transformation (image fill offset and scale) anyways, so we might as well just leave that up to the transform of the rectangle that is being drawn--this also means we don't have to fight with the scale property on the rectangle at the same time we fight with the image fill's width and height.

Allow users to set the image ST scaling on the rectangle. If I have an image fill (say, a simple brick image), and I want to tile it over the rectangle right now, I can't quite do it. It'd be cool if I could specify multipliers for ST (probably better understood as X and Y tiling scaling) so that the image, once stretch over the rectangle, is scaled out (values < 1) or tiled across (values > 1) properly. This might be the time to include the ability to clamp, repeat, or mirror as seems reasonable.

(note)
The docs erroneously state the image tuple as:
{:image, {image_key, start_x, start_y, end_x, end_y, angle, alpha}}
when it should be:
{:image, {image_key, start_x, start_y, width, height, angle, alpha}}
(end note)

In light of these things, and to make the API non-breaking with what's already been done, I'd propose a new fill type:

{:image_stretched, {image_key, scale_x, scale_y, x_repeat_mode, y_repeat_mode, alpha}}
{:image_stretched, {image_key, scale_x, scale_y, x_repeat_mode, y_repeat_mode, source_offset_x, source_offset_y, source_width, source_height, angle,alpha}}
  • scale_x is the S (horizontal) scale factor for the image when rendered on the rectangle. 1 is normal, 0.1 would be showing the first tenth of the horizontal parts of the image, 10 would be tiling the horizontal parts 10 times.
  • scale_y is the T (vertical) scale factor for the image when rendered on the rectangle. 1 is normal, 0.1 would be showing the first tenth of the vertical parts of the image, 10 would be tiling the vertical parts 10 times.
  • x_repeat_mode would be one of :repeat, :clamp_to_border, :clamp_to_edge, :mirror.
  • y_repeat_mode would be one of :repeat, :clamp_to_border, :clamp_to_edge, :mirror.
  • source_offset_x and source_offset_y are the offset (in pixels) of the upper-left corner of the subset of the image to use when texturing the rectangle.
  • source_width is the horizontal size, in pixels, of the subset of the image to use when texturing the rectangle.
  • source_height is the vertical size, in pixels, of the subset of the image to use when texturing the rectangle.
  • angle is the CCW rotation of the image in radians prior to sampling.
  • alpha is the [0,1] transparency (fully transparent to fully opaque) of the image to use.

Feature request: Root scene should receive untranslated mouse input

What problem does this feature solve?

It can be confusing to new users that cursor input is not received by the root scene, yet keyboard input is. The current behavior confused me initially and has also confused others (example)

What is your proposed solution?

Allowing the root scene to receive any cursor input that is not captured by any other scene. I think this makes sense logically, although if it doesn't make sense for any reason than maybe it's best to just add a transparent rectangle to the example project to help people with cursor input.

Although an alternative is to educate people on the behavior of mouse input, e.g. in the scenic_new project (ScenicFramework/scenic_new#22)

Button text not centered in button

This seems to be a font issue where button text is not rendered in the center of thee button. This looks
okay normally, but on bigger buttons it is a little strange.

screenshot from 2019-02-27 22-46-39

A possible refactoring of the example code?

First, congratulations on an exceptional achievement. Nicely done.

These days I'm on a mission to create Elixir code with smaller chunks of things, where a chunk could be a module, function, or even expression. Looking through this code, it seems like you're already there.

So I have a small suggestion for the example code generated by new.scenic.example.

Take the primitives code as an example. Right now, it looks like this:

defmodule Xx.Scene.Primitives do
  @moduledoc """
  Sample scene.
  """

  use Scenic.Scene
  alias Scenic.Graph
  import Scenic.Primitives

  alias Xx.Component.Nav
  alias Xx.Component.Notes

  @bird_path :code.priv_dir(:xx)
             |> Path.join("/static/images/cyanoramphus_zealandicus_1849.jpg")
  @bird_hash Scenic.Cache.Hash.file!( @bird_path, :sha )

  @bird_width 100
  @bird_height 128

  @body_offset 80

  @line {{0, 0}, {60, 60}}

  @notes """
    \"Primitives\" shows the various primitives available in Scenic.
    It also shows a sampling of the styles you can apply to them.
  """

  @graph Graph.build(font: :roboto, font_size: 24)
         |> group(
           fn g ->
             g
             |> text("Various primitives and styles", translate: {15, 20})

             # lines
             |> group(
               fn g ->
                 g
                 |> line(@line, stroke: {4, :red})
                 |> line(@line, stroke: {20, :green}, cap: :butt, t: {60, 0})
                 |> line(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0})
               end,
               t: {290, 50}
             )

             # row
             |> group(
               fn g ->
                 g
                 |> triangle({{0, 60}, {50, 0}, {50, 60}}, fill: :khaki, stroke: {4, :green})
                 |> circle(30, fill: :green, stroke: {6, :yellow}, t: {110, 30})
                 |> ellipse({30, 40}, rotate: 0.5, fill: :green, stroke: {4, :gray}, t: {200, 30})
               end,
               t: {15, 50}
             )

             # row
             |> group(
               fn g ->
                 g
                 |> rect({50, 60}, fill: :khaki, stroke: {4, :green})
                 |> rrect({50, 60, 6}, fill: :green, stroke: {6, :yellow}, t: {85, 0})
                 |> quad({{0, 100}, {160, 0}, {300, 110}, {200, 260}},
                   id: :quad,
                   fill: {:linear, {0, 0, 400, 400, :yellow, :purple}},
                   stroke: {10, :khaki},
                   translate: {160, 0},
                   scale: 0.3,
                   pin: {0, 0}
                 )
                 |> sector({100, -0.3, -0.8},
                   stroke: {3, :grey},
                   fill: {:radial, {0, 0, 20, 160, {:yellow, 128}, {:purple, 128}}},
                   translate: {270, 70}
                 )
                 |> arc({100, -0.1, -0.8}, stroke: {6, :orange}, translate: {320, 70})
               end,
               t: {15, 130}
             )

             # bird
             |> rect({@bird_width, @bird_height}, fill: {:image, @bird_hash}, t: {15, 230})

             # text
             |> group(
               fn g ->
                 g
                 |> text("Hello", translate: {0, 40})
                 |> text("World", translate: {90, 40}, fill: :yellow)
                 |> text("Blur", translate: {0, 80}, font_blur: 2)
                 |> text("Shadow", translate: {82, 82}, font_blur: 2, fill: :light_grey)
                 |> text("Shadow", translate: {80, 80})
               end,
               font_size: 40,
               t: {130, 240}
             )

             # twisty path
             |> path(
               [
                 :begin,
                 {:move_to, 0, 0},
                 {:bezier_to, 0, 20, 0, 50, 40, 50},
                 {:bezier_to, 60, 50, 60, 20, 80, 20},
                 {:bezier_to, 100, 20, 110, 0, 120, 0},
                 {:bezier_to, 140, 0, 160, 30, 160, 50}
               ],
               stroke: {2, :red},
               translate: {355, 230},
               rotate: 0.5
             )
           end,
           translate: {15, @body_offset}
         )

         # Nav and Notes are added last so that they draw on top
         |> Nav.add_to_graph(__MODULE__)
         |> Notes.add_to_graph(@notes)

  def init(_, _opts) do
    # load the parrot texture into the cache
    Scenic.Cache.File.load(@bird_path, @bird_hash)

    push_graph(@graph)

    {:ok, @graph}
  end
end

The @graph attribute is scary long, and I constantly messed up brackets when messing with it. So how about continuing the compile-time attribute goodness by splitting it further?

defmodule Me1.Scene.Primitives do
  @moduledoc """
  Sample scene.
  """

  use Scenic.Scene
  alias Scenic.Graph
  import Scenic.Primitives

  alias Me1.Component.Nav
  alias Me1.Component.Notes

  @bird_path :code.priv_dir(:me1)
             |> Path.join("/static/images/cyanoramphus_zealandicus_1849.jpg")
  @bird_hash Scenic.Cache.Hash.file!( @bird_path, :sha )

  @bird_width 100
  @bird_height 128

  @body_offset 80

  @line {{0, 0}, {60, 60}}

  @notes """
    \"Primitives\" shows the various primitives available in Scenic.
    It also shows a sampling of the styles you can apply to them.
  """

  @lines fn g ->
    g
    |> line(@line, stroke: {4, :red})
    |> line(@line, stroke: {20, :green}, cap: :butt, t: {60, 0})
    |> line(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0})
  end

  @triangle_circle_ellipse fn g ->
    g
    |> triangle({{0, 60}, {50, 0}, {50, 60}}, fill: :khaki, stroke: {4, :green})
    |> circle(30, fill: :green, stroke: {6, :yellow}, t: {110, 30})
    |> ellipse({30, 40}, rotate: 0.5, fill: :green, stroke: {4, :gray}, t: {200, 30})
  end

  # or possibly using & function literals??

  @filled_stuff & &1
    |> rect({50, 60}, fill: :khaki, stroke: {4, :green})
    |> rrect({50, 60, 6}, fill: :green, stroke: {6, :yellow}, t: {85, 0})
    |> quad({{0, 100}, {160, 0}, {300, 110}, {200, 260}},
      id: :quad,
      fill: {:linear, {0, 0, 400, 400, :yellow, :purple}},
      stroke: {10, :khaki},
      translate: {160, 0},
      scale: 0.3,
      pin: {0, 0}
    )
    |> sector({100, -0.3, -0.8},
      stroke: {3, :grey},
      fill: {:radial, {0, 0, 20, 160, {:yellow, 128}, {:purple, 128}}},
      translate: {270, 70}
    )
    |> arc({100, -0.1, -0.8}, stroke: {6, :orange}, translate: {320, 70})


  @text & &1
    |> text("Hello", translate: {0, 40})
    |> text("World", translate: {90, 40}, fill: :yellow)
    |> text("Blur", translate: {0, 80}, font_blur: 2)
    |> text("Shadow", translate: {82, 82}, font_blur: 2, fill: :light_grey)
    |> text("Shadow", translate: {80, 80})


  @path &path(&1,
      [
        :begin,
        {:move_to, 0, 0},
        {:bezier_to, 0, 20, 0, 50, 40, 50},
        {:bezier_to, 60, 50, 60, 20, 80, 20},
        {:bezier_to, 100, 20, 110, 0, 120, 0},
        {:bezier_to, 140, 0, 160, 30, 160, 50}
      ],
      stroke: {2, :red},
      translate: {355, 230},
      rotate: 0.5)

  @graph Graph.build(font: :roboto, font_size: 24)
         |> group(
           fn g ->
             g
             |> text("Various primitives and styles", translate: {15, 20})
             |> group(@lines, t: {290, 50})
             |> group(@triangle_circle_ellipse, t: {15, 50})
             |> group(@filled_stuff, t: {15, 130})
             |> rect({@bird_width, @bird_height}, fill: {:image, @bird_hash}, t: {15, 230})
             |> group(@text, font_size: 40, t: {130, 240})
             |> group(@path)
           end,
           translate: {15, @body_offset}
         )

         # Nav and Notes are added last so that they draw on top
         |> Nav.add_to_graph(__MODULE__)
         |> Notes.add_to_graph(@notes)

  def init(_, _opts) do
    # load the parrot texture into the cache
    Scenic.Cache.File.load(@bird_path, @bird_hash)

    push_graph(@graph)

    {:ok, @graph}
  end
end

You can see I switched styles from using fn to using & half way through just to see what each looked like.

Waddya think?

Dave

(ps: I think I get major credit for not showing you my solution using macros... :)

Scenic.Driver.Glfw can't be found when run mix scenic.run

Versions and Environment

elixir -v
Erlang/OTP 21 [erts-10.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.8.1 (compiled with Erlang/OTP 21)


Scenic:

mix deps | grep scenic
* scenic_sensor 0.7.0 (Hex package) (mix)
  locked at 0.7.0 (scenic_sensor) a12aed75
* scenic 0.10.2 (Hex package) (mix)
  locked at 0.10.2 (scenic) f4f0a00e
* scenic_clock 0.10.0 (Hex package) (mix)
  locked at 0.10.0 (scenic_clock) 5be4a87e

OS:
Mac OS 10.13.4 (17E199)

### Steps to reproduce
https://github.com/boydm/scenic_new

### Actual Behavior

mix deps.get
Resolving Hex dependencies...
Dependency resolution completed:
New:
  elixir_make 0.6.0
  font_metrics 0.3.1
  msgpax 2.2.3
  scenic 0.10.2
  scenic_clock 0.10.0
  scenic_driver_glfw 0.10.0
  scenic_sensor 0.7.0
* Getting scenic (Hex package)
* Getting scenic_driver_glfw (Hex package)
* Getting scenic_sensor (Hex package)
* Getting scenic_clock (Hex package)
* Getting elixir_make (Hex package)
* Getting font_metrics (Hex package)
* Getting msgpax (Hex package)

mix scenic.run
==> msgpax
Compiling 8 files (.ex)
Generated msgpax app
==> font_metrics
Compiling 2 files (.ex)
Generated font_metrics app
==> scenic_sensor
Compiling 1 file (.ex)
Generated scenic_sensor app
==> elixir_make
Compiling 1 file (.ex)
Generated elixir_make app
==> scenic
mkdir -p /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../priv
cp -rf static /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../priv/static
mkdir -p /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj
cc -c -I/usr/local/Cellar/erlang/21.3/lib/erlang/usr/include -fPIC -O2 -Wall -Wextra -Wno-unused-parameter -std=c99 -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/line.o c_src/line.c
cc /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/line.o -L/usr/local/Cellar/erlang/21.3/lib/erlang/usr/lib -fPIC -shared  -dynamiclib -undefined dynamic_lookup -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../priv/line.so
cc -c -I/usr/local/Cellar/erlang/21.3/lib/erlang/usr/include -fPIC -O2 -Wall -Wextra -Wno-unused-parameter -std=c99 -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/matrix.o c_src/matrix.c
cc /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/matrix.o -L/usr/local/Cellar/erlang/21.3/lib/erlang/usr/lib -fPIC -shared  -dynamiclib -undefined dynamic_lookup -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../priv/matrix.so
cc -c -I/usr/local/Cellar/erlang/21.3/lib/erlang/usr/include -fPIC -O2 -Wall -Wextra -Wno-unused-parameter -std=c99 -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/texture.o c_src/texture.c
cc /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../obj/texture.o -L/usr/local/Cellar/erlang/21.3/lib/erlang/usr/lib -fPIC -shared  -dynamiclib -undefined dynamic_lookup -o /Users/xman/elixir-learning/my_app/_build/rpi3_dev/lib/scenic/ebin/../priv/texture.so
Compiling 91 files (.ex)
Generated scenic app
==> scenic_clock
Compiling 3 files (.ex)
Generated scenic_clock app
==> my_app
Compiling 11 files (.ex)
Generated my_app app
** (Mix) Could not start application my_app: MyApp.start(:normal, []) returned an error: shutdown: failed to start child: Scenic
    ** (EXIT) shutdown: failed to start child: Scenic.ViewPort.SupervisorTop
        ** (EXIT) shutdown: failed to start child: :main_viewport
            ** (EXIT) shutdown: failed to start child: Scenic.ViewPort.Driver.Supervisor
                ** (EXIT) an exception was raised:
                    ** (ArgumentError) The module Scenic.Driver.Glfw was given as a child to a supervisor but it does not exist.
                        (elixir) lib/supervisor.ex:629: Supervisor.init_child/1
                        (elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
                        (elixir) lib/supervisor.ex:615: Supervisor.init/2
                        (stdlib) supervisor.erl:295: :supervisor.init/1
                        (stdlib) gen_server.erl:374: :gen_server.init_it/2
                        (stdlib) gen_server.erl:342: :gen_server.init_it/6
                        (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Text only uses theme inside components

Checklist

  • [x ] Check other issues and make sure that it is not reported yet.

Versions and Environment

Elixir: 1.8.1-otp-21
Erlang: 21.2.2
Scenic: 0.10.0
OS: MacOS

Steps to reproduce

Graph.build(font_size: 22, font: :roboto_mono, theme: :light)
  |> text("System")
  |> button("System")

Expected Behavior

Text would default to a dark color for the light theme and be visible.

Actual Behavior

Text is not a component, it is a primitive, which means it ignores the theme and renders white by default. The text ends up invisible.
The text inside the button is handled as expected and visible.

Additional Comments

After some discussion with Emilio I believe this works as intended but I'd say it doesn't work the way you'd expect. I think following the theme is the work of the component, not the primitive. But the default way of putting arbitrary text on the screen is using the primitive. So we get no good default for the theming. Would it be reasonable for text to pick up the theme for default text color?

I think there is a potential for UI developer incredulity at why text just doesn't respect the theme setting. Do we want a component that simply wraps text and does the theming? What is that called? A Label? A ThemedText?

Running scenic on raspberry-pi loops UI

Erlang 22.0-rc3
Elixir 1.8.0
Installed with asdf today on a Raspberry Pi 3B+

Steps to reproduce

I installed @axelson 's scenic asteroids and tried running. After folliowing instructions for Ubuntu 18 dependencies and running the game, it goes into a loop. A window appears then flickers away then appears again. The terminal output is spitting rapidly.. ctrl+c interrupt.

Expected Behavior

Expected scenic_asteroids to start up

Actual Behavior

Application does not run correctly.

Stack Trace

from ctrl+c:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Play.Scene.Asteroids\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" <> ..., "    (elixir) Calendar.ISO.from_unix(1221222574, :second)\n    (elixir) lib/calendar/datetime.ex:118: DateTime.from_unix/3\n    (msgpax) lib/msgpax/unpacker.ex:205: Msgpax.Unpacker.unpack_ext/3\n    (msgpax) lib/msgpax/unpacker.ex:140: Msgpax.Unpacker.unpack/6\n    (msgpax) lib/msgpax.ex:143: Msgpax.unpack_slice/2\n    (msgpax) lib/msgpax.ex:213: Msgpax.unpack/2\n    (font_metrics) lib/font_metrics.ex:136: FontMetrics.from_binary/1\n    (scenic) lib/scenic/cache/static/font_metrics.ex:225: Scenic.Cache.Static.FontMetrics.load/3\n"}, Scenic.Scenes.Error, {{"Scenic.Scenes.Error", "%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}", "{{\"Scenic.Scenes.Error\", \"%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}\", \"{{\\\"Scenic.Scenes.Error\\\", \\\"%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}\\\", \\\"{{\\\\\\\"Scenic.Scenes.Error\\\\\\\", \\\\\\\"%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}\\\\\\\", \\\\\\\"{{\\\\\\\\\\\\\\\"Scenic.Scenes.Error\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"{{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Scenic.Scenes.Error\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"%UndefinedFunctionError{arity: 2, function: :from_unix, message: nil, module: Calendar.ISO, reason: nil}\\
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution

Has anyone seen this occur? Scenic Asteroids is a good proof-of-concept for running a game in Scenic. The errors looked to be in Scenic/Elixir so I figured to ask here for help.

Thank you!

Incorrect documentation example for Scenic.Components.text_field/3

I think the examples for Scenic.Components.text_field/3 are not updated. I might be wrong.

graph
|> text_field( {"Sample Text", :text_id}, translate: {20,20} )

graph
|> text_field(
  {"", :pass_id, [type: :password, hint: "Enter password"]},
  translate: {20,20}
)

The updated examples should be as follow:

graph
|> text_field( "Sample Text", id: :text_id, translate: {20,20} )

graph
|> text_field( "", id: :pass_id, type: :password, hint: "Enter password",
  translate: {20,20}
)

The examples code cause the app crash and restart continuously until we manually quit the process by Ctrl-C, which may also be an issue. If it is a concern, would it be better if we can impose limit on the restart attempt caused by such error, so we can avoid the supervisor to crash and restart indefinitely?

To reproduce the issue,

git clone https://github.com/kw7oe/scenic_demo.git
cd scenic_demo
mix deps.get
mix scenic.run

Point me to the right direction if I am wrong, since I am fairly inexperience.

Thanks for the efforts in making this project. Really appreciate it.

Using a custom font fails with `Unknown message: 0x38`

I’m trying to load a custom font like this:

Scenic.Cache.Hash.compute(File.read!(@font_path), :sha) |> IO.inspect()
Scenic.Cache.File.load(@font_path, @font_hash) |> IO.inspect()
Scenic.Cache.File.read(@font_path, @font_hash) |> IO.inspect()

graph =
  Graph.build(font: @font_hash, font_size: 24)

This is the output when using the font:

"cu1h9EqFbnBMyCyDDqtWtMh2lOw"
{:ok, "cu1h9EqFbnBMyCyDDqtWtMh2lOw"}
{:ok,
<<0, 1, 0, 0, 0, 20, 1, 0, 0, 4, 0, 64, 71, 80, 79, 83, 39, 13, 154, 194, 0, 4,
82, 12, 0, 0, 117, 60, 71, 83, 85, 66, 177, 57, 193, 22, 0, 4, 199, 72, 0, 0,
0, 146, 76, 84, 83, 72, ...>>}
Unknown message: 0x38
WARNING Excess message bytes! 313343

So it looks like loading/reading the file works fine, but when I use it I get the error message.
It’s a ttf font.

(I've first posted this on the forum, but as this probably is a bug (or lacking documentation) I'm putting it here as well)

[Design discussion] Move event sending into handler return values.

What if instead of calling send_event/1, we returned a list of events, sort of how we return the new Graph to push?

I'm not sure if this is a proper feature request or whatever, but now that graph-pushing has been moved to handler return value it kind of stuck out to me that event sending isn't, if that makes sense. Please go ahead and close this if it's not interesting to discuss (or the wrong place to have that discussion!)

Support for collision detection?

What problem does this feature solve?

I am working on a simple game to try out scenic. Since scenic already maps an input coordinate through different translations, it would be nice if scenic was also able to accomplish collision detection. In addition to games this might be nice for developing custom responsive ui's.

What is your proposed solution?

Scenic.Graph.collisions(graph) would return all the components that had a collision along with their "final" coordinates.

Notes

Of course it may be reasonable to consider this out of scope for Scenic. It may be too difficult to support permanently.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.