Compare commits

...

34 Commits

Author SHA1 Message Date
Evan Husted
5a3eac99d6 change all grid RowDefinitions/ColumnDefinitions to direct property setters 2025-03-02 17:50:40 -06:00
Evan Husted
e8071e9c43 slight settings window default height bump 2025-03-02 16:11:11 -06:00
Evan Husted
eec39806e0 optimize spacing 2025-03-02 16:11:11 -06:00
Evan Husted
a65acae4aa Restyle stick visualizer 2025-03-02 16:11:11 -06:00
Evan Husted
2a97c00a55 Merge branch 'master' into xeyes 2025-03-02 15:44:26 -06:00
Danik2343
e104ee6be3 Update: Russian Language (Some missing strings) (#732) 2025-02-27 16:53:18 -06:00
Evan Husted
e8f6931d5f Merge branch 'master' into xeyes 2025-02-26 20:01:14 -06:00
Nicola
e65d1ec6c9 JoyCon to Joy-Con (#729)
Joy-Con is the official name
2025-02-26 20:00:35 -06:00
Evan Husted
534f92506b misc: chore: Add warning logs for invalid ips patch attempts 2025-02-26 02:31:18 -06:00
Daniel Nylander
10d20c1ae3 Update Swedish locale (#720) 2025-02-26 02:02:07 -06:00
Evan Husted
e294a79975 UI: dev: [ci skip] Add Avalonia DevTools support to all Windows defined by Ryujinx, accessible via Ctrl + F12 when running in Debug. 2025-02-25 23:12:57 -06:00
Evan Husted
ec06a86899 UI: Increase default size for setting windows to include autoload setting & the bottom of the input settings 2025-02-25 22:51:26 -06:00
Evan Husted
e914e94ad3 Merge branch 'master' into xeyes 2025-02-23 17:30:41 -06:00
Evan Husted
8a6f806dda Merge branch 'master' into xeyes 2025-02-12 16:34:47 -06:00
Evan Husted
15d589c455 Merge branch 'master' into xeyes 2025-02-11 22:55:43 -06:00
Evan Husted
3262020e18 Merge branch 'master' into xeyes 2025-02-07 21:35:51 -06:00
Evan Husted
a3afebd3a2 Merge branch 'master' into xeyes 2025-02-05 14:59:03 -06:00
Evan Husted
24e88e2485 Merge branch 'master' into xeyes 2025-01-29 02:48:51 -06:00
Evan Husted
3b447b764e Merge branch 'master' into xeyes 2025-01-28 01:45:49 -06:00
Evan Husted
849fd0199e Merge branch 'master' into xeyes 2025-01-26 17:33:58 -06:00
Evan Husted
57e26114e8 Merge branch 'master' into xeyes 2025-01-25 21:56:40 -06:00
Evan Husted
6a283190b3 Add the controller image back 2025-01-24 22:24:02 -06:00
MutantAura
85547874c8 Consolidate most logic into StickVisualizer. 2025-01-24 20:08:58 -06:00
MutantAura
16ca8e5005 Move most logic into new StickVisualizer class and add keyboard support. 2025-01-24 20:01:36 -06:00
MutantAura
cfa5ad0757 Simplfy clamping and fix bug on window close. 2025-01-24 19:58:17 -06:00
MutantAura
43ece083b2 Move some backing fields to match others.
formatting pt.2
2025-01-24 19:57:11 -06:00
MutantAura
e1f5c501b0 Fix some issues with stick magnitude. 2025-01-24 19:56:21 -06:00
MutantAura
ffe366d953 Cleanup AXAML and hide sticks when only one is present on guest controller. 2025-01-24 19:52:57 -06:00
MutantAura
75c7a29278 style and analyzers 2025-01-24 19:52:52 -06:00
MutantAura
3a0d9c1435 whitespace 2025-01-24 19:52:47 -06:00
MutantAura
93d1476a2a Remove unused grid definitions. 2025-01-24 19:52:39 -06:00
MutantAura
ce13830063 Clean up some magic numbers between code and axaml. 2025-01-24 19:52:24 -06:00
MutantAura
aa3f2824e0 Polish the aesthetic and include deadzone visualization. 2025-01-24 19:51:44 -06:00
MutantAura
d2bb580aea Initial implementation of analog stick visualization. 2025-01-24 19:50:09 -06:00
37 changed files with 660 additions and 400 deletions

View File

@@ -97,7 +97,7 @@ If you are planning to contribute or just want to learn more about this project
- **Input** - **Input**
We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers. We currently have support for keyboard, mouse, touch input, Joy-Con input support, and nearly all controllers.
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required. Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
In all scenarios, you can set up everything inside the input configuration menu. In all scenarios, you can set up everything inside the input configuration menu.

View File

@@ -71,16 +71,24 @@ namespace Ryujinx.HLE.Loaders.Mods
int patchOffset = (int)offset; int patchOffset = (int)offset;
int patchSize = patch.Length; int patchSize = patch.Length;
if (patchOffset < protectedOffset || patchOffset > memory.Length) if (patchOffset < protectedOffset)
{ {
continue; // Add warning? Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch protected memory ({patchOffset:x} is within protected boundary of {protectedOffset:x}).");
continue;
}
if (patchOffset > memory.Length)
{
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch out of bounds memory (offset {patchOffset} ({patchOffset:x}) exceeds memory buffer length {memory.Length}).");
continue;
} }
patchOffset -= protectedOffset; patchOffset -= protectedOffset;
if (patchOffset + patchSize > memory.Length) if (patchOffset + patchSize > memory.Length)
{ {
patchSize = memory.Length - patchOffset; // Add warning? Logger.Warning?.Print(LogClass.ModLoader, $"Patch offset ({patchOffset:x}) + size ({patchSize}) is greater than the size of the memory buffer ({memory.Length}). Attempting to fix this...");
patchSize = memory.Length - patchOffset;
} }
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}"); Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");

View File

@@ -464,7 +464,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Abrir Pasta de Capturas de Tela", "pt_BR": "Abrir Pasta de Capturas de Tela",
"ru_RU": "Открыть папку со скриншотами", "ru_RU": "Открыть папку со скриншотами",
"sv_SE": "", "sv_SE": "Öppna skärmbildsmappen",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Відкрити теку скріншотів", "uk_UA": "Відкрити теку скріншотів",
@@ -1564,7 +1564,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Desenvolvido por {0}", "pt_BR": "Desenvolvido por {0}",
"ru_RU": "Разработана {0}", "ru_RU": "Разработана {0}",
"sv_SE": "", "sv_SE": "Utvecklat av {0}",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Розроблено: {0}", "uk_UA": "Розроблено: {0}",
@@ -1864,7 +1864,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Compatibilidade:", "pt_BR": "Compatibilidade:",
"ru_RU": "Совместимость:", "ru_RU": "Совместимость:",
"sv_SE": "", "sv_SE": "Kompatibilitet:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Сумісність:", "uk_UA": "Сумісність:",
@@ -1889,7 +1889,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "ID do Título:", "pt_BR": "ID do Título:",
"ru_RU": "ID приложения", "ru_RU": "ID приложения",
"sv_SE": "", "sv_SE": "Titel-id:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "ID гри:", "uk_UA": "ID гри:",
@@ -1914,7 +1914,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Jogos Hospedados: {0}", "pt_BR": "Jogos Hospedados: {0}",
"ru_RU": "Запущенно игр: {0}", "ru_RU": "Запущенно игр: {0}",
"sv_SE": "", "sv_SE": "Värdskap för spel: {0}",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Розміщені ігри: {0}", "uk_UA": "Розміщені ігри: {0}",
@@ -1939,7 +1939,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Jogadores Online: {0}", "pt_BR": "Jogadores Online: {0}",
"ru_RU": "Игроков онлайн: {0}", "ru_RU": "Игроков онлайн: {0}",
"sv_SE": "", "sv_SE": "Online-spelare: {0}",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Гравців онлайн: {0}", "uk_UA": "Гравців онлайн: {0}",
@@ -2289,7 +2289,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Limpar Cache PPTC", "pt_BR": "Limpar Cache PPTC",
"ru_RU": "Очистить кэш PPTC", "ru_RU": "Очистить кэш PPTC",
"sv_SE": "", "sv_SE": "Rensa PPTC-cache",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Очистити кеш PPTC", "uk_UA": "Очистити кеш PPTC",
@@ -2314,7 +2314,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Apaga os arquivos de cache PPTC do aplicativo", "pt_BR": "Apaga os arquivos de cache PPTC do aplicativo",
"ru_RU": "Удаляет все файлы кэша PPTC для приложения", "ru_RU": "Удаляет все файлы кэша PPTC для приложения",
"sv_SE": "", "sv_SE": "Tar bort alla PPTC-cachefiler för applikationen",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Видаляє всі файли кешу PPTC для застосунку", "uk_UA": "Видаляє всі файли кешу PPTC для застосунку",
@@ -2763,7 +2763,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Создать пользовательскую конфигурацию",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -2788,7 +2788,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Изменить пользовательскую конфигурацию",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -2863,7 +2863,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Отредактировать существующую независимую конфигурацию для выбранной игры.",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -2889,7 +2889,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Mostrar Dados de Compatibilidade", "pt_BR": "Mostrar Dados de Compatibilidade",
"ru_RU": "Показать записи о совместимости", "ru_RU": "Показать записи о совместимости",
"sv_SE": "", "sv_SE": "Visa kompatibilitetspost",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Iнформація про сумісність", "uk_UA": "Iнформація про сумісність",
@@ -2914,7 +2914,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.", "pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.",
"ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.", "ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.",
"sv_SE": "", "sv_SE": "Visa valt spel i kompatibilitetslistan som du normalt sett kan komma åt via hjälpmenyn.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.", "uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.",
@@ -2939,7 +2939,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Mostrar Informações do Jogo", "pt_BR": "Mostrar Informações do Jogo",
"ru_RU": "Показать информацию об игре", "ru_RU": "Показать информацию об игре",
"sv_SE": "", "sv_SE": "Visa spelinformation",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Інформація про гру", "uk_UA": "Інформація про гру",
@@ -2964,7 +2964,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.", "pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.",
"ru_RU": "Показывать статистику и подробную информацию о выбранной игре.", "ru_RU": "Показывать статистику и подробную информацию о выбранной игре.",
"sv_SE": "", "sv_SE": "Visa statistik och detaljer om det aktuella spelet.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Показати статистику та деталі обраної гри.", "uk_UA": "Показати статистику та деталі обраної гри.",
@@ -3514,7 +3514,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Verificar Atualizações:", "pt_BR": "Verificar Atualizações:",
"ru_RU": "Проверка наличия обновлений", "ru_RU": "Проверка наличия обновлений",
"sv_SE": "", "sv_SE": "Leta efter uppdateringar:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Перевірка оновлень:", "uk_UA": "Перевірка оновлень:",
@@ -3539,7 +3539,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Desligado", "pt_BR": "Desligado",
"ru_RU": "Отключить", "ru_RU": "Отключить",
"sv_SE": "", "sv_SE": "Av",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути", "uk_UA": "Вимкнути",
@@ -3564,7 +3564,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Ao Abrir", "pt_BR": "Ao Abrir",
"ru_RU": "При запуске", "ru_RU": "При запуске",
"sv_SE": "", "sv_SE": "Fråga",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запитувати щоразу", "uk_UA": "Запитувати щоразу",
@@ -3589,7 +3589,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "2° Plano", "pt_BR": "2° Plano",
"ru_RU": "В фоне", "ru_RU": "В фоне",
"sv_SE": "", "sv_SE": "Bakgrund",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Оновлювати в фоні", "uk_UA": "Оновлювати в фоні",
@@ -3614,7 +3614,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Ao Perder o Foco:", "pt_BR": "Ao Perder o Foco:",
"ru_RU": "При выходе эмулятора из фокуса", "ru_RU": "При выходе эмулятора из фокуса",
"sv_SE": "", "sv_SE": "När emulatorn tappar fokus:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "При втраті фокуса емулятором:", "uk_UA": "При втраті фокуса емулятором:",
@@ -3639,7 +3639,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Não Fazer Nada", "pt_BR": "Não Fazer Nada",
"ru_RU": "Ничего не делать", "ru_RU": "Ничего не делать",
"sv_SE": "", "sv_SE": "Gör ingenting",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Нічого не робити", "uk_UA": "Нічого не робити",
@@ -3664,7 +3664,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Bloquear Controles", "pt_BR": "Bloquear Controles",
"ru_RU": "Блокировать управление", "ru_RU": "Блокировать управление",
"sv_SE": "", "sv_SE": "Blockera inmatning",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Блокувати введення", "uk_UA": "Блокувати введення",
@@ -3689,7 +3689,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Ficar Mudo", "pt_BR": "Ficar Mudo",
"ru_RU": "Отключить звук", "ru_RU": "Отключить звук",
"sv_SE": "", "sv_SE": "Stäng av ljudet",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути звук", "uk_UA": "Вимкнути звук",
@@ -3714,7 +3714,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Bloquear Controles & Ficar Mudo", "pt_BR": "Bloquear Controles & Ficar Mudo",
"ru_RU": "Блокировать управление и отключить звук", "ru_RU": "Блокировать управление и отключить звук",
"sv_SE": "", "sv_SE": "Blockera inmatningar och stäng av ljudet",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Блокувати введення та Вимкнути звук", "uk_UA": "Блокувати введення та Вимкнути звук",
@@ -3739,7 +3739,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Pausar a Emulação", "pt_BR": "Pausar a Emulação",
"ru_RU": "Поставить паузу", "ru_RU": "Поставить паузу",
"sv_SE": "", "sv_SE": "Pausa emuleringen",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Поставити на паузу", "uk_UA": "Поставити на паузу",
@@ -3814,7 +3814,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Desativar Controles Quando Estiver Fora de Foco", "pt_BR": "Desativar Controles Quando Estiver Fora de Foco",
"ru_RU": "Отключает управление при выходе из фокуса", "ru_RU": "Отключает управление при выходе из фокуса",
"sv_SE": "", "sv_SE": "Inaktivera inmatning när fokus tappas",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
@@ -4839,7 +4839,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Sincronizar com o Sistema PC", "pt_BR": "Sincronizar com o Sistema PC",
"ru_RU": "Соответствовать времени в системе", "ru_RU": "Соответствовать времени в системе",
"sv_SE": "", "sv_SE": "Matcha systemtid",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
@@ -5013,7 +5013,7 @@
"no_NO": "Lyd Inn/Ut", "no_NO": "Lyd Inn/Ut",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Выход/Вход звука",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -5264,7 +5264,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Ignorar Applet do Controlador", "pt_BR": "Ignorar Applet do Controlador",
"ru_RU": "Игнорировать апплет контроллера", "ru_RU": "Игнорировать апплет контроллера",
"sv_SE": "", "sv_SE": "Ignorera kontroller-applet",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Ігнорувати Аплет Контролера", "uk_UA": "Ігнорувати Аплет Контролера",
@@ -6114,7 +6114,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Habilitar Logs da IU", "pt_BR": "Habilitar Logs da IU",
"ru_RU": "Включить журнал интерфейса", "ru_RU": "Включить журнал интерфейса",
"sv_SE": "", "sv_SE": "Aktivera gränssnittsloggar",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Увімкнути журнали інтерфейсу", "uk_UA": "Увімкнути журнали інтерфейсу",
@@ -6514,7 +6514,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Redefinir Configurações", "pt_BR": "Redefinir Configurações",
"ru_RU": "Сбросить настройки", "ru_RU": "Сбросить настройки",
"sv_SE": "", "sv_SE": "Nollställ inställningar",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Скинути налаштування", "uk_UA": "Скинути налаштування",
@@ -6539,7 +6539,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Quero redefinir minhas configurações.", "pt_BR": "Quero redefinir minhas configurações.",
"ru_RU": "Я хочу сбросить свои настройки.", "ru_RU": "Я хочу сбросить свои настройки.",
"sv_SE": "", "sv_SE": "Jag vill nollställa mina inställningar.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Я хочу скинути налаштування.", "uk_UA": "Я хочу скинути налаштування.",
@@ -6563,7 +6563,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Ок",
"sv_SE": "Ok", "sv_SE": "Ok",
"th_TH": "ตกลง", "th_TH": "ตกลง",
"tr_TR": "Tamam", "tr_TR": "Tamam",
@@ -7013,7 +7013,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "Pro Kontroler", "pl_PL": "Pro Kontroler",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Pro контроллер",
"sv_SE": "", "sv_SE": "",
"th_TH": "โปรคอนโทรลเลอร์", "th_TH": "โปรคอนโทรลเลอร์",
"tr_TR": "Profesyonel Kumanda", "tr_TR": "Profesyonel Kumanda",
@@ -8514,7 +8514,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Velocidade do Arco-íris", "pt_BR": "Velocidade do Arco-íris",
"ru_RU": "Скорость переливания", "ru_RU": "Скорость переливания",
"sv_SE": "", "sv_SE": "Regnbågshastighet",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
@@ -13814,7 +13814,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?", "pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?",
"ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?", "ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?",
"sv_SE": "", "sv_SE": "Du är på väg att ta bort allt PPTC-data från:\n\n{0}\n\nÄr du säker på att du vill fortsätta?",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?", "uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?",
@@ -16664,7 +16664,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.", "pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.",
"ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.", "ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.",
"sv_SE": "", "sv_SE": "Handkontroller-appleten kommer inte att visas om gamepaden är frånkopplad under tiden en applikation körs.\n\nLämna AV om du är osäker.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.", "uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.",
@@ -17139,7 +17139,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.", "pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.",
"ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.", "ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.",
"sv_SE": "", "sv_SE": "Skriver ut loggmeddelanden från Avalonia (användargränssnittet) i konsollen.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль", "uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль",
@@ -17339,7 +17339,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Abre a pasta de capturas de tela do Ryujinx", "pt_BR": "Abre a pasta de capturas de tela do Ryujinx",
"ru_RU": "Открывает папку скриншотов Ryujinx", "ru_RU": "Открывает папку скриншотов Ryujinx",
"sv_SE": "", "sv_SE": "Öppna Ryujinx skärmbildsmapp",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx", "uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx",
@@ -18089,7 +18089,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Atualização Disponível!", "pt_BR": "Atualização Disponível!",
"ru_RU": "Доступно обновление!", "ru_RU": "Доступно обновление!",
"sv_SE": "", "sv_SE": "Uppdatering finns tillgänglig!",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Доступне оновлення!", "uk_UA": "Доступне оновлення!",
@@ -20013,7 +20013,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Амибо",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -24064,7 +24064,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.", "pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.",
"ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.", "ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.",
"sv_SE": "", "sv_SE": "Startar upp och spelas utan några krascher eller GPU-fel av några slag och med en hastighet som är snabb nog för bra upplevelse på en genomsnittlig PC.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.", "uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.",
@@ -24089,7 +24089,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.", "pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.",
"ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.", "ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.",
"sv_SE": "", "sv_SE": "Startar och går in i spelet men lider av ett eller flera av följande: kraschar, deadlocks, GPU-buggar, distraherande dåligt ljud eller är helt enkelt för långsamt. Spelet kan fortfarande spelas hela vägen igenom, men inte så som spelet är avsett att spelas.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.", "uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.",
@@ -24114,7 +24114,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.", "pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.",
"ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.", "ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.",
"sv_SE": "", "sv_SE": "Startar upp och går förbi titelskärmen men tar sig inte in i huvudspelet.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.", "uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.",
@@ -24139,7 +24139,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inizializa, mas não passa da tela de título.", "pt_BR": "Inizializa, mas não passa da tela de título.",
"ru_RU": "Загружается, но не проходит дальше титульного экрана.", "ru_RU": "Загружается, но не проходит дальше титульного экрана.",
"sv_SE": "", "sv_SE": "Startar upp men tar sig inte förbi titelskärmen.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається, але не відображає навіть початкового екрану.", "uk_UA": "Запускається, але не відображає навіть початкового екрану.",
@@ -24164,7 +24164,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Não inicializa ou não mostra sinais de atividade.", "pt_BR": "Não inicializa ou não mostra sinais de atividade.",
"ru_RU": "Не запускается или не подаёт признаков жизни.", "ru_RU": "Не запускается или не подаёт признаков жизни.",
"sv_SE": "", "sv_SE": "Startar inte upp eller visar någon form av aktivitet.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Взагалі не запускається.", "uk_UA": "Взагалі не запускається.",
@@ -24264,7 +24264,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Imagem da Presença do Discord", "pt_BR": "Imagem da Presença do Discord",
"ru_RU": "Изображение для статуса активности", "ru_RU": "Изображение для статуса активности",
"sv_SE": "", "sv_SE": "Bild för Rich Presence",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Зображення картки активності Discord", "uk_UA": "Зображення картки активності Discord",
@@ -24289,7 +24289,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Presença Dinâmica do Discord", "pt_BR": "Presença Dinâmica do Discord",
"ru_RU": "Динамический статус активности", "ru_RU": "Динамический статус активности",
"sv_SE": "", "sv_SE": "Dynamisk Rich Presence",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Динамічна картка активності Discord", "uk_UA": "Динамічна картка активності Discord",

View File

@@ -158,16 +158,6 @@ namespace Ryujinx.Ava
} }
} }
public static bool FindGameConfig(string gameDir)
{
if (File.Exists(gameDir))
{
return true;
}
return false;
}
public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false) public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false)
{ {
if (string.IsNullOrEmpty(gameId)) if (string.IsNullOrEmpty(gameId))

View File

@@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Applet
_parent.SettingsWindow = _parent.SettingsWindow =
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager); new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
await _parent.SettingsWindow.ShowDialog(window); await StyleableAppWindow.ShowAsync(_parent.SettingsWindow, window);
_parent.SettingsWindow = null; _parent.SettingsWindow = null;

View File

@@ -17,11 +17,7 @@
<viewModels:ProfileSelectorDialogViewModel /> <viewModels:ProfileSelectorDialogViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border <Border
CornerRadius="5" CornerRadius="5"

View File

@@ -91,11 +91,14 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args) public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await new CheatWindow( await StyleableAppWindow.ShowAsync(
new CheatWindow(
viewModel.VirtualFileSystem, viewModel.VirtualFileSystem,
viewModel.SelectedApplication.IdString, viewModel.SelectedApplication.IdString,
viewModel.SelectedApplication.Name, viewModel.SelectedApplication.Name,
viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel); viewModel.SelectedApplication.Path
)
);
} }
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args) public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
@@ -391,9 +394,9 @@ namespace Ryujinx.Ava.UI.Controls
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
{ {
await new GameSpecificSettingsWindow(viewModel).ShowDialog((Window)viewModel.TopLevel); await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
//just checking for file presence // just checking for file presence
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false)); viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
viewModel.RefreshView(); viewModel.RefreshView();

View File

@@ -14,10 +14,7 @@
mc:Ignorable="d" mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel"> x:DataType="viewModels:MainWindowViewModel">
<Grid> <Grid RowDefinitions="*">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox <ListBox
Grid.Row="0" Grid.Row="0"
Padding="8" Padding="8"
@@ -57,11 +54,7 @@
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}" Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
ClipToBounds="True" ClipToBounds="True"
CornerRadius="4"> CornerRadius="4">
<Grid> <Grid RowDefinitions="Auto,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image <Image
Grid.Row="0" Grid.Row="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -13,10 +13,7 @@
mc:Ignorable="d" mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel"> x:DataType="viewModels:MainWindowViewModel">
<Grid> <Grid RowDefinitions="*">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox <ListBox
Name="GameListBox" Name="GameListBox"
Grid.Row="0" Grid.Row="0"

View File

@@ -13,15 +13,7 @@
<Grid <Grid
Margin="20" Margin="20"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch" ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image <Image
Grid.Row="1" Grid.Row="1"
Height="70" Height="70"

View File

@@ -1,6 +1,7 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Threading; using Avalonia.Threading;
@@ -385,6 +386,10 @@ namespace Ryujinx.Ava.UI.Helpers
ShowInTaskbar = false, ShowInTaskbar = false,
}; };
#if DEBUG
_contentDialogOverlayWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
#endif
parent.PositionChanged += OverlayOnPositionChanged; parent.PositionChanged += OverlayOnPositionChanged;
void OverlayOnPositionChanged(object sender, PixelPointEventArgs e) void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)

View File

@@ -0,0 +1,260 @@
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Input;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Models.Input
{
public class StickVisualizer : BaseModel, IDisposable
{
public const int DrawStickPollRate = 50; // Milliseconds per poll.
public const int DrawStickCircumference = 5;
public const float DrawStickScaleFactor = DrawStickCanvasCenter;
public const int DrawStickCanvasSize = 100;
public const int DrawStickBorderSize = DrawStickCanvasSize + 5;
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
public const float MaxVectorLength = DrawStickCanvasSize / 2;
public CancellationTokenSource PollTokenSource;
public CancellationToken PollToken;
private static float _vectorLength;
private static float _vectorMultiplier;
private bool disposedValue;
private DeviceType _type;
public DeviceType Type
{
get => _type;
set
{
_type = value;
OnPropertyChanged();
}
}
private GamepadInputConfig _gamepadConfig;
public GamepadInputConfig GamepadConfig
{
get => _gamepadConfig;
set
{
_gamepadConfig = value;
OnPropertyChanged();
}
}
private KeyboardInputConfig _keyboardConfig;
public KeyboardInputConfig KeyboardConfig
{
get => _keyboardConfig;
set
{
_keyboardConfig = value;
OnPropertyChanged();
}
}
private (float, float) _uiStickLeft;
public (float, float) UiStickLeft
{
get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
set
{
_uiStickLeft = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickRightX));
OnPropertyChanged(nameof(UiStickRightY));
OnPropertyChanged(nameof(UiDeadzoneRight));
}
}
private (float, float) _uiStickRight;
public (float, float) UiStickRight
{
get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
set
{
_uiStickRight = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickLeftX));
OnPropertyChanged(nameof(UiStickLeftY));
OnPropertyChanged(nameof(UiDeadzoneLeft));
}
}
public float UiStickLeftX => ClampVector(UiStickLeft).Item1;
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
public float UiStickRightX => ClampVector(UiStickRight).Item1;
public float UiStickRightY => ClampVector(UiStickRight).Item2;
public int UiStickCircumference => DrawStickCircumference;
public int UiCanvasSize => DrawStickCanvasSize;
public int UiStickBorderSize => DrawStickBorderSize;
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
private InputViewModel Parent;
public StickVisualizer(InputViewModel parent)
{
Parent = parent;
PollTokenSource = new CancellationTokenSource();
PollToken = PollTokenSource.Token;
Task.Run(Initialize, PollToken);
}
public void UpdateConfig(object config)
{
if (config is ControllerInputViewModel padConfig)
{
GamepadConfig = padConfig.Config;
Type = DeviceType.Controller;
return;
}
else if (config is KeyboardInputViewModel keyConfig)
{
KeyboardConfig = keyConfig.Config;
Type = DeviceType.Keyboard;
return;
}
Type = DeviceType.None;
}
public async Task Initialize()
{
(float, float) leftBuffer;
(float, float) rightBuffer;
while (!PollToken.IsCancellationRequested)
{
leftBuffer = (0f, 0f);
rightBuffer = (0f, 0f);
switch (Type)
{
case DeviceType.Keyboard:
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
if (keyboard != null)
{
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
{
leftBuffer.Item1 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
{
leftBuffer.Item1 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
{
leftBuffer.Item2 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
{
leftBuffer.Item2 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
{
rightBuffer.Item1 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
{
rightBuffer.Item1 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
{
rightBuffer.Item2 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
{
rightBuffer.Item2 -= 1;
}
UiStickLeft = leftBuffer;
UiStickRight = rightBuffer;
}
break;
case DeviceType.Controller:
IGamepad controller = Parent.SelectedGamepad;
if (controller != null)
{
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
}
break;
case DeviceType.None:
break;
default:
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
}
UiStickLeft = leftBuffer;
UiStickRight = rightBuffer;
await Task.Delay(DrawStickPollRate, PollToken);
}
PollTokenSource.Dispose();
}
public static (float, float) ClampVector((float, float) vect)
{
_vectorMultiplier = 1;
_vectorLength = MathF.Sqrt((vect.Item1 * vect.Item1) + (vect.Item2 * vect.Item2));
if (_vectorLength > MaxVectorLength)
{
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
vect.Item1 = vect.Item1 * _vectorMultiplier + DrawStickCanvasCenter;
vect.Item2 = vect.Item2 * _vectorMultiplier + DrawStickCanvasCenter;
return vect;
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
PollTokenSource.Cancel();
}
KeyboardConfig = null;
GamepadConfig = null;
Parent = null;
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -1,5 +1,9 @@
using Avalonia.Svg.Skia; using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
@@ -10,7 +14,29 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class ControllerInputViewModel : BaseModel public partial class ControllerInputViewModel : BaseModel
{ {
[ObservableProperty] private GamepadInputConfig _config; private GamepadInputConfig _config;
public GamepadInputConfig Config
{
get => _config;
set
{
_config = value;
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
}
private bool _isLeft; private bool _isLeft;
public bool IsLeft public bool IsLeft
@@ -42,9 +68,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public InputViewModel ParentModel { get; } public InputViewModel ParentModel { get; }
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config) public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
{ {
ParentModel = model; ParentModel = model;
Visualizer = visualizer;
model.NotifyChangesEvent += OnParentModelChanged; model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged(); OnParentModelChanged();
config.PropertyChanged += (_, args) => config.PropertyChanged += (_, args) =>

View File

@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _controller; private int _controller;
private string _controllerImage; private string _controllerImage;
private int _device; private int _device;
[ObservableProperty] private object _configViewModel; private object _configViewModel;
[ObservableProperty] private string _profileName; [ObservableProperty] private string _profileName;
private bool _isLoaded; private bool _isLoaded;
@@ -74,6 +74,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
} }
} }
public StickVisualizer VisualStick { get; private set; }
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; } public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; } public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
@@ -94,6 +95,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsModified { get; set; } public bool IsModified { get; set; }
public event Action NotifyChangesEvent; public event Action NotifyChangesEvent;
public object ConfigViewModel
{
get => _configViewModel;
set
{
_configViewModel = value;
VisualStick.UpdateConfig(value);
OnPropertyChanged();
}
}
public PlayerIndex PlayerIdChoose public PlayerIndex PlayerIdChoose
{ {
get => _playerIdChoose; get => _playerIdChoose;
@@ -269,6 +283,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
Devices = []; Devices = [];
ProfilesList = []; ProfilesList = [];
DeviceList = []; DeviceList = [];
VisualStick = new StickVisualizer(this);
ControllerImage = ProControllerResource; ControllerImage = ProControllerResource;
@@ -289,12 +304,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (Config is StandardKeyboardInputConfig keyboardInputConfig) if (Config is StandardKeyboardInputConfig keyboardInputConfig)
{ {
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig)); ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig), VisualStick);
} }
if (Config is StandardControllerInputConfig controllerInputConfig) if (Config is StandardControllerInputConfig controllerInputConfig)
{ {
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig)); ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
} }
} }
@@ -893,6 +908,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates(); _mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
VisualStick.Dispose();
SelectedGamepad?.Dispose(); SelectedGamepad?.Dispose();
AvaloniaKeyboardDriver.Dispose(); AvaloniaKeyboardDriver.Dispose();

View File

@@ -6,7 +6,29 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class KeyboardInputViewModel : BaseModel public partial class KeyboardInputViewModel : BaseModel
{ {
[ObservableProperty] private KeyboardInputConfig _config; private KeyboardInputConfig _config;
public KeyboardInputConfig Config
{
get => _config;
set
{
_config = value;
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
}
private bool _isLeft; private bool _isLeft;
public bool IsLeft public bool IsLeft
@@ -38,9 +60,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public readonly InputViewModel ParentModel; public readonly InputViewModel ParentModel;
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config) public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
{ {
ParentModel = model; ParentModel = model;
Visualizer = visualizer;
model.NotifyChangesEvent += OnParentModelChanged; model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged(); OnParentModelChanged();
Config = config; Config = config;

View File

@@ -1747,7 +1747,7 @@ namespace Ryujinx.Ava.UI.ViewModels
string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper(); string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId); AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId);
await window.ShowDialog(Window); await StyleableAppWindow.ShowAsync(window);
if (window.IsScanned) if (window.IsScanned)
{ {

View File

@@ -34,12 +34,7 @@
<!-- Button / JoyStick Settings --> <!-- Button / JoyStick Settings -->
<Grid <Grid
Name="SettingButtons" Name="SettingButtons"
MinHeight="450"> MinHeight="450" ColumnDefinitions="Auto,*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Left Controls --> <!-- Left Controls -->
<StackPanel <StackPanel
Orientation="Vertical" Orientation="Vertical"
@@ -54,15 +49,7 @@
CornerRadius="5"> CornerRadius="5">
<Grid <Grid
Margin="10" Margin="10"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Grid.Row="0" Grid.Row="0"
@@ -316,17 +303,99 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch">
<!-- Controller Picture --> <!-- Controller Picture -->
<Image
Margin="0,10"
MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding Image}" />
<Border <Border
BorderBrush="{DynamicResource ThemeControlBorderColor}" BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1" BorderThickness="1"
CornerRadius="5" CornerRadius="5"
Margin="0,0, 0, 5"
MinHeight="90"> MinHeight="90">
<StackPanel Orientation="Vertical">
<Image
Margin="5,10"
MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding Image}" />
<StackPanel
Margin="10"
Orientation="Horizontal"
Spacing="20"
HorizontalAlignment="Center">
<Border
BorderBrush="Transparent"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsLeft}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="{DynamicResource ThemeControlBorderColor}"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}" />
<Ellipse
HorizontalAlignment="Center"
Fill="Black"
Opacity="100"
Height="{Binding Visualizer.UiDeadzoneLeft}"
Width="{Binding Visualizer.UiDeadzoneLeft}" />
</Grid>
<Ellipse
Fill="{DynamicResource Warning}"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
</Canvas>
</Border>
<Border
BorderBrush="Transparent"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsRight}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="{DynamicResource ThemeControlBorderColor}"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}" />
<Ellipse
HorizontalAlignment="Center"
Fill="Black"
Opacity="100"
Height="{Binding Visualizer.UiDeadzoneRight}"
Width="{Binding Visualizer.UiDeadzoneRight}" />
</Grid>
<Ellipse
Fill="{DynamicResource Warning}"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
</Canvas>
</Border>
</StackPanel>
</StackPanel>
</Border>
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5">
<StackPanel <StackPanel
Margin="8" Margin="8"
Orientation="Vertical"> Orientation="Vertical">
@@ -428,7 +497,7 @@
</Border> </Border>
<!-- Motion, Rumble, LED --> <!-- Motion, Rumble, LED -->
<StackPanel <StackPanel
Margin="0,10,0,0" Margin="0,5,0,0"
Spacing="5" Spacing="5"
Orientation="Vertical" Orientation="Vertical"
VerticalAlignment="Bottom"> VerticalAlignment="Bottom">
@@ -438,11 +507,7 @@
CornerRadius="5" CornerRadius="5"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<Grid> <Grid ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox <CheckBox
Margin="10" Margin="10"
MinWidth="0" MinWidth="0"
@@ -464,11 +529,7 @@
CornerRadius="5" CornerRadius="5"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="0,-1,0,0"> Margin="0,-1,0,0">
<Grid> <Grid ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox <CheckBox
Margin="10" Margin="10"
MinWidth="0" MinWidth="0"
@@ -490,11 +551,7 @@
CornerRadius="5" CornerRadius="5"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="0,-1,0,0"> Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}"> <Grid IsVisible="{Binding ParentModel.HasLed}" ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox <CheckBox
Margin="10, 10, 5, 10" Margin="10, 10, 5, 10"
MinWidth="0" MinWidth="0"
@@ -526,15 +583,7 @@
CornerRadius="5"> CornerRadius="5">
<Grid <Grid
Margin="10" Margin="10"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Column="1" Grid.Column="1"
Grid.Row="0" Grid.Row="0"

View File

@@ -35,22 +35,13 @@
Margin="0 0 0 5" Margin="0 0 0 5"
Orientation="Vertical" Orientation="Vertical"
Spacing="5"> Spacing="5">
<Grid> <Grid ColumnDefinitions="*,10,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Player Selection --> <!-- Player Selection -->
<Grid <Grid
Grid.Column="0" Grid.Column="0"
Margin="2" Margin="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center"> VerticalAlignment="Center" ColumnDefinitions="Auto,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Margin="5,0,10,0" Margin="5,0,10,0"
Width="90" Width="90"
@@ -77,14 +68,7 @@
Grid.Column="2" Grid.Column="2"
Margin="2" Margin="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center"> VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Margin="5,0,10,0" Margin="5,0,10,0"
Width="90" Width="90"
@@ -139,22 +123,12 @@
</Grid> </Grid>
</Grid> </Grid>
<Separator /> <Separator />
<Grid> <Grid ColumnDefinitions="*,10,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Input Device --> <!-- Input Device -->
<Grid <Grid
Grid.Column="0" Grid.Column="0"
Margin="2" Margin="2"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
Margin="5,0,10,0" Margin="5,0,10,0"
@@ -186,11 +160,7 @@
Grid.Column="2" Grid.Column="2"
Margin="2" Margin="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center"> VerticalAlignment="Center" ColumnDefinitions="Auto,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Margin="5,0,10,0" Margin="5,0,10,0"
Width="90" Width="90"

View File

@@ -32,12 +32,7 @@
<!-- Button / JoyStick Settings --> <!-- Button / JoyStick Settings -->
<Grid <Grid
Name="SettingButtons" Name="SettingButtons"
MinHeight="450"> MinHeight="450" ColumnDefinitions="Auto,*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Left Controls --> <!-- Left Controls -->
<StackPanel <StackPanel
Orientation="Vertical" Orientation="Vertical"
@@ -52,15 +47,7 @@
CornerRadius="5"> CornerRadius="5">
<Grid <Grid
Margin="10" Margin="10"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Grid.Row="0" Grid.Row="0"
@@ -309,12 +296,79 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch">
<!-- Controller Picture --> <!-- Controller Picture -->
<Image <Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Margin="0,10" Margin="0,10"
MaxHeight="300" MinHeight="90">
HorizontalAlignment="Stretch" <StackPanel
VerticalAlignment="Stretch" Margin="10"
Source="{Binding Image}" /> Orientation="Horizontal"
Spacing="20"
HorizontalAlignment="Center">
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsLeft}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="Black"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}"/>
</Grid>
<Ellipse
Fill="Red"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
</Canvas>
</Border>
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsRight}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="Black"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}"/>
</Grid>
<Ellipse
Fill="Red"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
</Canvas>
</Border>
</StackPanel>
</Border>
<Border <Border
BorderBrush="{DynamicResource ThemeControlBorderColor}" BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1" BorderThickness="1"
@@ -413,15 +467,7 @@
CornerRadius="5"> CornerRadius="5">
<Grid <Grid
Margin="10" Margin="10"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Column="1" Grid.Column="1"
Grid.Row="0" Grid.Row="0"

View File

@@ -11,11 +11,7 @@
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView" x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
x:DataType="viewModels:MotionInputViewModel" x:DataType="viewModels:MotionInputViewModel"
Focusable="True"> Focusable="True">
<Grid Margin="10"> <Grid Margin="10" RowDefinitions="Auto,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<StackPanel <StackPanel
Orientation="Horizontal" Orientation="Horizontal"
@@ -80,11 +76,7 @@
BorderThickness="1" BorderThickness="1"
CornerRadius="5" CornerRadius="5"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<Grid VerticalAlignment="Top"> <Grid VerticalAlignment="Top" RowDefinitions="Auto,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Row="1" Grid.Row="1"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@@ -118,15 +110,7 @@
Text="{Binding DsuServerPort, Mode=TwoWay}" /> Text="{Binding DsuServerPort, Mode=TwoWay}" />
</StackPanel> </StackPanel>
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<Grid> <Grid RowDefinitions="*,*" ColumnDefinitions="*,*">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Margin="0,10,0,0" Margin="0,10,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"

View File

@@ -10,11 +10,7 @@
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView" x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
x:DataType="viewModels:RumbleInputViewModel" x:DataType="viewModels:RumbleInputViewModel"
Focusable="True"> Focusable="True">
<Grid Margin="10"> <Grid Margin="10" RowDefinitions="Auto,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock <TextBlock

View File

@@ -19,6 +19,7 @@ using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption; using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -133,20 +134,20 @@ namespace Ryujinx.Ava.UI.Views.Main
if (ViewModel.SelectedApplication is null) // Checks if game data exists if (ViewModel.SelectedApplication is null) // Checks if game data exists
{ {
await Window.SettingsWindow.ShowDialog(Window); await StyleableAppWindow.ShowAsync(Window.SettingsWindow);
} }
else else
{ {
bool userConfigExist = Program.FindGameConfig(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString, false, false)); bool customConfigExists = File.Exists(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString));
if (!ViewModel.IsGameRunning || !userConfigExist) if (!ViewModel.IsGameRunning || !customConfigExists)
{ {
await Window.SettingsWindow.ShowDialog(Window); // The game is not running, or if the user configuration does not exist await Window.SettingsWindow.ShowDialog(Window); // The game is not running, or if the user configuration does not exist
} }
else else
{ {
// If there is a custom configuration in the folder // If there is a custom configuration in the folder
await new GameSpecificSettingsWindow(ViewModel, userConfigExist).ShowDialog((Window)ViewModel.TopLevel); await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(ViewModel, customConfigExists));
} }
} }
@@ -175,11 +176,13 @@ namespace Ryujinx.Ava.UI.Views.Main
string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString(); string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString();
await new CheatWindow( await StyleableAppWindow.ShowAsync(
new CheatWindow(
Window.VirtualFileSystem, Window.VirtualFileSystem,
ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
name, name,
ViewModel.SelectedApplication.Path).ShowDialog(Window); ViewModel.SelectedApplication.Path)
);
ViewModel.AppHost.Device.EnableCheats(); ViewModel.AppHost.Device.EnableCheats();
} }

View File

@@ -21,12 +21,7 @@
<Border Classes="settings"> <Border Classes="settings">
<Panel <Panel
Margin="10"> Margin="10">
<Grid> <Grid RowDefinitions="Auto,*,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<views:InputView <views:InputView
Grid.Row="0" Grid.Row="0"
Name="InputView" /> Name="InputView" />

View File

@@ -177,12 +177,7 @@
</Style> </Style>
</ListBox.Styles> </ListBox.Styles>
</ListBox> </ListBox>
<Grid HorizontalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox <TextBox
Name="GameDirPathBox" Name="GameDirPathBox"
Margin="0" Margin="0"
@@ -235,12 +230,7 @@
</Style> </Style>
</ListBox.Styles> </ListBox.Styles>
</ListBox> </ListBox>
<Grid HorizontalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox <TextBox
Name="AutoloadDirPathBox" Name="AutoloadDirPathBox"
Margin="0" Margin="0"

View File

@@ -14,15 +14,7 @@
mc:Ignorable="d" mc:Ignorable="d"
Focusable="True" Focusable="True"
x:DataType="models:TempProfile"> x:DataType="models:TempProfile">
<Grid Margin="0"> <Grid Margin="0" ColumnDefinitions="Auto,*" RowDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Row="0" Grid.Row="0"
Grid.Column="0" Grid.Column="0"

View File

@@ -20,13 +20,7 @@
<Grid <Grid
Margin="0" Margin="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox <ListBox
Grid.Row="1" Grid.Row="1"
BorderThickness="0" BorderThickness="0"

View File

@@ -17,12 +17,7 @@
</Design.DataContext> </Design.DataContext>
<Grid <Grid
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center"> VerticalAlignment="Center" RowDefinitions="Auto,70,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="70" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock <TextBlock
Grid.Row="0" Grid.Row="0"
TextWrapping="Wrap" TextWrapping="Wrap"

View File

@@ -18,11 +18,7 @@
<viewModels:UserProfileViewModel /> <viewModels:UserProfileViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" <Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch" RowDefinitions="*,Auto">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border <Border
CornerRadius="5" CornerRadius="5"
BorderBrush="{DynamicResource AppListHoverBackgroundColor}" BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
@@ -41,11 +37,7 @@
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
ClipToBounds="True" ClipToBounds="True"
CornerRadius="5"> CornerRadius="5">
<Grid Margin="0"> <Grid Margin="0" ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Text="{Binding UserId}" Text="{Binding UserId}"

View File

@@ -19,19 +19,10 @@
<Design.DataContext> <Design.DataContext>
<viewModels:UserSaveManagerViewModel /> <viewModels:UserSaveManagerViewModel />
</Design.DataContext> </Design.DataContext>
<Grid> <Grid RowDefinitions="Auto,*,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid <Grid
Grid.Row="0" Grid.Row="0"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel <StackPanel
Spacing="10" Spacing="10"
Orientation="Horizontal" Orientation="Horizontal"
@@ -80,11 +71,7 @@
<Grid <Grid
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="10,0, 0, 0"> Margin="10,0, 0, 0" ColumnDefinitions="Auto,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="{ext:Locale Search}" VerticalAlignment="Center" /> <Label Content="{ext:Locale Search}" VerticalAlignment="Center" />
<TextBox <TextBox
Margin="5,0,0,0" Margin="5,0,0,0"
@@ -118,11 +105,7 @@
</ListBox.Styles> </ListBox.Styles>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate x:DataType="models:SaveModel"> <DataTemplate x:DataType="models:SaveModel">
<Grid HorizontalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Orientation="Horizontal" Orientation="Horizontal"

View File

@@ -18,11 +18,7 @@
<Design.DataContext> <Design.DataContext>
<viewModels:UserProfileViewModel /> <viewModels:UserProfileViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border <Border
CornerRadius="5" CornerRadius="5"
BorderBrush="{DynamicResource AppListHoverBackgroundColor}" BorderBrush="{DynamicResource AppListHoverBackgroundColor}"

View File

@@ -12,7 +12,7 @@
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
Width="1100" Width="1100"
Height="768" Height="910"
MinWidth="800" MinWidth="800"
MinHeight="480" MinHeight="480"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
@@ -53,13 +53,7 @@
<!-- For image --> <!-- For image -->
<ui:NavigationView.PaneHeader> <ui:NavigationView.PaneHeader>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid HorizontalAlignment="Center" VerticalAlignment="Center" RowDefinitions="Auto,Auto,Auto,5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding GameId}" <TextBlock Text="{Binding GameId}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"

View File

@@ -47,11 +47,6 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
Load(); Load();
#if DEBUG
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
#endif
} }
public void SaveSettings() public void SaveSettings()
@@ -65,7 +60,6 @@ namespace Ryujinx.Ava.UI.Windows
Pages.Children.Clear(); Pages.Children.Clear();
NavPanel.SelectionChanged += NavPanelOnSelectionChanged; NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0); NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
} }
private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e) private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)

View File

@@ -70,11 +70,7 @@
<DataTemplate <DataTemplate
DataType="models:ModModel"> DataType="models:ModModel">
<Panel Margin="10"> <Panel Margin="10">
<Grid> <Grid ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"

View File

@@ -12,7 +12,7 @@
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
Width="1100" Width="1100"
Height="768" Height="927"
MinWidth="800" MinWidth="800"
MinHeight="480" MinHeight="480"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"

View File

@@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
@@ -8,7 +6,6 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.Input; using Ryujinx.Input;
using System; using System;
using System.Linq; using System.Linq;
using Key = Avalonia.Input.Key;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
{ {
@@ -27,10 +24,6 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
Load(); Load();
#if DEBUG
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
#endif
} }
public SettingsWindow() public SettingsWindow()

View File

@@ -1,15 +1,26 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using FluentAvalonia.UI.Windowing; using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
{ {
public abstract class StyleableAppWindow : AppWindow public abstract class StyleableAppWindow : AppWindow
{ {
public static async Task ShowAsync(StyleableAppWindow appWindow, Window owner = null)
{
#if DEBUG
appWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
#endif
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
}
protected StyleableAppWindow() protected StyleableAppWindow()
{ {
WindowStartupLocation = WindowStartupLocation.CenterOwner; WindowStartupLocation = WindowStartupLocation.CenterOwner;
@@ -36,6 +47,14 @@ namespace Ryujinx.Ava.UI.Windows
public abstract class StyleableWindow : Window public abstract class StyleableWindow : Window
{ {
public static async Task ShowAsync(StyleableWindow window, Window owner = null)
{
#if DEBUG
window.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
#endif
await window.ShowDialog(owner ?? RyujinxApp.MainWindow);
}
protected StyleableWindow() protected StyleableWindow()
{ {
WindowStartupLocation = WindowStartupLocation.CenterOwner; WindowStartupLocation = WindowStartupLocation.CenterOwner;

View File

@@ -13,14 +13,7 @@
x:DataType="viewModels:XCITrimmerViewModel" x:DataType="viewModels:XCITrimmerViewModel"
Focusable="True" Focusable="True"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="20 0 20 0"> <Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Panel <Panel
Margin="10 10 10 10" Margin="10 10 10 10"
Grid.Row="0"> Grid.Row="0">
@@ -30,12 +23,7 @@
Margin="0 0 10 10" Margin="0 0 10 10"
IsVisible="{Binding !Processing}" IsVisible="{Binding !Processing}"
Grid.Row="1"> Grid.Row="1">
<Grid> <Grid ColumnDefinitions="Auto,*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Orientation="Horizontal"> Orientation="Horizontal">
@@ -145,11 +133,7 @@
<DataTemplate <DataTemplate
DataType="models:XCITrimmerFileModel"> DataType="models:XCITrimmerFileModel">
<Panel Margin="10"> <Panel Margin="10">
<Grid> <Grid ColumnDefinitions="65*,35*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65*" />
<ColumnDefinition Width="35*" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
Margin="10 0 10 0" Margin="10 0 10 0"
@@ -160,11 +144,7 @@
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
Text="{Binding Name}"> Text="{Binding Name}">
</TextBlock> </TextBlock>
<Grid Grid.Column="1"> <Grid Grid.Column="1" ColumnDefinitions="45*,55*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="55*" />
</Grid.ColumnDefinitions>
<ProgressBar <ProgressBar
Height="10" Height="10"
Margin="10 0 10 0" Margin="10 0 10 0"
@@ -226,15 +206,7 @@
BorderThickness="1" BorderThickness="1"
CornerRadius="5" CornerRadius="5"
Padding="2.5"> Padding="2.5">
<Grid> <Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
Grid.Row="0" Grid.Row="0"
@@ -274,11 +246,7 @@
<Panel <Panel
Grid.Row="4" Grid.Row="4"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<Grid> <Grid ColumnDefinitions="*,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Orientation="Horizontal" Orientation="Horizontal"