|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
using CommanderApp.Services;
|
|
|
|
|
|
|
|
|
|
@ -141,6 +141,9 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
OnHomeClicked(this, EventArgs.Empty);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Всегда скроллим после любого действия с клавиатуры
|
|
|
|
|
ScrollToSelectedItem();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -159,6 +162,9 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
var button = RightPanel.Children[e.RightSelectedIndex] as Button;
|
|
|
|
|
button?.Focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Скроллим при изменении состояния
|
|
|
|
|
ScrollToSelectedItem();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetInitialFocus()
|
|
|
|
|
@ -178,6 +184,7 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
if (focused)
|
|
|
|
|
{
|
|
|
|
|
_panelManager.SetSelection(0, true);
|
|
|
|
|
ScrollToSelectedItem();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -188,6 +195,55 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Простой и надежный метод скролла
|
|
|
|
|
private async void ScrollToSelectedItem()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(50); // Небольшая задержка для стабильности
|
|
|
|
|
|
|
|
|
|
if (_panelManager.IsLeftPanelActive)
|
|
|
|
|
{
|
|
|
|
|
if (_panelManager.LeftSelectedIndex >= 0 && _panelManager.LeftSelectedIndex < LeftPanel.Children.Count)
|
|
|
|
|
{
|
|
|
|
|
// Вычисляем позицию для скролла
|
|
|
|
|
var itemHeight = 40; // Высота одного элемента
|
|
|
|
|
var scrollViewHeight = LeftScrollView.Height; // Высота видимой области
|
|
|
|
|
var visibleItems = (int)(scrollViewHeight / itemHeight); // Сколько элементов видно
|
|
|
|
|
|
|
|
|
|
// Вычисляем целевой скролл, чтобы элемент был в середине видимой области
|
|
|
|
|
var targetScrollY = Math.Max(0, (_panelManager.LeftSelectedIndex - visibleItems / 2) * itemHeight);
|
|
|
|
|
|
|
|
|
|
await LeftScrollView.ScrollToAsync(0, targetScrollY, true);
|
|
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"Left scroll: index={_panelManager.LeftSelectedIndex}, targetY={targetScrollY}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (_panelManager.RightSelectedIndex >= 0 && _panelManager.RightSelectedIndex < RightPanel.Children.Count)
|
|
|
|
|
{
|
|
|
|
|
// Вычисляем позицию для скролла
|
|
|
|
|
var itemHeight = 40; // Высота одного элемента
|
|
|
|
|
var scrollViewHeight = RightScrollView.Height; // Высота видимой области
|
|
|
|
|
var visibleItems = (int)(scrollViewHeight / itemHeight); // Сколько элементов видно
|
|
|
|
|
|
|
|
|
|
// Вычисляем целевой скролл, чтобы элемент был в середине видимой области
|
|
|
|
|
var targetScrollY = Math.Max(0, (_panelManager.RightSelectedIndex - visibleItems / 2) * itemHeight);
|
|
|
|
|
|
|
|
|
|
await RightScrollView.ScrollToAsync(0, targetScrollY, true);
|
|
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"Right scroll: index={_panelManager.RightSelectedIndex}, targetY={targetScrollY}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"Scroll error: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Остальные методы без изменений...
|
|
|
|
|
private void OpenSelectedItem()
|
|
|
|
|
{
|
|
|
|
|
var item = _panelManager.SelectedItem;
|
|
|
|
|
@ -302,6 +358,7 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
{
|
|
|
|
|
var firstButton = panel.Children[0] as Button;
|
|
|
|
|
firstButton?.Focus();
|
|
|
|
|
ScrollToSelectedItem();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -327,29 +384,6 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
CornerRadius = 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Устанавливаем тематический цвет текста
|
|
|
|
|
// button.SetAppThemeColor(Button.TextColorProperty, Colors.Black, Colors.White);
|
|
|
|
|
|
|
|
|
|
// Визуальные состояния для фокуса
|
|
|
|
|
var visualStateGroups = new VisualStateGroupList();
|
|
|
|
|
var commonStates = new VisualStateGroup { Name = "CommonStates" };
|
|
|
|
|
|
|
|
|
|
var normalState = new VisualState { Name = "Normal" };
|
|
|
|
|
normalState.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = NormalButtonColor });
|
|
|
|
|
|
|
|
|
|
var focusedState = new VisualState { Name = "Focused" };
|
|
|
|
|
focusedState.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = FocusedButtonColor });
|
|
|
|
|
|
|
|
|
|
var pressedState = new VisualState { Name = "Pressed" };
|
|
|
|
|
pressedState.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = NormalButtonColor });
|
|
|
|
|
|
|
|
|
|
commonStates.States.Add(normalState);
|
|
|
|
|
commonStates.States.Add(focusedState);
|
|
|
|
|
commonStates.States.Add(pressedState);
|
|
|
|
|
visualStateGroups.Add(commonStates);
|
|
|
|
|
|
|
|
|
|
VisualStateManager.SetVisualStateGroups(button, visualStateGroups);
|
|
|
|
|
|
|
|
|
|
// Обработчик клика - выделение при клике, открытие при двойном клике
|
|
|
|
|
button.Clicked += (s, e) => HandleItemClick(button, item, isLeft);
|
|
|
|
|
|
|
|
|
|
@ -387,6 +421,7 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
|
|
|
|
|
// Устанавливаем фокус на кнопку
|
|
|
|
|
button.Focus();
|
|
|
|
|
ScrollToSelectedItem();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Если это двойной клик - открываем/запускаем
|
|
|
|
|
@ -403,7 +438,7 @@ public partial class MainPage : ContentPage, INotifyPropertyChanged
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Команды тулбара
|
|
|
|
|
// Команды тулбара (без изменений)
|
|
|
|
|
private async void OnCopyClicked(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("=== BUTTON: F5 Copy ===");
|
|
|
|
|
|