Packages
Terminal emulation and driver infrastructure for Raxol. ANSI parsing, screen buffers, command processing, cursor management, input handling, session management, and termbox2 NIF integration.
Current section
Files
Jump to
Current section
Files
lib/raxol/terminal/window.ex
defmodule Raxol.Terminal.Window do
@moduledoc """
Represents a terminal window with its properties and state.
This module provides functionality for managing terminal windows, including:
* Window creation and configuration
* State management (active, inactive, minimized, maximized)
* Size and position control
* Parent-child window relationships
* Terminal emulator integration
## Window States
* `:active` - Window is currently focused
* `:inactive` - Window is not focused
* `:minimized` - Window is minimized
* `:maximized` - Window is maximized
## Usage
```elixir
# Create a new window with default size
window = Window.new(Config.new())
# Create a window with custom dimensions
window = Window.new(100, 50)
# Update window title
{:ok, window} = Window.set_title(window, "My Terminal")
```
"""
alias Raxol.Terminal.{Config, Emulator}
alias Raxol.Terminal.Emulator.Struct, as: EmulatorStruct
@type window_state :: :active | :inactive | :minimized | :maximized
@type window_position :: {integer(), integer()}
@type window_size :: {integer(), integer()}
@type t :: %__MODULE__{
id: String.t() | nil,
title: String.t(),
icon_name: String.t(),
font: String.t(),
cursor_shape: String.t(),
clipboard: String.t(),
emulator: EmulatorStruct.t(),
config: Config.t(),
state: window_state(),
position: window_position(),
size: window_size(),
width: integer(),
height: integer(),
previous_size: window_size() | nil,
parent: String.t() | nil,
children: [String.t()]
}
defstruct [
:id,
title: "Terminal",
icon_name: "Terminal",
font: "monospace",
cursor_shape: "block",
clipboard: "",
emulator: nil,
config: nil,
state: :inactive,
position: {0, 0},
size: {80, 24},
width: 80,
height: 24,
previous_size: nil,
parent: nil,
children: []
]
@doc """
Creates a new window with the given configuration.
## Parameters
* `config` - Terminal configuration (Config.t())
## Returns
* A new window instance with the specified configuration
## Examples
iex> config = Config.new()
iex> window = Window.new(config)
iex> window.size
{80, 24}
"""
def new(config) do
{width, height} = Config.get_dimensions(config)
emulator = EmulatorStruct.new(width, height)
%__MODULE__{
config: config,
emulator: emulator,
size: {width, height},
width: width,
height: height
}
end
@doc """
Creates a new window with custom dimensions.
## Parameters
* `width` - Window width in characters (positive integer)
* `height` - Window height in characters (positive integer)
## Returns
* A new window instance with the specified dimensions
## Examples
iex> window = Window.new(100, 50)
iex> window.size
{100, 50}
"""
def new(width, height)
when is_integer(width) and is_integer(height) and width > 0 and height > 0 do
config = Config.new(width, height)
new(config)
end
@doc """
Updates the window title.
## Parameters
* `window` - The window to update
* `title` - New window title
## Returns
* `{:ok, updated_window}` - Title updated successfully
* `{:error, reason}` - Failed to update title
## Examples
iex> window = Window.new(80, 24)
iex> {:ok, window} = Window.set_title(window, "My Terminal")
iex> window.title
"My Terminal"
"""
def set_title(%__MODULE__{} = window, title) when is_binary(title) do
{:ok, %{window | title: title}}
end
@doc """
Updates the window position.
"""
def set_position(%__MODULE__{} = window, x, y)
when is_integer(x) and is_integer(y) do
{:ok, %{window | position: {x, y}}}
end
@doc """
Updates the window size.
"""
def set_size(%__MODULE__{} = window, width, height)
when is_integer(width) and is_integer(height) and width > 0 and height > 0 do
previous_size = window.size
emulator = Emulator.resize(window.emulator, width, height)
{:ok,
%{
window
| size: {width, height},
width: width,
height: height,
previous_size: previous_size,
emulator: emulator
}}
end
@doc """
Updates the window state.
"""
def set_state(%__MODULE__{} = window, state)
when state in [:active, :inactive, :minimized, :maximized] do
{:ok, %{window | state: state}}
end
@doc """
Sets the parent window.
"""
def set_parent(%__MODULE__{} = window, parent_id) when is_binary(parent_id) do
{:ok, %{window | parent: parent_id}}
end
@doc """
Adds a child window.
"""
def add_child(%__MODULE__{} = window, child_id) when is_binary(child_id) do
{:ok, %{window | children: [child_id | window.children]}}
end
@doc """
Removes a child window.
"""
def remove_child(%__MODULE__{} = window, child_id) when is_binary(child_id) do
{:ok, %{window | children: List.delete(window.children, child_id)}}
end
@doc """
Restores the previous window size.
"""
def restore_size(%__MODULE__{} = window) do
case window.previous_size do
nil -> {:ok, window}
{width, height} -> set_size(window, width, height)
end
end
@doc """
Gets the window's current dimensions.
"""
def get_dimensions(%__MODULE__{} = window) do
{:ok, window.size}
end
@doc """
Gets the window's current position.
"""
def get_position(%__MODULE__{} = window) do
{:ok, window.position}
end
@doc """
Gets the window's current state.
"""
def get_state(%__MODULE__{} = window) do
{:ok, window.state}
end
@doc """
Gets the window's child windows.
"""
def get_children(%__MODULE__{} = window) do
{:ok, window.children}
end
@doc """
Gets the window's parent window.
"""
def get_parent(%__MODULE__{} = window) do
{:ok, window.parent}
end
@doc """
Updates the window's icon name.
"""
def set_icon_name(%__MODULE__{} = window, name) when is_binary(name) do
{:ok, %{window | icon_name: name}}
end
@doc """
Updates the window's font.
"""
def set_font(%__MODULE__{} = window, font) when is_binary(font) do
{:ok, %{window | font: font}}
end
@doc """
Updates the window's cursor shape.
"""
def set_cursor_shape(%__MODULE__{} = window, shape) when is_binary(shape) do
%{window | cursor_shape: shape}
end
@doc """
Updates the window's clipboard content.
"""
def set_clipboard(%__MODULE__{} = window, content) when is_binary(content) do
%{window | clipboard: content}
end
@doc """
Gets the window's clipboard content.
"""
def get_clipboard(%__MODULE__{} = window) do
window.clipboard
end
@doc """
Gets the window's icon name.
"""
def get_icon_name(%__MODULE__{} = window) do
window.icon_name
end
@doc """
Gets the window's font.
"""
def get_font(%__MODULE__{} = window) do
window.font
end
@doc """
Gets the window's cursor shape.
"""
def get_cursor_shape(%__MODULE__{} = window) do
window.cursor_shape
end
@doc """
Gets the window's working directory.
"""
def get_working_directory(%__MODULE__{} = _window) do
File.cwd!()
end
@doc """
Sets the window's working directory.
"""
def set_working_directory(%__MODULE__{}, _dir) do
{:error, :working_directory_not_supported}
end
@doc """
Gets a hyperlink by ID.
"""
def get_hyperlink(%__MODULE__{}, _id) do
nil
end
@doc """
Sets a hyperlink with the given ID and URL.
"""
def set_hyperlink(%__MODULE__{}, _id, _url) do
{:error, :hyperlinks_not_supported}
end
@doc """
Clears a hyperlink by ID.
"""
def clear_hyperlink(%__MODULE__{}, _id) do
{:error, :hyperlinks_not_supported}
end
@doc """
Gets the window's current size.
"""
def get_size(%__MODULE__{} = window) do
window.size
end
end