Hash :
4493aa9d
Author :
Thomas de Grivel
Date :
2022-02-11T13:44:03
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
defmodule Exterm do
@behaviour :wx_object
use Bitwise
@title 'exterm'
@size {800, 600}
def start_link(opts) do
{_ref, _num, _type, pid} = :wx_object.start_link(__MODULE__, opts, [])
{:ok, pid}
end
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]},
type: :worker,
restart: :permanent,
shutdown: 500
}
end
def init(config) do
IO.inspect({&Exterm.init/1, config})
wx = :wx.new(config)
frame = :wxFrame.new(wx, :wx_const.wx_id_any, @title, [{:size, @size}])
:wxWindow.connect(frame, :close_window)
:wxFrame.show(frame)
Exterm.Font.init()
font = Exterm.Font.load()
opts = [{:size, @size}]
gl_attrib = [{:attribList, [:wx_const.wx_gl_rgba,
:wx_const.wx_gl_doublebuffer,
:wx_const.wx_gl_min_red, 8,
:wx_const.wx_gl_min_green, 8,
:wx_const.wx_gl_min_blue, 8,
:wx_const.wx_gl_depth_size, 24, 0]}]
canvas = :wxGLCanvas.new(frame, opts ++ gl_attrib)
:wxGLCanvas.connect(canvas, :size)
:wxWindow.reparent(canvas, frame)
context = :wxGLContext.new(canvas)
:wxGLCanvas.setCurrent(canvas, context)
setup_gl(canvas)
state = %{canvas: canvas,
font: font,
lines: ['$ hello world !']}
:wx.batch(fn -> render(state) end)
{frame, state}
end
def code_change(_, _, state) do
{:stop, :not_implemented, state}
end
def handle_cast(msg, state) do
IO.puts "Cast:"
IO.inspect msg
{:noreply, state}
end
def handle_call(msg, _from, state) do
IO.puts "Call:"
IO.inspect msg
{:reply, :ok, state}
end
def handle_info(:stop, state) do
:wxGLCanvas.destroy(state.canvas)
{:stop, :normal, state}
end
def handle_info(:update, state) do
:wx.batch(fn -> render(state) end)
{:noreply, state}
end
# Example input:
# {:wx, -2006, {:wx_ref, 35, :wxFrame, []}, [], {:wxClose, :close_window}}
def handle_event({:wx, _, _, _, {:wxClose, :close_window}}, state) do
{:stop, :normal, state}
end
def handle_event({:wx, _, _, _, {:wxSize, :size, {width, height}, _}}, state) do
if width != 0 and height != 0 do
resize_gl_scene(width, height)
:wx.batch(fn -> render(state) end)
:ok
end
{:noreply, state}
end
def handle_event(data, state) do
IO.inspect({:handle_event, data, state})
{:noreply, state}
end
def terminate(_reason, state) do
:wxGLCanvas.destroy(state.canvas)
end
defp setup_gl(win) do
{w, h} = :wxWindow.getClientSize(win)
resize_gl_scene(w, h)
#:gl.shadeModel(:gl_const.gl_smooth)
:gl.clearColor(1.0, 1.0, 1.0, 0.0)
#:gl.clearDepth(1.0)
#:gl.enable(:gl_const.gl_depth_test)
#:gl.depthFunc(:gl_const.gl_lequal)
#:gl.hint(:gl_const.gl_perspective_correction_hint, :gl_const.gl_nicest)
:ok
end
defp resize_gl_scene(width, height) do
IO.inspect({:resize_gl_scene, width, height})
:gl.viewport(0, 0, width, height)
:gl.matrixMode(:gl_const.gl_projection)
:gl.loadIdentity()
:gl.ortho(0.0, width + 0.0, height + 0.0, 0.0, -1.0, 1.0)
:gl.matrixMode(:gl_const.gl_modelview)
:gl.loadIdentity()
:ok
end
defp draw(font, lines) do
IO.inspect(:draw)
:gl.clear(:gl_const.gl_color_buffer_bit)
:gl.loadIdentity()
Enum.each(lines, fn line ->
Enum.each(line, fn c when is_integer(c) ->
Exterm.Font.render_glyph(font.regular, c)
end)
end)
:gl.end()
end
defp render(%{canvas: canvas, font: font, lines: lines} = _state) do
draw(font, lines)
:wxGLCanvas.swapBuffers(canvas)
:ok
end
end