defmodule FloUI.Scrollable.ScrollBarController do
alias Scenic.Graph
alias Scenic.Primitive
alias FloUI.Scrollable.Direction
# def on_scroll_position_change(%{assigns: %{scroll_bar_state: %{scrolling: :wheel}}} = scene) do
# drag_control_position = local_scroll_position_vector2(scene)
# graph =
# scene.assigns.graph
# |> Graph.modify(
# :scroll_bar_slider_drag_control,
# &Primitive.put_transform(&1, :translate, drag_control_position)
# )
# Scenic.Scene.assign(scene, graph: graph)
# end
# def on_scroll_position_change(
# %{assigns: %{direction: :vertical, scroll_bar_state: %{scrolling: :dragging}}} =
# scene
# ) do
# drag_control_position = local_scroll_position_vector2(scene)
# graph =
# scene.assigns.graph
# |> Graph.modify(
# :scroll_bar_slider_drag_control,
# &Primitive.put_transform(&1, :translate, drag_control_position)
# )
# Scenic.Scene.assign(scene, graph: graph)
# end
# def on_scroll_position_change(
# %{assigns: %{direction: :horizontal, scroll_bar_state: %{scrolling: :dragging}}} =
# scene
# ) do
# drag_control_position = local_scroll_position_vector2(scene)
# graph =
# scene.assigns.graph
# |> Graph.modify(
# :scroll_bar_slider_drag_control,
# &Primitive.put_transform(&1, :translate, drag_control_position)
# )
# Scenic.Scene.assign(scene, graph: graph)
# end
def on_scroll_position_change(scene) do
drag_control_position = local_scroll_position_vector2(scene)
graph =
scene.assigns.graph
|> Graph.modify(
:scroll_bar_slider_drag_control,
&Primitive.put_transform(&1, :translate, drag_control_position)
)
Scenic.Scene.assign(scene, graph: graph)
end
defp scroll_button_size(%{assigns: %{scroll_bar_state: %{scroll_buttons: nil}}}), do: 0
defp scroll_button_size(%{assigns: %{width: width, height: height, direction: direction}}) do
Direction.return(1, direction)
|> Direction.invert()
|> Direction.multiply(width)
|> Direction.multiply(height)
|> Direction.unwrap()
end
# defp button_width(%{assigns: %{direction: :horizontal}} = scene) do
# Direction.divide(scene.assigns.frame_size, scene.assigns.content_size)
# |> Direction.multiply(scene.assigns.width)
# |> Direction.unwrap()
# end
# defp button_width(scene), do: scene.assigns.opts[:scroll_bar_thickness]
# defp button_height(%{assigns: %{direction: :vertical}} = scene) do
# Direction.divide(scene.assigns.frame_size, scene.assigns.content_size)
# |> Direction.multiply(scene.assigns.height)
# |> Direction.unwrap()
# end
# defp button_height(scene), do: scene.assigns.opts[:scroll_bar_thickness]
defp width_factor(%{assigns: %{content_size: {:horizontal, size}, width: {_, width}}}) do
width / size
end
defp width_factor(_), do: 1
defp height_factor(%{assigns: %{content_size: {:vertical, size}, height: {_, height}}}) do
height / size
end
defp height_factor(_), do: 1
# POSITION CALCULATIONS
# defp scroll_position_vector2(scene) do
# Direction.to_vector_2(scene.assigns.scroll_position)
# end
defp local_scroll_position_vector2(scene) do
world_to_local(scene, scene.assigns.scroll_position)
end
defp world_to_local(scene, {:horizontal, x} = pos) do
pos
|> Direction.map(fn _ -> world_to_local(scene, x) end)
|> Direction.to_vector_2()
end
defp world_to_local(scene, {:vertical, y} = pos) do
pos
|> Direction.map(fn _ -> world_to_local(scene, y) end)
|> Direction.to_vector_2()
end
defp world_to_local(%{assigns: %{direction: direction}} = scene, {x, y}) do
Direction.from_vector_2({x, y}, direction)
|> Direction.map(&world_to_local(scene, &1))
|> Direction.to_vector_2()
end
defp world_to_local(%{assigns: %{direction: :horizontal}} = scene, x),
do: -x * width_factor(scene) + scroll_button_size(scene)
defp world_to_local(%{assigns: %{direction: :vertical}} = scene, y),
do: -y * height_factor(scene) + scroll_button_size(scene)
end