scenic_driver_renderling/lib/scenic_driver_rendering/window/window.ex

117 lines
3 KiB
Elixir

defmodule Scenic.Driver.Renderling.Window do
@moduledoc """
The Scenic for windowed applications.
"""
alias Scenic.ViewPort
alias Scenic.Driver.Renderling.Window.{Config, Nif}
use Scenic.Driver
require Logger
@default_limit 29
@default_layer 0
@default_opacity 255
@position_schema [
scaled: [type: :boolean, default: false],
centered: [type: :boolean, default: false],
orientation: [type: {:in, [:normal, :left, :right, :upside_down]}, default: :normal]
]
@window_schema [
title: [type: :string, default: "Scenic Window"],
resizeable: [type: :boolean, default: false]
]
@opts_schema [
name: [type: {:or, [:atom, :string]}],
limit_ms: [type: :non_neg_integer, default: @default_limit],
layer: [type: :integer, default: @default_layer],
opacity: [type: :integer, default: @default_opacity],
debug: [type: :boolean, default: false],
debugger: [type: :string, default: ""],
debug_fps: [type: :integer, default: 0],
antialias: [type: :boolean, default: true],
position: [type: :keyword_list, keys: @position_schema, default: []],
window: [type: :keyword_list, keys: @window_schema, default: []],
cursor: [type: :boolean, default: false],
key_map: [type: :atom, default: Scenic.KeyMap.USEnglish],
on_close: [
type:
{:or, [:mfa, {:in, [:restart, :stop_driver, :stop_viewport, :stop_system, :halt_system]}]},
default: :restart
],
input_blacklist: [type: {:list, :string}, default: []]
]
@doc false
@impl Scenic.Driver
def validate_opts(opts), do: NimbleOptions.validate(opts, @opts_schema)
@doc false
@impl true
def init(driver, opts) do
{width, height} = driver.viewport.size
config =
opts
|> Keyword.update(
:window,
[width: width, height: height],
&Keyword.merge(&1, width: width, height: height)
)
|> Config.init()
driver = assign(driver, config: config, server: Nif.init(config))
Process.flag(:trap_exit, true)
Logger.info("#{inspect(__MODULE__)}: start #{inspect(opts)}, pid: #{inspect(self())}")
{:ok, driver}
end
@doc false
@impl true
def update_scene(ids, driver) do
Enum.reduce_while(ids, {:ok, driver}, fn id, {:ok, driver} ->
case ViewPort.get_script(driver.viewport, id) do
{:ok, script} ->
Nif.update_scene(script, id, driver.assigns.server)
{:cont, {:ok, driver}}
{:error, reason} ->
{:halt, {:error, reason}}
end
end)
end
@doc false
@impl true
def reset_scene(driver) do
Nif.reset_scene(driver.assigns.server)
{:ok, driver}
end
@doc false
@impl true
def del_scripts(ids, driver) do
Nif.del_scripts(ids, driver.assigns.server)
{:ok, driver}
end
@doc false
@impl true
def clear_color(color, driver) do
Nif.clear_color(color, driver.assigns.server)
{:ok, driver}
end
@doc false
@impl GenServer
def terminate(_, driver) do
Nif.terminate(driver.assigns.server)
end
end