diff --git a/src/LiveSplit.AutoSplittingRuntime/ASR.cs b/src/LiveSplit.AutoSplittingRuntime/ASR.cs index 1ae81b2..ba4d3cb 100644 --- a/src/LiveSplit.AutoSplittingRuntime/ASR.cs +++ b/src/LiveSplit.AutoSplittingRuntime/ASR.cs @@ -607,6 +607,7 @@ public string GetType(ulong index) 2 => "title", 3 => "choice", 4 => "file-select", + 5 => "text-input", _ => "", }; } @@ -680,6 +681,21 @@ public string GetFileSelectFilter(ulong index) return ASRNative.Widgets_get_file_select_filter(ptr, (UIntPtr)index); } + + public string GetTextInput(ulong index, SettingsMapRef settingsMap) + { + if (ptr == IntPtr.Zero) + { + return ""; + } + + if (settingsMap.ptr == IntPtr.Zero) + { + return ""; + } + + return ASRNative.Widgets_get_text_input(ptr, (UIntPtr)index, settingsMap.ptr); + } } public class WidgetsRefMut : WidgetsRef @@ -836,6 +852,8 @@ LogDelegate log public static extern ASRString Widgets_get_choice_option_description(IntPtr self, UIntPtr index, UIntPtr option_index); [DllImport("asr_capi", CallingConvention = CallingConvention.Cdecl)] public static extern ASRString Widgets_get_file_select_filter(IntPtr self, UIntPtr index); + [DllImport("asr_capi", CallingConvention = CallingConvention.Cdecl)] + public static extern ASRString Widgets_get_text_input(IntPtr self, UIntPtr index, IntPtr settings_map); [DllImport("asr_capi", CallingConvention = CallingConvention.Cdecl)] public static extern UIntPtr get_buf_len(); diff --git a/src/LiveSplit.AutoSplittingRuntime/ComponentSettings.cs b/src/LiveSplit.AutoSplittingRuntime/ComponentSettings.cs index 75cc216..e8cdc9b 100644 --- a/src/LiveSplit.AutoSplittingRuntime/ComponentSettings.cs +++ b/src/LiveSplit.AutoSplittingRuntime/ComponentSettings.cs @@ -331,6 +331,59 @@ public void BuildTree() rowIndex++; break; } + case "text-input": + { + if (rowIndex < settingsTable.RowStyles.Count + && settingsTable.GetControlFromPosition(0, rowIndex) is Label exLabel + && exLabel.Text == desc + && exLabel.Margin.Left == margin) + { + toolTip.SetToolTip(exLabel, tooltip); + } + else + { + ClearSettingsTableTail(rowIndex); + var label = new Label + { + Text = desc, + Margin = new Padding(margin, 0, 0, 0) + }; + label.Anchor |= AnchorStyles.Right; + toolTip.SetToolTip(label, tooltip); + settingsTable.Controls.Add(label, 0, settingsTable.RowStyles.Count); + settingsTable.RowStyles.Add(new RowStyle(SizeType.Absolute, label.Height)); + } + + rowIndex++; + + if (rowIndex < settingsTable.RowStyles.Count + && settingsTable.GetControlFromPosition(0, rowIndex) is TextBox exTextBox + && exTextBox.Tag is string exTag + && exTag == widgets.GetKey(i) + && exTextBox.Margin.Left == margin) + { + toolTip.SetToolTip(exTextBox, tooltip); + exTextBox.Text = widgets.GetTextInput(i, previousMap); + } + else + { + ClearSettingsTableTail(rowIndex); + var textBox = new TextBox + { + Tag = widgets.GetKey(i), + Margin = new Padding(margin, 0, 0, 0), + Text = widgets.GetTextInput(i, previousMap) + }; + textBox.Anchor |= AnchorStyles.Right; + toolTip.SetToolTip(textBox, tooltip); + textBox.TextChanged += TextInput_TextChanged; + settingsTable.Controls.Add(textBox, 0, settingsTable.RowStyles.Count); + settingsTable.RowStyles.Add(new RowStyle(SizeType.Absolute, textBox.Height + 5)); + } + + rowIndex++; + break; + } default: { break; @@ -387,6 +440,23 @@ private void Combo_SelectedIndexChanged(object sender, EventArgs e) } } + private void TextInput_TextChanged(object sender, EventArgs e) + { + var textBox = (TextBox)sender; + if (textBox.Tag is not string) + { + return; + } + + if (runtime != null) + { + runtime.SettingsMapSetString((string)textBox.Tag, textBox.Text); + SettingsMap prev = previousMap; + previousMap = runtime.GetSettingsMap(); + prev?.Dispose(); + } + } + private void FileSelect_Click(object sender, EventArgs e) { var button = (Button)sender; diff --git a/src/LiveSplit.AutoSplittingRuntime/x64/asr_capi.dll b/src/LiveSplit.AutoSplittingRuntime/x64/asr_capi.dll index e63052c..b165c9b 100644 Binary files a/src/LiveSplit.AutoSplittingRuntime/x64/asr_capi.dll and b/src/LiveSplit.AutoSplittingRuntime/x64/asr_capi.dll differ diff --git a/src/LiveSplit.AutoSplittingRuntime/x86/asr_capi.dll b/src/LiveSplit.AutoSplittingRuntime/x86/asr_capi.dll index 548b449..7c1a146 100644 Binary files a/src/LiveSplit.AutoSplittingRuntime/x86/asr_capi.dll and b/src/LiveSplit.AutoSplittingRuntime/x86/asr_capi.dll differ diff --git a/src/asr-capi/src/widgets.rs b/src/asr-capi/src/widgets.rs index 403d400..1bcedcf 100644 --- a/src/asr-capi/src/widgets.rs +++ b/src/asr-capi/src/widgets.rs @@ -67,6 +67,7 @@ pub extern "C" fn Widgets_get_type(_this: &Widgets, _index: usize) -> usize { WidgetKind::Title { .. } => 2, WidgetKind::Choice { .. } => 3, WidgetKind::FileSelect { .. } => 4, + WidgetKind::TextInput { .. } => 5, } } #[cfg(not(target_pointer_width = "64"))] @@ -192,6 +193,27 @@ pub extern "C" fn Widgets_get_heading_level(_this: &Widgets, _index: usize) -> u panic!("Index out of bounds") } +#[no_mangle] +pub extern "C" fn Widgets_get_text_input( + _this: &Widgets, + _index: usize, + _settings_map: &SettingsMap, +) -> *const u8 { + #[cfg(target_pointer_width = "64")] + { + let setting = &_this.inner[_index]; + let WidgetKind::TextInput { default_value } = &setting.kind else { + return output_str(""); + }; + match _settings_map.get(&setting.key) { + Some(SettingValue::String(stored)) => output_str(stored), + _ => output_str(default_value), + } + } + #[cfg(not(target_pointer_width = "64"))] + panic!("Index out of bounds") +} + #[no_mangle] pub extern "C" fn Widgets_get_file_select_filter(_this: &Widgets, _index: usize) -> *const u8 { #[cfg(target_pointer_width = "64")]