Packages
inky_host_dev
1.0.0
A development convenience for the Inky eInk display library. Allows rendering a window with largely the same behavior as the Inky display during host development. Built with the Erlang wxWidgets minimize dependencies.
Current section
Files
Jump to
Current section
Files
lib/canvas.ex
defmodule InkyHostDev.Canvas do
@behaviour :wx_object
@title "Inky"
def start_link(config) do
:wx_object.start_link(__MODULE__, config, [])
end
def init(%{size: base_size, accent: accent}) do
{width, height} = base_size
wx = :wx.new()
# Allow room for a border
size = {width + 2, height + 2}
frame = :wxFrame.new(wx, -1, @title, size: size)
:wxWindow.setClientSize(frame, size)
:wxFrame.connect(frame, :close_window)
panel = :wxPanel.new(frame, size: size)
:wxPanel.connect(panel, :paint, [:callback])
:wxFrame.show(frame)
state = %{
wx: wx,
panel: panel,
size: base_size,
frame: frame,
accent: accent,
pixels: %{},
border: nil
}
Process.send_after(self(), :refresh, 200)
{frame, state}
end
def handle_call({:draw_pixels, pixels, border}, _from, state) do
state = %{state | pixels: pixels, border: border}
{:reply, nil, state}
end
def handle_info(:refresh, state) do
:wxWindow.refresh(state.frame)
{:noreply, state}
end
defp draw_pixel(_, _, _, _, nil) do
end
defp draw_pixel(dc, x, y, brushes, color) do
brush = brushes[color]
if brush != nil do
:wxDC.setBrush(dc, brush)
:wxDC.drawRectangle(dc, {x, y}, {x + 1, y + 1})
end
end
defp draw_border(dc, width, height, brushes, border) do
for y <- [1, height + 1],
x <- 1..(width + 1),
do: draw_pixel(dc, x, y, brushes, border)
for x <- [1, width + 1],
y <- 1..(height + 1),
do: draw_pixel(dc, x, y, brushes, border)
end
def handle_event({:wx, _, _, _, {:wxSize, :size, _size, _}}, state) do
{:noreply, state}
end
def handle_event({:wx, _, _, _, {:wxClose, :close_window}}, state) do
:wxPanel.destroy(state.panel)
:wxFrame.destroy(state.frame)
:wx.destroy()
{:stop, :normal, state}
end
def handle_sync_event({:wx, _, _, _, {:wxPaint, :paint}}, _, state) do
%{
panel: panel,
frame: frame,
accent: accent,
pixels: pixels,
border: border
} = state
# Must be created, even if not used.
dc = :wxPaintDC.new(panel)
accent_brush_color =
case accent do
:red -> {200, 0, 0}
:yellow -> {200, 200, 0}
_ -> {0, 255, 0}
end
accent_brush = :wxBrush.new(accent_brush_color)
brushes = %{
black: :wxBrush.new({0, 0, 0}),
white: :wxBrush.new({255, 255, 255}),
accent: accent_brush,
red: accent_brush,
yellow: accent_brush
}
{width, height} = state.size
:wxDC.setPen(dc, :wxPen.new({255, 255, 255, 0}))
for y <- 1..height,
x <- 1..width,
do: draw_pixel(dc, x + 1, y + 1, brushes, pixels[{x, y}])
draw_border(dc, width, height, brushes, border)
:wxWindow.show(frame)
:wxPaintDC.destroy(dc)
:wxBrush.destroy(brushes.accent)
Process.send_after(self(), :refresh, 200)
:ok
end
end