defmodule ReflectOS.Core.Sections.Note do use ReflectOS.Kernel.Section, has_children: false alias Scenic.Graph alias Scenic.Assets.Static import Scenic.Primitives, only: [{:text, 3}] import Phoenix.Component, only: [sigil_H: 2] import ReflectOS.Kernel.Typography alias ReflectOS.Kernel.Section.Definition alias ReflectOS.Kernel.{OptionGroup, Option} import ReflectOS.Kernel.Primitives, only: [render_section_label: 3] @section_width 350 embedded_schema do field(:show_label?, :boolean, default: false) field(:label, :string) field(:note, :string) end @impl true def changeset(%__MODULE__{} = section, params \\ %{}) do section |> cast(params, [:show_label?, :label, :note]) end @doc false @impl true def section_definition(), do: %Definition{ name: "Note", icon: """ < !--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--> """, description: fn assigns -> ~H""" This section allows you to to write a simple note for display on ReflectOS. """ end } @impl true def section_options(), do: [ # Label %OptionGroup{ label: "Label", options: [ %Option{ key: :show_label?, label: "Show Label", config: %{ type: "checkbox" } }, %Option{ key: :label, label: "Label Text", hidden: fn %{show_label?: show_label?} -> !show_label? end } ] }, # Descrition %Option{ key: :note, label: "Note", config: %{ type: "textarea", placeholder: "Write your note here!" } } ] @doc false @impl true def init_section(scene, %__MODULE__{} = section_config, opts) do scene = scene |> assign( layout_align: opts[:layout_align], show_label?: section_config.show_label?, label: section_config.label, note: section_config.note ) |> render() {:ok, scene} end # -------------------------------------------------------- defp render(%Scenic.Scene{} = scene) do graph = render_graph(scene.assigns) scene |> push_section(graph) end defp render_graph(%{ layout_align: layout_align, show_label?: show_label?, label: label, note: note }) do graph = if is_binary(note) do {:ok, {Static.Font, fm}} = Static.meta(:roboto) wrapped = FontMetrics.wrap(note, @section_width, 32, fm) Graph.build() |> text( wrapped, [ id: :note, text_base: :top, text_align: :left, t: {0, 0} ] |> h7() ) else Graph.build() end graph |> render_section_label(%{show_label?: show_label?, label: label}, align: layout_align ) end end