Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions capi/bind_gen/src/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,16 +599,16 @@ export interface TextComponentStateJson {
display_two_rows: boolean,
/**
* The color of the left part of the split up text or the whole text if
* it's not split up. If `None` is specified, the color is taken from the
* it's not split up. If null is specified, the color is taken from the
* layout.
*/
left_center_color: Color,
left_center_color: Color | null,
/**
* The color of the right part of the split up text. This can be ignored if
* the text is not split up. If `None` is specified, the color is taken
* the text is not split up. If `null` is specified, the color is taken
* from the layout.
*/
right_color: Color,
right_color: Color | null,
/** The text to show for the component. */
text: TextComponentStateText,
}
Expand Down Expand Up @@ -671,12 +671,27 @@ export interface DetailedTimerComponentComparisonStateJson {
* properly.
*/
export interface LayoutEditorStateJson {
/** The name of all the components in the layout. */
/** The name of all the components in the layout, including those nested
* inside groups. */
components: string[],
/** The indentation level of each component (0 = top level, 1 = inside a
* group, etc.). */
indent_levels: number[],
/** Whether each component is an empty group placeholder. */
is_placeholder: boolean[],
/** Describes which actions are currently available. */
buttons: LayoutEditorButtonsJson,
/** The index of the currently selected component. */
/** The flat index of the currently selected component. */
selected_component: number,
/**
* The layout direction at the selected component's position. This is the
* direction of the container that the selected component belongs to. A
* component added at this position would be laid out in this direction. For
* example, in a vertical root layout this is "Vertical" at the top level.
* Adding a group here creates a row (horizontal), adding a row's
* placeholder creates a column (vertical), and so on.
*/
layout_direction: LayoutDirection,
/**
* A generic description of the settings available for the selected
* component and their current values.
Expand Down Expand Up @@ -710,6 +725,11 @@ export interface LayoutEditorButtonsJson {
* the last component is selected, it can't be moved.
*/
can_move_down: boolean,
/**
* Describes whether the currently selected component can be duplicated.
* Placeholders can't be duplicated.
*/
can_duplicate: boolean,
}

/** A generic description of the settings available and their current values. */
Expand Down Expand Up @@ -740,6 +760,7 @@ export interface SettingsDescriptionFieldJson {
export type SettingsDescriptionValueJson =
{ Bool: boolean } |
{ UInt: number } |
{ OptionalUInt: number | null } |
{ Int: number } |
{ String: string } |
{ OptionalString: string | null } |
Expand Down
57 changes: 57 additions & 0 deletions capi/src/group_component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! A Component Group groups multiple components together and lays them out
//! in the opposite direction to the parent, enabling nested layout hierarchies.

use crate::component::OwnedComponent;
use livesplit_core::component::group::Component as GroupComponent;

/// type
pub type OwnedGroupComponent = Box<GroupComponent>;

/// Creates a new empty Group Component.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_new() -> OwnedGroupComponent {
Box::new(GroupComponent::new())
}

/// drop
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_drop(this: OwnedGroupComponent) {
drop(this);
}

/// Converts the Group Component into a generic component suitable for using
/// with a layout.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_into_generic(this: OwnedGroupComponent) -> OwnedComponent {
Box::new((*this).into())
}

/// Adds a component to the end of the group.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_add_component(
this: &mut GroupComponent,
component: OwnedComponent,
) {
this.components.push(*component);
}

/// Returns the number of components in the group.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_len(this: &GroupComponent) -> usize {
this.components.len()
}

/// Returns the size override of the group. In horizontal mode this is the
/// height, in vertical mode it is the width. 0xFFFFFFFF means automatic sizing.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_size(this: &GroupComponent) -> u32 {
this.size.unwrap_or(u32::MAX)
}

/// Sets the size override of the group. In horizontal mode this sets the
/// height, in vertical mode it sets the width. 0xFFFFFFFF means automatic
/// sizing.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponent_set_size(this: &mut GroupComponent, size: u32) {
this.size = if size != u32::MAX { Some(size) } else { None };
}
41 changes: 41 additions & 0 deletions capi/src/group_component_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! The state object describes the information to visualize for this component.

use livesplit_core::{component::group::State as GroupComponentState, layout::ComponentState};
use std::os::raw::c_char;

/// Returns the number of components in a Group State.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponentState_len(this: &GroupComponentState) -> usize {
this.components.len()
}

/// Returns a string describing the type of the component at the specified
/// index within a Group State.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponentState_component_type(
this: &GroupComponentState,
index: usize,
) -> *const c_char {
(match this.components[index] {
ComponentState::BlankSpace(_) => "BlankSpace\0",
ComponentState::DetailedTimer(_) => "DetailedTimer\0",
ComponentState::Graph(_) => "Graph\0",
ComponentState::KeyValue(_) => "KeyValue\0",
ComponentState::Separator(_) => "Separator\0",
ComponentState::Splits(_) => "Splits\0",
ComponentState::Text(_) => "Text\0",
ComponentState::Timer(_) => "Timer\0",
ComponentState::Title(_) => "Title\0",
ComponentState::Group(_) => "Group\0",
})
.as_ptr()
.cast()
}

/// Returns the size override of a Group State. In horizontal mode this is the
/// height, in vertical mode it is the width. 0xFFFFFFFF means automatic
/// sizing.
#[unsafe(no_mangle)]
pub extern "C" fn GroupComponentState_size(this: &GroupComponentState) -> u32 {
this.size.unwrap_or(u32::MAX)
}
32 changes: 31 additions & 1 deletion capi/src/layout_editor_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ pub extern "C" fn LayoutEditorState_component_text(
///
/// The bits are as follows:
///
/// * `0x08` - Can duplicate the current component
/// * `0x04` - Can remove the current component
/// * `0x02` - Can move the current component up
/// * `0x01` - Can move the current component down
#[unsafe(no_mangle)]
pub extern "C" fn LayoutEditorState_buttons(this: &LayoutEditorState) -> u8 {
((this.buttons.can_remove as u8) << 2)
((this.buttons.can_duplicate as u8) << 3)
| ((this.buttons.can_remove as u8) << 2)
| ((this.buttons.can_move_up as u8) << 1)
| this.buttons.can_move_down as u8
}
Expand Down Expand Up @@ -94,3 +96,31 @@ pub extern "C" fn LayoutEditorState_field_value(
&this.general_settings.fields[index].value
}
}

/// Returns the indentation level of the component at the specified index.
/// 0 means top level, 1 means inside a group, etc.
#[unsafe(no_mangle)]
pub extern "C" fn LayoutEditorState_component_indent_level(
this: &LayoutEditorState,
index: usize,
) -> u32 {
this.indent_levels[index]
}

/// Returns whether the component at the specified index is a placeholder for
/// an empty group rather than an actual component.
#[unsafe(no_mangle)]
pub extern "C" fn LayoutEditorState_component_is_placeholder(
this: &LayoutEditorState,
index: usize,
) -> bool {
this.is_placeholder[index]
}

/// Returns the layout direction of the selected component's container. This
/// indicates whether a new group added at this position would become a row or
/// column.
#[unsafe(no_mangle)]
pub extern "C" fn LayoutEditorState_layout_direction(this: &LayoutEditorState) -> u8 {
this.layout_direction as u8
}
20 changes: 17 additions & 3 deletions capi/src/layout_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use livesplit_core::{
component::{
blank_space::State as BlankSpaceComponentState,
detailed_timer::State as DetailedTimerComponentState, graph::State as GraphComponentState,
key_value::State as KeyValueComponentState, separator::State as SeparatorComponentState,
splits::State as SplitsComponentState, text::State as TextComponentState,
timer::State as TimerComponentState, title::State as TitleComponentState,
group::State as GroupComponentState, key_value::State as KeyValueComponentState,
separator::State as SeparatorComponentState, splits::State as SplitsComponentState,
text::State as TextComponentState, timer::State as TimerComponentState,
title::State as TitleComponentState,
},
layout::{ComponentState, LayoutState},
};
Expand Down Expand Up @@ -64,6 +65,7 @@ pub extern "C" fn LayoutState_component_type(this: &LayoutState, index: usize) -
ComponentState::Text(_) => "Text\0",
ComponentState::Timer(_) => "Timer\0",
ComponentState::Title(_) => "Title\0",
ComponentState::Group(_) => "Group\0",
})
.as_ptr()
.cast()
Expand Down Expand Up @@ -176,3 +178,15 @@ pub extern "C" fn LayoutState_component_as_title(
_ => panic!("wrong component state type"),
}
}

/// Gets the Group component state at the specified index.
#[unsafe(no_mangle)]
pub extern "C" fn LayoutState_component_as_group(
this: &LayoutState,
index: usize,
) -> &GroupComponentState {
match &this.components[index] {
ComponentState::Group(x) => x,
_ => panic!("wrong component state type"),
}
}
2 changes: 2 additions & 0 deletions capi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub mod fuzzy_list;
pub mod general_layout_settings;
pub mod graph_component;
pub mod graph_component_state;
pub mod group_component;
pub mod group_component_state;
pub mod hotkey_config;
pub mod hotkey_system;
pub mod image_cache;
Expand Down
18 changes: 18 additions & 0 deletions capi/src/setting_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ pub extern "C" fn SettingValue_from_uint(value: u32) -> OwnedSettingValue {
Box::new((value as u64).into())
}

/// Creates a new setting value from an optional unsigned integer. A value of
/// 0xFFFFFFFF means that the value is empty and has no unsigned integer.
#[unsafe(no_mangle)]
pub extern "C" fn SettingValue_from_optional_uint(value: u32) -> OwnedSettingValue {
let v = if value == u32::MAX {
None
} else {
Some(value as u64)
};
Box::new(v.into())
}

/// Creates a new empty setting value that has the type `optional uint`.
#[unsafe(no_mangle)]
pub extern "C" fn SettingValue_from_optional_empty_uint() -> OwnedSettingValue {
Box::new(None::<u64>.into())
}

/// Creates a new setting value from a signed integer.
#[unsafe(no_mangle)]
pub extern "C" fn SettingValue_from_int(value: i32) -> OwnedSettingValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn resolve_network_drive_path(drive: u8, remote_buffer: &mut Vec<u16>) -> Option
// least up until the nul-terminator.
unsafe {
// There should always be a nul-terminator, but if there isn't,
// it's better if we return `None` than read out of bounds /
// it's better if we return [`None`] than read out of bounds /
// uninitialized bytes.
let len = remote_buffer
.spare_capacity_mut()
Expand Down
4 changes: 2 additions & 2 deletions crates/livesplit-auto-splitting/src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub trait Timer: Send + 'static {
/// Returns the current state of the timer.
fn state(&self) -> TimerState;
/// Accesses the index of the split the attempt is currently on.
/// If there's no attempt in progress, `None` is returned instead.
/// If there's no attempt in progress, [`None`] is returned instead.
/// This returns an index that is equal to the amount of segments
/// when the attempt is finished, but has not been reset.
/// So you need to be careful when using this value for indexing.
Expand All @@ -46,7 +46,7 @@ pub trait Timer: Send + 'static {
/// Returns `Some(true)` if the segment was splitted,
/// or `Some(false)` if skipped.
/// If `idx` is greater than or equal to the current split index,
/// `None` is returned instead.
/// [`None`] is returned instead.
fn segment_splitted(&self, idx: usize) -> Option<bool>;
/// Starts the timer.
fn start(&mut self);
Expand Down
2 changes: 1 addition & 1 deletion src/comparison/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub fn or_current<'a>(comparison: Option<&'a str>, timer: &'a Timer) -> &'a str
}

/// Tries to resolve the given comparison based on a Timer object. If either
/// `None` is given or the comparison doesn't exist, `None` is returned.
/// [`None`] is given or the comparison doesn't exist, [`None`] is returned.
/// Otherwise the comparison name stored in the Timer is returned by reference.
pub fn resolve<'a>(comparison: &Option<String>, timer: &'a Timer) -> Option<&'a str> {
let comparison = comparison.as_ref()?;
Expand Down
2 changes: 1 addition & 1 deletion src/comparison/none.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Defines the Comparison Generator for the `None` comparison. The `None`
//! Defines the Comparison Generator for the [`None`] comparison. The `None`
//! Comparison intentionally leaves all split times empty.

use super::ComparisonGenerator;
Expand Down
4 changes: 2 additions & 2 deletions src/component/current_comparison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ pub struct Settings {
/// Specifies whether to display the name of the component and its value in
/// two separate rows.
pub display_two_rows: bool,
/// The color of the label. If `None` is specified, the color is taken from
/// The color of the label. If [`None`] is specified, the color is taken from
/// the layout.
pub label_color: Option<Color>,
/// The color of the value. If `None` is specified, the color is taken from
/// The color of the value. If [`None`] is specified, the color is taken from
/// the layout.
pub value_color: Option<Color>,
}
Expand Down
4 changes: 2 additions & 2 deletions src/component/current_pace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ pub struct Settings {
/// Specifies whether to display the name of the component and its value in
/// two separate rows.
pub display_two_rows: bool,
/// The color of the label. If `None` is specified, the color is taken from
/// The color of the label. If [`None`] is specified, the color is taken from
/// the layout.
pub label_color: Option<Color>,
/// The color of the value. If `None` is specified, the color is taken from
/// The color of the value. If [`None`] is specified, the color is taken from
/// the layout.
pub value_color: Option<Color>,
/// The accuracy of the time shown.
Expand Down
2 changes: 1 addition & 1 deletion src/component/delta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub struct Settings {
/// Specifies whether to display the name of the component and its value in
/// two separate rows.
pub display_two_rows: bool,
/// The color of the label. If `None` is specified, the color is taken from
/// The color of the label. If [`None`] is specified, the color is taken from
/// the layout.
pub label_color: Option<Color>,
/// Specifies if the decimals should not be shown anymore when the
Expand Down
Loading
Loading