Merge pull request #6133 from Morph1984/project-eleuthia
Project Eleuthia - On-Screen Keyboard and Error Applet Overlays
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 796 B |
After Width: | Height: | Size: 745 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 741 B |
After Width: | Height: | Size: 767 B |
After Width: | Height: | Size: 781 B |
After Width: | Height: | Size: 791 B |
After Width: | Height: | Size: 726 B |
After Width: | Height: | Size: 502 B |
After Width: | Height: | Size: 694 B |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 626 B |
After Width: | Height: | Size: 676 B |
After Width: | Height: | Size: 645 B |
After Width: | Height: | Size: 664 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 281 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,64 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="overlay">
|
||||||
|
<file>arrow_left.png</file>
|
||||||
|
<file>arrow_left_dark.png</file>
|
||||||
|
<file>arrow_right.png</file>
|
||||||
|
<file>arrow_right_dark.png</file>
|
||||||
|
<file>button_minus.png</file>
|
||||||
|
<file>button_minus_dark.png</file>
|
||||||
|
<file>button_plus.png</file>
|
||||||
|
<file>button_plus_dark.png</file>
|
||||||
|
<file>button_A.png</file>
|
||||||
|
<file>button_A_dark.png</file>
|
||||||
|
<file>button_B.png</file>
|
||||||
|
<file>button_B_dark.png</file>
|
||||||
|
<file>button_X.png</file>
|
||||||
|
<file>button_X_dark.png</file>
|
||||||
|
<file>button_Y.png</file>
|
||||||
|
<file>button_Y_dark.png</file>
|
||||||
|
<file>button_L.png</file>
|
||||||
|
<file>button_L_dark.png</file>
|
||||||
|
<file>button_R.png</file>
|
||||||
|
<file>button_R_dark.png</file>
|
||||||
|
<file>button_press_stick.png</file>
|
||||||
|
<file>button_press_stick_dark.png</file>
|
||||||
|
<file>osk_button_B.png</file>
|
||||||
|
<file>osk_button_B_disabled.png</file>
|
||||||
|
<file>osk_button_B_dark.png</file>
|
||||||
|
<file>osk_button_B_dark_disabled.png</file>
|
||||||
|
<file>osk_button_Y.png</file>
|
||||||
|
<file>osk_button_Y_disabled.png</file>
|
||||||
|
<file>osk_button_Y_dark.png</file>
|
||||||
|
<file>osk_button_Y_dark_disabled.png</file>
|
||||||
|
<file>osk_button_backspace.png</file>
|
||||||
|
<file>osk_button_backspace_dark.png</file>
|
||||||
|
<file>osk_button_plus.png</file>
|
||||||
|
<file>osk_button_plus_disabled.png</file>
|
||||||
|
<file>osk_button_plus_dark.png</file>
|
||||||
|
<file>osk_button_plus_dark_disabled.png</file>
|
||||||
|
<file>osk_button_shift.png</file>
|
||||||
|
<file>osk_button_shift_dark.png</file>
|
||||||
|
<file>osk_button_shift_on.png</file>
|
||||||
|
<file>osk_button_shift_on_dark.png</file>
|
||||||
|
<file>osk_button_shift_lock_on.png</file>
|
||||||
|
<file>osk_button_shift_lock_off.png</file>
|
||||||
|
<file>controller_dual_joycon.png</file>
|
||||||
|
<file>controller_dual_joycon_dark.png</file>
|
||||||
|
<file>controller_pro.png</file>
|
||||||
|
<file>controller_pro_dark.png</file>
|
||||||
|
<file>controller_handheld.png</file>
|
||||||
|
<file>controller_handheld_dark.png</file>
|
||||||
|
<file>controller_single_joycon_left.png</file>
|
||||||
|
<file>controller_single_joycon_left_dark.png</file>
|
||||||
|
<file>controller_single_joycon_right.png</file>
|
||||||
|
<file>controller_single_joycon_right_dark.png</file>
|
||||||
|
<file>controller_single_joycon_left_a.png</file>
|
||||||
|
<file>controller_single_joycon_left_a_dark.png</file>
|
||||||
|
<file>controller_single_joycon_left_b.png</file>
|
||||||
|
<file>controller_single_joycon_left_b_dark.png</file>
|
||||||
|
<file>controller_single_joycon_left_x.png</file>
|
||||||
|
<file>controller_single_joycon_left_x_dark.png</file>
|
||||||
|
<file>controller_single_joycon_left_y.png</file>
|
||||||
|
<file>controller_single_joycon_left_y_dark.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -281,3 +281,380 @@ QWidget#controllerPlayer7,
|
||||||
QWidget#controllerPlayer8 {
|
QWidget#controllerPlayer8 {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog,
|
||||||
|
QStackedWidget#topOSK {
|
||||||
|
background: rgba(51, 51, 51, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDialog#OverlayDialog,
|
||||||
|
QStackedWidget#stackedDialog {
|
||||||
|
background: rgba(51, 51, 51, .7);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#boxOSK,
|
||||||
|
QWidget#lineOSK,
|
||||||
|
QWidget#richDialog,
|
||||||
|
QWidget#lineDialog {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#bottomOSK,
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
background: rgba(240, 240, 240, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#buttonsDialog,
|
||||||
|
QWidget#buttonsRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-top: 2px solid rgba(44, 44, 44, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#legendOSKnum {
|
||||||
|
border-top: 1px solid rgba(44, 44, 44, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::vertical {
|
||||||
|
background: #cdcdcd;
|
||||||
|
width: 15px;
|
||||||
|
margin: 15px 3px 15px 3px;
|
||||||
|
border: 1px transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizoncal {
|
||||||
|
background: #cdcdcd;
|
||||||
|
height: 15px;
|
||||||
|
margin: 3px 15px 3px 15px;
|
||||||
|
border: 1px transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::handle {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-height: 5px;
|
||||||
|
min-width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line,
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-page,
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-page {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK {
|
||||||
|
border-bottom: 3px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK QLineEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK {
|
||||||
|
border: 2px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK QTextEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#richDialog QTextBrowser {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 35px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_header {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_sub,
|
||||||
|
QWidget#lineOSK QLabel#label_characters,
|
||||||
|
QWidget#boxOSK QLabel#label_characters_box {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_dialog {
|
||||||
|
padding: 20px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich {
|
||||||
|
padding: 0px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton {
|
||||||
|
color: rgba(49, 79, 239, 1);
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:focus,
|
||||||
|
QDialog#OverlayDialog QPushButton:hover {
|
||||||
|
color: rgba(49, 79, 239, 1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 5px solid rgba(148, 250, 202, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(150, 150, 150, 1);
|
||||||
|
border: 5px solid rgba(148, 250, 202, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton {
|
||||||
|
background: rgba(232, 232, 232, 1);
|
||||||
|
border: 2px solid rgba(240, 240, 240, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background: rgba(218, 218, 218, 1);
|
||||||
|
border: 2px solid rgba(240, 240, 240, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(44, 44, 44, 1);
|
||||||
|
border: 2px solid rgba(240, 240, 240, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(49, 79, 239, 1);
|
||||||
|
border: 2px solid rgba(240, 240, 240, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
|
||||||
|
color: rgba(0, 0, 0, 1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 5px solid rgba(148, 250, 202, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(150, 150, 150, 1);
|
||||||
|
border: 5px solid rgba(148, 250, 202, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_B.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_backspace.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_Y.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_plus.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift_on.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
|
||||||
|
background: transparent;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
|
||||||
|
image: url(:/overlay/button_L.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
|
||||||
|
image: url(:/overlay/arrow_left.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
|
||||||
|
image: url(:/overlay/button_R.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
|
||||||
|
image: url(:/overlay/arrow_right.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
|
||||||
|
image: url(:/overlay/button_press_stick.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
|
||||||
|
image: url(:/overlay/button_X.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
|
||||||
|
image: url(:/overlay/button_A.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
color: rgba(164, 164, 164, 1);
|
||||||
|
background-color: rgba(218, 218, 218, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
|
||||||
|
color: rgba(164, 164, 164, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_plus_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_B_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_Y_disabled.png);
|
||||||
|
}
|
||||||
|
|
|
@ -1560,7 +1560,400 @@ QWidget#controllerPlayer8 {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* touchscreen mapping widget */
|
QDialog#QtSoftwareKeyboardDialog,
|
||||||
TouchScreenPreview {
|
QStackedWidget#topOSK {
|
||||||
qproperty-dotHighlightColor: #3daee9;
|
background: rgba(41, 41, 41, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDialog#OverlayDialog,
|
||||||
|
QStackedWidget#stackedDialog {
|
||||||
|
background: rgba(41, 41, 41, .7);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#boxOSK,
|
||||||
|
QWidget#lineOSK,
|
||||||
|
QWidget#richDialog,
|
||||||
|
QWidget#lineDialog {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#bottomOSK,
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
background: rgba(71, 69, 71, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#buttonsDialog,
|
||||||
|
QWidget#buttonsRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-top: 2px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#legendOSKnum {
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QWidget {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar {
|
||||||
|
background: #2a2929;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
|
||||||
|
border-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK {
|
||||||
|
border-bottom: 3px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK QLineEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK {
|
||||||
|
border: 2px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK QTextEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#richDialog QTextBrowser {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
padding: 35px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_header {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_sub,
|
||||||
|
QWidget#lineOSK QLabel#label_characters,
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich,
|
||||||
|
QWidget#boxOSK QLabel#label_characters_box {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#buttonsDialog,
|
||||||
|
QWidget#buttonsRichDialog,
|
||||||
|
QWidget#mainOSK,
|
||||||
|
QWidget#headerOSK,
|
||||||
|
QWidget#normalOSK,
|
||||||
|
QWidget#shiftOSK,
|
||||||
|
QWidget#numOSK,
|
||||||
|
QWidget#subOSK,
|
||||||
|
QWidget#inputOSK,
|
||||||
|
QWidget#inputBoxOSK,
|
||||||
|
QWidget#charactersOSK,
|
||||||
|
QWidget#charactersBoxOSK,
|
||||||
|
QWidget#legendOSK,
|
||||||
|
QWidget#legendOSK QWidget,
|
||||||
|
QWidget#legendOSKshift,
|
||||||
|
QWidget#legendOSKshift QWidget,
|
||||||
|
QWidget#legendOSKnum,
|
||||||
|
QWidget#legendOSKnum QWidget {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel,
|
||||||
|
QWidget#legendOSK QLabel,
|
||||||
|
QWidget#legendOSKshift QLabel,
|
||||||
|
QWidget#legendOSKnum QLabel {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_dialog {
|
||||||
|
padding: 20px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich {
|
||||||
|
padding: 0px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton {
|
||||||
|
color: rgba(1, 253, 201, 1);
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:focus,
|
||||||
|
QDialog#OverlayDialog QPushButton:hover {
|
||||||
|
color: rgba(1, 253, 201, 1);
|
||||||
|
background: rgba(58, 61, 66, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(150, 150, 150, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
background: rgba(80, 79, 80, 1);
|
||||||
|
border: 2px solid rgba(71, 69, 71, 1);
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background: rgba(95, 94, 95, 1);
|
||||||
|
border: 2px solid rgba(71, 69, 71, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 2px solid rgba(71, 69, 71, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
color: rgba(0, 0, 0, 1);
|
||||||
|
background: rgba(1, 253, 201, 1);
|
||||||
|
border: 2px solid rgba(71, 69, 71, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
background: rgba(58, 61, 66, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(150, 150, 150, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_B_dark.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_Y_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
color: rgba(44, 44, 44, 1);
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_plus_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
|
||||||
|
background: transparent;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
|
||||||
|
image: url(:/overlay/button_L_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
|
||||||
|
image: url(:/overlay/arrow_left_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
|
||||||
|
image: url(:/overlay/button_R_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
|
||||||
|
image: url(:/overlay/arrow_right_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
|
||||||
|
image: url(:/overlay/button_press_stick_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
|
||||||
|
image: url(:/overlay/button_X_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
|
||||||
|
image: url(:/overlay/button_A_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
color: rgba(144, 144, 144, 1);
|
||||||
|
background-color: rgba(95, 94, 95, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
|
||||||
|
color: rgba(144, 144, 144, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_B_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QFrame,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QFrame[frameShape="0"],
|
||||||
|
QDialog#OverlayDialog QFrame,
|
||||||
|
QDialog#OverlayDialog QFrame[frameShape="0"] {
|
||||||
|
border-radius: 0px;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Created by the qtsass compiler v0.1.1
|
Created by the qtsass compiler v0.1.1
|
||||||
|
|
||||||
The definitions are in the "qdarkstyle.qss._styles.scss" module
|
The definitions are in the "qdarkstyle.qss._styles.scss" module
|
||||||
|
|
||||||
WARNING! All changes made in this file will be lost!
|
WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
--------------------------------------------------------------------------- */
|
--------------------------------------------------------------------------- */
|
||||||
/* QDarkStyleSheet -----------------------------------------------------------
|
/* QDarkStyleSheet -----------------------------------------------------------
|
||||||
|
@ -15,34 +15,34 @@ It is based on three selecting colors, three greyish (background) colors
|
||||||
plus three whitish (foreground) colors. Each set of widgets of the same
|
plus three whitish (foreground) colors. Each set of widgets of the same
|
||||||
type have a header like this:
|
type have a header like this:
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
GroupName --------
|
GroupName --------
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
And each widget is separated with a header like this:
|
And each widget is separated with a header like this:
|
||||||
|
|
||||||
QWidgetName ------
|
QWidgetName ------
|
||||||
|
|
||||||
This makes more easy to find and change some css field. The basic
|
This makes more easy to find and change some css field. The basic
|
||||||
configuration is described bellow.
|
configuration is described bellow.
|
||||||
|
|
||||||
BACKGROUND -----------
|
BACKGROUND -----------
|
||||||
|
|
||||||
Light (unpressed)
|
Light (unpressed)
|
||||||
Normal (border, disabled, pressed, checked, toolbars, menus)
|
Normal (border, disabled, pressed, checked, toolbars, menus)
|
||||||
Dark (background)
|
Dark (background)
|
||||||
|
|
||||||
FOREGROUND -----------
|
FOREGROUND -----------
|
||||||
|
|
||||||
Light (texts/labels)
|
Light (texts/labels)
|
||||||
Normal (not used yet)
|
Normal (not used yet)
|
||||||
Dark (disabled texts)
|
Dark (disabled texts)
|
||||||
|
|
||||||
SELECTION ------------
|
SELECTION ------------
|
||||||
|
|
||||||
Light (selection/hover/active)
|
Light (selection/hover/active)
|
||||||
Normal (selected)
|
Normal (selected)
|
||||||
Dark (selected disabled)
|
Dark (selected disabled)
|
||||||
|
|
||||||
If a stranger configuration is required because of a bugfix or anything
|
If a stranger configuration is required because of a bugfix or anything
|
||||||
else, keep the comment on the line above so nobody changes it, including the
|
else, keep the comment on the line above so nobody changes it, including the
|
||||||
|
@ -2483,3 +2483,404 @@ QWidget#controllerPlayer7,
|
||||||
QWidget#controllerPlayer8 {
|
QWidget#controllerPlayer8 {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog,
|
||||||
|
QStackedWidget#topOSK {
|
||||||
|
background: rgba(15, 25, 34, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog,
|
||||||
|
QStackedWidget#stackedDialog {
|
||||||
|
background: rgba(15, 25, 34, .7);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#boxOSK,
|
||||||
|
QWidget#lineOSK,
|
||||||
|
QWidget#richDialog,
|
||||||
|
QWidget#lineDialog {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#bottomOSK,
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
background: rgba(31, 41, 51, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog,
|
||||||
|
QWidget#contentRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#buttonsDialog,
|
||||||
|
QWidget#buttonsRichDialog {
|
||||||
|
margin: 5px;
|
||||||
|
border-top: 2px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#legendOSKnum {
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QWidget {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar {
|
||||||
|
background: #19232d;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
|
||||||
|
QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
|
||||||
|
border-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#mainOSK QStackedWidget,
|
||||||
|
QDialog#OverlayDialog QStackedWidget {
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK {
|
||||||
|
border-bottom: 3px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputOSK QLineEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK {
|
||||||
|
border: 2px solid rgba(255, 255, 255, .9);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#inputBoxOSK QTextEdit {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#richDialog QTextBrowser {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
padding: 35px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_header {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#lineOSK QLabel#label_sub,
|
||||||
|
QWidget#lineOSK QLabel#label_characters,
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich,
|
||||||
|
QWidget#boxOSK QLabel#label_characters_box {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#buttonsDialog,
|
||||||
|
QWidget#buttonsRichDialog,
|
||||||
|
QWidget#mainOSK,
|
||||||
|
QWidget#headerOSK,
|
||||||
|
QWidget#normalOSK,
|
||||||
|
QWidget#shiftOSK,
|
||||||
|
QWidget#numOSK,
|
||||||
|
QWidget#subOSK,
|
||||||
|
QWidget#inputOSK,
|
||||||
|
QWidget#inputBoxOSK,
|
||||||
|
QWidget#charactersOSK,
|
||||||
|
QWidget#charactersBoxOSK,
|
||||||
|
QWidget#legendOSK,
|
||||||
|
QWidget#legendOSK QWidget,
|
||||||
|
QWidget#legendOSKshift,
|
||||||
|
QWidget#legendOSKshift QWidget,
|
||||||
|
QWidget#legendOSKnum,
|
||||||
|
QWidget#legendOSKnum QWidget {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel,
|
||||||
|
QWidget#legendOSK QLabel,
|
||||||
|
QWidget#legendOSKshift QLabel,
|
||||||
|
QWidget#legendOSKnum QLabel {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_dialog {
|
||||||
|
padding: 20px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#contentDialog QLabel#label_title,
|
||||||
|
QWidget#contentRichDialog QLabel#label_title_rich {
|
||||||
|
padding: 0px 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton {
|
||||||
|
color: rgba(1, 253, 201, 1);
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:focus,
|
||||||
|
QDialog#OverlayDialog QPushButton:hover {
|
||||||
|
color: rgba(1, 253, 201, 1);
|
||||||
|
background: rgba(18, 33, 46, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#OverlayDialog QPushButton:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(110, 122, 130, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QLabel {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
background: rgba(40, 51, 60, 1);
|
||||||
|
border: 2px solid rgba(31, 41, 51, 1);
|
||||||
|
border-radius: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background: rgba(55, 66, 75, 1);
|
||||||
|
border: 2px solid rgba(31, 41, 51, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 2px solid rgba(31, 41, 51, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
color: rgba(0, 0, 0, 1);
|
||||||
|
background: rgba(1, 253, 201, 1);
|
||||||
|
border: 2px solid rgba(31, 41, 51, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
background: rgba(18, 33, 46, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
|
||||||
|
color: rgba(240, 240, 240, 1);
|
||||||
|
background: rgba(110, 122, 130, 1);
|
||||||
|
border: 5px solid rgba(56, 189, 225, 1);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_B_dark.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_Y_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
|
||||||
|
color: rgba(44, 44, 44, 1);
|
||||||
|
background-position: right top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_plus_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
|
||||||
|
background-position: left top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-origin: content;
|
||||||
|
background-image: url(:/overlay/osk_button_shift_lock_off.png);
|
||||||
|
qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
|
||||||
|
qproperty-iconSize: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
|
||||||
|
background: transparent;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
|
||||||
|
image: url(:/overlay/button_L_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
|
||||||
|
image: url(:/overlay/arrow_left_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
|
||||||
|
image: url(:/overlay/button_R_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
|
||||||
|
image: url(:/overlay/arrow_right_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
|
||||||
|
image: url(:/overlay/button_press_stick_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
|
||||||
|
image: url(:/overlay/button_X_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
|
||||||
|
image: url(:/overlay/button_A_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
color: rgba(144, 144, 144, 1);
|
||||||
|
background-color: rgba(55, 66, 75, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
|
||||||
|
color: rgba(144, 144, 144, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_B_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||||
|
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
|
||||||
|
background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
|
||||||
|
}
|
||||||
|
|
|
@ -273,6 +273,7 @@ add_library(core STATIC
|
||||||
hle/service/am/applets/profile_select.h
|
hle/service/am/applets/profile_select.h
|
||||||
hle/service/am/applets/software_keyboard.cpp
|
hle/service/am/applets/software_keyboard.cpp
|
||||||
hle/service/am/applets/software_keyboard.h
|
hle/service/am/applets/software_keyboard.h
|
||||||
|
hle/service/am/applets/software_keyboard_types.h
|
||||||
hle/service/am/applets/web_browser.cpp
|
hle/service/am/applets/web_browser.cpp
|
||||||
hle/service/am/applets/web_browser.h
|
hle/service/am/applets/web_browser.h
|
||||||
hle/service/am/applets/web_types.h
|
hle/service/am/applets/web_types.h
|
||||||
|
|
|
@ -1,29 +1,149 @@
|
||||||
// Copyright 2018 yuzu emulator team
|
// Copyright 2021 yuzu Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/logging/backend.h"
|
#include <thread>
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/frontend/applets/software_keyboard.h"
|
#include "core/frontend/applets/software_keyboard.h"
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
|
|
||||||
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
|
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
|
||||||
|
|
||||||
void DefaultSoftwareKeyboardApplet::RequestText(
|
DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default;
|
||||||
std::function<void(std::optional<std::u16string>)> out,
|
|
||||||
SoftwareKeyboardParameters parameters) const {
|
|
||||||
if (parameters.initial_text.empty())
|
|
||||||
out(u"yuzu");
|
|
||||||
|
|
||||||
out(parameters.initial_text);
|
void DefaultSoftwareKeyboardApplet::InitializeKeyboard(
|
||||||
|
bool is_inline, KeyboardInitializeParameters initialize_parameters,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)> submit_normal_callback_,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback_) {
|
||||||
|
if (is_inline) {
|
||||||
|
LOG_WARNING(
|
||||||
|
Service_AM,
|
||||||
|
"(STUBBED) called, backend requested to initialize the inline software keyboard.");
|
||||||
|
|
||||||
|
submit_inline_callback = std::move(submit_inline_callback_);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(
|
||||||
|
Service_AM,
|
||||||
|
"(STUBBED) called, backend requested to initialize the normal software keyboard.");
|
||||||
|
|
||||||
|
submit_normal_callback = std::move(submit_normal_callback_);
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters = std::move(initialize_parameters);
|
||||||
|
|
||||||
|
LOG_INFO(Service_AM,
|
||||||
|
"\nKeyboardInitializeParameters:"
|
||||||
|
"\nok_text={}"
|
||||||
|
"\nheader_text={}"
|
||||||
|
"\nsub_text={}"
|
||||||
|
"\nguide_text={}"
|
||||||
|
"\ninitial_text={}"
|
||||||
|
"\nmax_text_length={}"
|
||||||
|
"\nmin_text_length={}"
|
||||||
|
"\ninitial_cursor_position={}"
|
||||||
|
"\ntype={}"
|
||||||
|
"\npassword_mode={}"
|
||||||
|
"\ntext_draw_type={}"
|
||||||
|
"\nkey_disable_flags={}"
|
||||||
|
"\nuse_blur_background={}"
|
||||||
|
"\nenable_backspace_button={}"
|
||||||
|
"\nenable_return_button={}"
|
||||||
|
"\ndisable_cancel_button={}",
|
||||||
|
Common::UTF16ToUTF8(parameters.ok_text), Common::UTF16ToUTF8(parameters.header_text),
|
||||||
|
Common::UTF16ToUTF8(parameters.sub_text), Common::UTF16ToUTF8(parameters.guide_text),
|
||||||
|
Common::UTF16ToUTF8(parameters.initial_text), parameters.max_text_length,
|
||||||
|
parameters.min_text_length, parameters.initial_cursor_position, parameters.type,
|
||||||
|
parameters.password_mode, parameters.text_draw_type, parameters.key_disable_flags.raw,
|
||||||
|
parameters.use_blur_background, parameters.enable_backspace_button,
|
||||||
|
parameters.enable_return_button, parameters.disable_cancel_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(
|
void DefaultSoftwareKeyboardApplet::ShowNormalKeyboard() const {
|
||||||
std::u16string error_message, std::function<void()> finished_check) const {
|
|
||||||
LOG_WARNING(Service_AM,
|
LOG_WARNING(Service_AM,
|
||||||
"(STUBBED) called - Default fallback software keyboard does not support text "
|
"(STUBBED) called, backend requested to show the normal software keyboard.");
|
||||||
"check! (error_message={})",
|
|
||||||
Common::UTF16ToUTF8(error_message));
|
SubmitNormalText(u"yuzu");
|
||||||
finished_check();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::ShowTextCheckDialog(
|
||||||
|
Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) const {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to show the text check dialog.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::ShowInlineKeyboard(
|
||||||
|
InlineAppearParameters appear_parameters) const {
|
||||||
|
LOG_WARNING(Service_AM,
|
||||||
|
"(STUBBED) called, backend requested to show the inline software keyboard.");
|
||||||
|
|
||||||
|
LOG_INFO(Service_AM,
|
||||||
|
"\nInlineAppearParameters:"
|
||||||
|
"\nmax_text_length={}"
|
||||||
|
"\nmin_text_length={}"
|
||||||
|
"\nkey_top_scale_x={}"
|
||||||
|
"\nkey_top_scale_y={}"
|
||||||
|
"\nkey_top_translate_x={}"
|
||||||
|
"\nkey_top_translate_y={}"
|
||||||
|
"\ntype={}"
|
||||||
|
"\nkey_disable_flags={}"
|
||||||
|
"\nkey_top_as_floating={}"
|
||||||
|
"\nenable_backspace_button={}"
|
||||||
|
"\nenable_return_button={}"
|
||||||
|
"\ndisable_cancel_button={}",
|
||||||
|
appear_parameters.max_text_length, appear_parameters.min_text_length,
|
||||||
|
appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y,
|
||||||
|
appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y,
|
||||||
|
appear_parameters.type, appear_parameters.key_disable_flags.raw,
|
||||||
|
appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button,
|
||||||
|
appear_parameters.enable_return_button, appear_parameters.disable_cancel_button);
|
||||||
|
|
||||||
|
std::thread([this] { SubmitInlineText(u"yuzu"); }).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::HideInlineKeyboard() const {
|
||||||
|
LOG_WARNING(Service_AM,
|
||||||
|
"(STUBBED) called, backend requested to hide the inline software keyboard.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::InlineTextChanged(InlineTextParameters text_parameters) const {
|
||||||
|
LOG_WARNING(Service_AM,
|
||||||
|
"(STUBBED) called, backend requested to change the inline keyboard text.");
|
||||||
|
|
||||||
|
LOG_INFO(Service_AM,
|
||||||
|
"\nInlineTextParameters:"
|
||||||
|
"\ninput_text={}"
|
||||||
|
"\ncursor_position={}",
|
||||||
|
Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
|
||||||
|
|
||||||
|
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
|
||||||
|
text_parameters.input_text, text_parameters.cursor_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::ExitKeyboard() const {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to exit the software keyboard.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::SubmitNormalText(std::u16string text) const {
|
||||||
|
submit_normal_callback(Service::AM::Applets::SwkbdResult::Ok, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSoftwareKeyboardApplet::SubmitInlineText(std::u16string_view text) const {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
|
||||||
|
for (std::size_t index = 0; index < text.size(); ++index) {
|
||||||
|
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
|
||||||
|
std::u16string(text.data(), text.data() + index + 1),
|
||||||
|
static_cast<s32>(index) + 1);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||||
|
}
|
||||||
|
|
||||||
|
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, std::u16string(text),
|
||||||
|
static_cast<s32>(text.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core::Frontend
|
} // namespace Core::Frontend
|
||||||
|
|
|
@ -1,54 +1,116 @@
|
||||||
// Copyright 2018 yuzu emulator team
|
// Copyright 2021 yuzu Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <thread>
|
||||||
#include <string>
|
|
||||||
#include "common/bit_field.h"
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "core/hle/service/am/applets/software_keyboard_types.h"
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
struct SoftwareKeyboardParameters {
|
|
||||||
std::u16string submit_text;
|
struct KeyboardInitializeParameters {
|
||||||
|
std::u16string ok_text;
|
||||||
std::u16string header_text;
|
std::u16string header_text;
|
||||||
std::u16string sub_text;
|
std::u16string sub_text;
|
||||||
std::u16string guide_text;
|
std::u16string guide_text;
|
||||||
std::u16string initial_text;
|
std::u16string initial_text;
|
||||||
std::size_t max_length;
|
u32 max_text_length;
|
||||||
bool password;
|
u32 min_text_length;
|
||||||
bool cursor_at_beginning;
|
s32 initial_cursor_position;
|
||||||
|
Service::AM::Applets::SwkbdType type;
|
||||||
|
Service::AM::Applets::SwkbdPasswordMode password_mode;
|
||||||
|
Service::AM::Applets::SwkbdTextDrawType text_draw_type;
|
||||||
|
Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
|
||||||
|
bool use_blur_background;
|
||||||
|
bool enable_backspace_button;
|
||||||
|
bool enable_return_button;
|
||||||
|
bool disable_cancel_button;
|
||||||
|
};
|
||||||
|
|
||||||
union {
|
struct InlineAppearParameters {
|
||||||
u8 value;
|
u32 max_text_length;
|
||||||
|
u32 min_text_length;
|
||||||
|
f32 key_top_scale_x;
|
||||||
|
f32 key_top_scale_y;
|
||||||
|
f32 key_top_translate_x;
|
||||||
|
f32 key_top_translate_y;
|
||||||
|
Service::AM::Applets::SwkbdType type;
|
||||||
|
Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
|
||||||
|
bool key_top_as_floating;
|
||||||
|
bool enable_backspace_button;
|
||||||
|
bool enable_return_button;
|
||||||
|
bool disable_cancel_button;
|
||||||
|
};
|
||||||
|
|
||||||
BitField<1, 1, u8> disable_space;
|
struct InlineTextParameters {
|
||||||
BitField<2, 1, u8> disable_address;
|
std::u16string input_text;
|
||||||
BitField<3, 1, u8> disable_percent;
|
s32 cursor_position;
|
||||||
BitField<4, 1, u8> disable_slash;
|
|
||||||
BitField<6, 1, u8> disable_number;
|
|
||||||
BitField<7, 1, u8> disable_download_code;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoftwareKeyboardApplet {
|
class SoftwareKeyboardApplet {
|
||||||
public:
|
public:
|
||||||
virtual ~SoftwareKeyboardApplet();
|
virtual ~SoftwareKeyboardApplet();
|
||||||
|
|
||||||
virtual void RequestText(std::function<void(std::optional<std::u16string>)> out,
|
virtual void InitializeKeyboard(
|
||||||
SoftwareKeyboardParameters parameters) const = 0;
|
bool is_inline, KeyboardInitializeParameters initialize_parameters,
|
||||||
virtual void SendTextCheckDialog(std::u16string error_message,
|
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
|
||||||
std::function<void()> finished_check) const = 0;
|
submit_normal_callback_,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback_) = 0;
|
||||||
|
|
||||||
|
virtual void ShowNormalKeyboard() const = 0;
|
||||||
|
|
||||||
|
virtual void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) const = 0;
|
||||||
|
|
||||||
|
virtual void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const = 0;
|
||||||
|
|
||||||
|
virtual void HideInlineKeyboard() const = 0;
|
||||||
|
|
||||||
|
virtual void InlineTextChanged(InlineTextParameters text_parameters) const = 0;
|
||||||
|
|
||||||
|
virtual void ExitKeyboard() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
|
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
|
||||||
public:
|
public:
|
||||||
void RequestText(std::function<void(std::optional<std::u16string>)> out,
|
~DefaultSoftwareKeyboardApplet() override;
|
||||||
SoftwareKeyboardParameters parameters) const override;
|
|
||||||
void SendTextCheckDialog(std::u16string error_message,
|
void InitializeKeyboard(
|
||||||
std::function<void()> finished_check) const override;
|
bool is_inline, KeyboardInitializeParameters initialize_parameters,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
|
||||||
|
submit_normal_callback_,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback_) override;
|
||||||
|
|
||||||
|
void ShowNormalKeyboard() const override;
|
||||||
|
|
||||||
|
void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) const override;
|
||||||
|
|
||||||
|
void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const override;
|
||||||
|
|
||||||
|
void HideInlineKeyboard() const override;
|
||||||
|
|
||||||
|
void InlineTextChanged(InlineTextParameters text_parameters) const override;
|
||||||
|
|
||||||
|
void ExitKeyboard() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SubmitNormalText(std::u16string text) const;
|
||||||
|
void SubmitInlineText(std::u16string_view text) const;
|
||||||
|
|
||||||
|
KeyboardInitializeParameters parameters;
|
||||||
|
|
||||||
|
mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
|
||||||
|
submit_normal_callback;
|
||||||
|
mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core::Frontend
|
} // namespace Core::Frontend
|
||||||
|
|
|
@ -12,7 +12,9 @@ InputInterpreter::InputInterpreter(Core::System& system)
|
||||||
: npad{system.ServiceManager()
|
: npad{system.ServiceManager()
|
||||||
.GetService<Service::HID::Hid>("hid")
|
.GetService<Service::HID::Hid>("hid")
|
||||||
->GetAppletResource()
|
->GetAppletResource()
|
||||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {}
|
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
|
||||||
|
ResetButtonStates();
|
||||||
|
}
|
||||||
|
|
||||||
InputInterpreter::~InputInterpreter() = default;
|
InputInterpreter::~InputInterpreter() = default;
|
||||||
|
|
||||||
|
@ -25,6 +27,17 @@ void InputInterpreter::PollInput() {
|
||||||
button_states[current_index] = button_state;
|
button_states[current_index] = button_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputInterpreter::ResetButtonStates() {
|
||||||
|
previous_index = 0;
|
||||||
|
current_index = 0;
|
||||||
|
|
||||||
|
button_states[0] = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
for (std::size_t i = 1; i < button_states.size(); ++i) {
|
||||||
|
button_states[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool InputInterpreter::IsButtonPressed(HIDButton button) const {
|
bool InputInterpreter::IsButtonPressed(HIDButton button) const {
|
||||||
return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0;
|
return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,9 @@ public:
|
||||||
/// Gets a button state from HID and inserts it into the array of button states.
|
/// Gets a button state from HID and inserts it into the array of button states.
|
||||||
void PollInput();
|
void PollInput();
|
||||||
|
|
||||||
|
/// Resets all the button states to their defaults.
|
||||||
|
void ResetButtonStates();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the button is pressed.
|
* Checks whether the button is pressed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -75,10 +75,14 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
// Populate the object lists with the data in the IPC request.
|
// Populate the object lists with the data in the IPC request.
|
||||||
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
|
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
|
||||||
copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
|
const u32 copy_handle{rp.Pop<Handle>()};
|
||||||
|
copy_handles.push_back(copy_handle);
|
||||||
|
copy_objects.push_back(handle_table.GetGeneric(copy_handle));
|
||||||
}
|
}
|
||||||
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
|
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
|
||||||
move_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
|
const u32 move_handle{rp.Pop<Handle>()};
|
||||||
|
move_handles.push_back(move_handle);
|
||||||
|
move_objects.push_back(handle_table.GetGeneric(move_handle));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For responses we just ignore the handles, they're empty and will be populated when
|
// For responses we just ignore the handles, they're empty and will be populated when
|
||||||
|
|
|
@ -210,6 +210,14 @@ public:
|
||||||
/// Helper function to test whether the output buffer at buffer_index can be written
|
/// Helper function to test whether the output buffer at buffer_index can be written
|
||||||
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
|
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
|
||||||
|
|
||||||
|
Handle GetCopyHandle(std::size_t index) const {
|
||||||
|
return copy_handles.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle GetMoveHandle(std::size_t index) const {
|
||||||
|
return move_handles.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::shared_ptr<T> GetCopyObject(std::size_t index) {
|
std::shared_ptr<T> GetCopyObject(std::size_t index) {
|
||||||
return DynamicObjectCast<T>(copy_objects.at(index));
|
return DynamicObjectCast<T>(copy_objects.at(index));
|
||||||
|
@ -285,6 +293,8 @@ private:
|
||||||
std::shared_ptr<Kernel::ServerSession> server_session;
|
std::shared_ptr<Kernel::ServerSession> server_session;
|
||||||
std::shared_ptr<KThread> thread;
|
std::shared_ptr<KThread> thread;
|
||||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
||||||
|
boost::container::small_vector<Handle, 8> move_handles;
|
||||||
|
boost::container::small_vector<Handle, 8> copy_handles;
|
||||||
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
|
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
|
||||||
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
|
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
|
||||||
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
||||||
|
|
|
@ -971,7 +971,7 @@ private:
|
||||||
|
|
||||||
auto storage = applet->GetBroker().PopNormalDataToGame();
|
auto storage = applet->GetBroker().PopNormalDataToGame();
|
||||||
if (storage == nullptr) {
|
if (storage == nullptr) {
|
||||||
LOG_ERROR(Service_AM,
|
LOG_DEBUG(Service_AM,
|
||||||
"storage is a nullptr. There is no data in the current normal channel");
|
"storage is a nullptr. There is no data in the current normal channel");
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NO_DATA_IN_CHANNEL);
|
rb.Push(ERR_NO_DATA_IN_CHANNEL);
|
||||||
|
@ -1002,7 +1002,7 @@ private:
|
||||||
|
|
||||||
auto storage = applet->GetBroker().PopInteractiveDataToGame();
|
auto storage = applet->GetBroker().PopInteractiveDataToGame();
|
||||||
if (storage == nullptr) {
|
if (storage == nullptr) {
|
||||||
LOG_ERROR(Service_AM,
|
LOG_DEBUG(Service_AM,
|
||||||
"storage is a nullptr. There is no data in the current interactive channel");
|
"storage is a nullptr. There is no data in the current interactive channel");
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NO_DATA_IN_CHANNEL);
|
rb.Push(ERR_NO_DATA_IN_CHANNEL);
|
||||||
|
@ -1125,7 +1125,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
|
||||||
{2, nullptr, "AreAnyLibraryAppletsLeft"},
|
{2, nullptr, "AreAnyLibraryAppletsLeft"},
|
||||||
{10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
|
{10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
|
||||||
{11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
|
{11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
|
||||||
{12, nullptr, "CreateHandleStorage"},
|
{12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
|
@ -1134,14 +1134,15 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default;
|
||||||
|
|
||||||
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
|
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const auto applet_id = rp.PopRaw<Applets::AppletId>();
|
const auto applet_id = rp.PopRaw<Applets::AppletId>();
|
||||||
const auto applet_mode = rp.PopRaw<u32>();
|
const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>();
|
||||||
|
|
||||||
LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
|
LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
|
||||||
applet_mode);
|
applet_mode);
|
||||||
|
|
||||||
const auto& applet_manager{system.GetAppletManager()};
|
const auto& applet_manager{system.GetAppletManager()};
|
||||||
const auto applet = applet_manager.GetApplet(applet_id);
|
const auto applet = applet_manager.GetApplet(applet_id, applet_mode);
|
||||||
|
|
||||||
if (applet == nullptr) {
|
if (applet == nullptr) {
|
||||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
||||||
|
@ -1159,9 +1160,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
|
||||||
|
|
||||||
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const u64 size{rp.Pop<u64>()};
|
|
||||||
|
const s64 size{rp.Pop<s64>()};
|
||||||
|
|
||||||
LOG_DEBUG(Service_AM, "called, size={}", size);
|
LOG_DEBUG(Service_AM, "called, size={}", size);
|
||||||
|
|
||||||
|
if (size <= 0) {
|
||||||
|
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<u8> buffer(size);
|
std::vector<u8> buffer(size);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
@ -1170,18 +1180,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
|
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
rp.SetCurrentOffset(3);
|
struct Parameters {
|
||||||
const auto handle{rp.Pop<Kernel::Handle>()};
|
u8 permissions;
|
||||||
|
s64 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto parameters{rp.PopRaw<Parameters>()};
|
||||||
|
const auto handle{ctx.GetCopyHandle(0)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions,
|
||||||
|
parameters.size, handle);
|
||||||
|
|
||||||
|
if (parameters.size <= 0) {
|
||||||
|
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto transfer_mem =
|
auto transfer_mem =
|
||||||
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
|
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
|
||||||
|
|
||||||
if (transfer_mem == nullptr) {
|
if (transfer_mem == nullptr) {
|
||||||
LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
|
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* const mem_begin = transfer_mem->GetPointer();
|
||||||
|
const u8* const mem_end = mem_begin + transfer_mem->GetSize();
|
||||||
|
std::vector<u8> memory{mem_begin, mem_end};
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface<IStorage>(system, std::move(memory));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
const s64 size{rp.Pop<s64>()};
|
||||||
|
const auto handle{ctx.GetCopyHandle(0)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
|
||||||
|
|
||||||
|
if (size <= 0) {
|
||||||
|
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto transfer_mem =
|
||||||
|
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
|
||||||
|
|
||||||
|
if (transfer_mem == nullptr) {
|
||||||
|
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(RESULT_UNKNOWN);
|
rb.Push(RESULT_UNKNOWN);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -254,6 +254,7 @@ private:
|
||||||
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
|
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
|
||||||
void CreateStorage(Kernel::HLERequestContext& ctx);
|
void CreateStorage(Kernel::HLERequestContext& ctx);
|
||||||
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
|
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
|
||||||
|
void CreateHandleStorage(Kernel::HLERequestContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
|
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
|
||||||
|
|
|
@ -241,31 +241,31 @@ void AppletManager::ClearAll() {
|
||||||
frontend = {};
|
frontend = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
|
std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode mode) const {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case AppletId::Auth:
|
case AppletId::Auth:
|
||||||
return std::make_shared<Auth>(system, *frontend.parental_controls);
|
return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
|
||||||
case AppletId::Controller:
|
case AppletId::Controller:
|
||||||
return std::make_shared<Controller>(system, *frontend.controller);
|
return std::make_shared<Controller>(system, mode, *frontend.controller);
|
||||||
case AppletId::Error:
|
case AppletId::Error:
|
||||||
return std::make_shared<Error>(system, *frontend.error);
|
return std::make_shared<Error>(system, mode, *frontend.error);
|
||||||
case AppletId::ProfileSelect:
|
case AppletId::ProfileSelect:
|
||||||
return std::make_shared<ProfileSelect>(system, *frontend.profile_select);
|
return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
|
||||||
case AppletId::SoftwareKeyboard:
|
case AppletId::SoftwareKeyboard:
|
||||||
return std::make_shared<SoftwareKeyboard>(system, *frontend.software_keyboard);
|
return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
|
||||||
case AppletId::Web:
|
case AppletId::Web:
|
||||||
case AppletId::Shop:
|
case AppletId::Shop:
|
||||||
case AppletId::OfflineWeb:
|
case AppletId::OfflineWeb:
|
||||||
case AppletId::LoginShare:
|
case AppletId::LoginShare:
|
||||||
case AppletId::WebAuth:
|
case AppletId::WebAuth:
|
||||||
return std::make_shared<WebBrowser>(system, *frontend.web_browser);
|
return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser);
|
||||||
case AppletId::PhotoViewer:
|
case AppletId::PhotoViewer:
|
||||||
return std::make_shared<PhotoViewer>(system, *frontend.photo_viewer);
|
return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer);
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_MSG(
|
UNIMPLEMENTED_MSG(
|
||||||
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
|
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
|
||||||
static_cast<u8>(id));
|
static_cast<u8>(id));
|
||||||
return std::make_shared<StubApplet>(system, id);
|
return std::make_shared<StubApplet>(system, id, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,14 @@ enum class AppletId : u32 {
|
||||||
MyPage = 0x1A,
|
MyPage = 0x1A,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class LibraryAppletMode : u32 {
|
||||||
|
AllForeground = 0,
|
||||||
|
Background = 1,
|
||||||
|
NoUI = 2,
|
||||||
|
BackgroundIndirectDisplay = 3,
|
||||||
|
AllForegroundInitiallyHidden = 4,
|
||||||
|
};
|
||||||
|
|
||||||
class AppletDataBroker final {
|
class AppletDataBroker final {
|
||||||
public:
|
public:
|
||||||
explicit AppletDataBroker(Kernel::KernelCore& kernel_);
|
explicit AppletDataBroker(Kernel::KernelCore& kernel_);
|
||||||
|
@ -200,7 +208,7 @@ public:
|
||||||
void SetDefaultAppletsIfMissing();
|
void SetDefaultAppletsIfMissing();
|
||||||
void ClearAll();
|
void ClearAll();
|
||||||
|
|
||||||
std::shared_ptr<Applet> GetApplet(AppletId id) const;
|
std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppletFrontendSet frontend;
|
AppletFrontendSet frontend;
|
||||||
|
|
|
@ -45,8 +45,9 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_)
|
Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
const Core::Frontend::ControllerApplet& frontend_)
|
||||||
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
|
||||||
|
|
||||||
Controller::~Controller() = default;
|
Controller::~Controller() = default;
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,8 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
|
||||||
|
|
||||||
class Controller final : public Applet {
|
class Controller final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_);
|
explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
|
const Core::Frontend::ControllerApplet& frontend_);
|
||||||
~Controller() override;
|
~Controller() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -119,6 +120,7 @@ public:
|
||||||
void ConfigurationComplete();
|
void ConfigurationComplete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
const Core::Frontend::ControllerApplet& frontend;
|
const Core::Frontend::ControllerApplet& frontend;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,9 @@ ResultCode Decode64BitError(u64 error) {
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
|
Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
const Core::Frontend::ErrorApplet& frontend_)
|
||||||
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
|
||||||
|
|
||||||
Error::~Error() = default;
|
Error::~Error() = default;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ enum class ErrorAppletMode : u8 {
|
||||||
|
|
||||||
class Error final : public Applet {
|
class Error final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_);
|
explicit Error(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
|
const Core::Frontend::ErrorApplet& frontend_);
|
||||||
~Error() override;
|
~Error() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -40,6 +41,7 @@ public:
|
||||||
private:
|
private:
|
||||||
union ErrorArguments;
|
union ErrorArguments;
|
||||||
|
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
const Core::Frontend::ErrorApplet& frontend;
|
const Core::Frontend::ErrorApplet& frontend;
|
||||||
ResultCode error_code = RESULT_SUCCESS;
|
ResultCode error_code = RESULT_SUCCESS;
|
||||||
ErrorAppletMode mode = ErrorAppletMode::ShowError;
|
ErrorAppletMode mode = ErrorAppletMode::ShowError;
|
||||||
|
|
|
@ -37,8 +37,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
|
Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
Core::Frontend::ParentalControlsApplet& frontend_)
|
||||||
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
|
||||||
|
|
||||||
Auth::~Auth() = default;
|
Auth::~Auth() = default;
|
||||||
|
|
||||||
|
@ -152,8 +153,9 @@ void Auth::AuthFinished(bool is_successful) {
|
||||||
broker.SignalStateChanged();
|
broker.SignalStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
|
PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
const Core::Frontend::PhotoViewerApplet& frontend_)
|
||||||
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
|
||||||
|
|
||||||
PhotoViewer::~PhotoViewer() = default;
|
PhotoViewer::~PhotoViewer() = default;
|
||||||
|
|
||||||
|
@ -202,8 +204,8 @@ void PhotoViewer::ViewFinished() {
|
||||||
broker.SignalStateChanged();
|
broker.SignalStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
StubApplet::StubApplet(Core::System& system_, AppletId id_)
|
StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
|
||||||
: Applet{system_.Kernel()}, id{id_}, system{system_} {}
|
: Applet{system_.Kernel()}, id{id_}, applet_mode{applet_mode_}, system{system_} {}
|
||||||
|
|
||||||
StubApplet::~StubApplet() = default;
|
StubApplet::~StubApplet() = default;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ enum class AuthAppletType : u32 {
|
||||||
|
|
||||||
class Auth final : public Applet {
|
class Auth final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_);
|
explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
|
Core::Frontend::ParentalControlsApplet& frontend_);
|
||||||
~Auth() override;
|
~Auth() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -32,6 +33,7 @@ public:
|
||||||
void AuthFinished(bool is_successful = true);
|
void AuthFinished(bool is_successful = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
Core::Frontend::ParentalControlsApplet& frontend;
|
Core::Frontend::ParentalControlsApplet& frontend;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
|
@ -50,7 +52,8 @@ enum class PhotoViewerAppletMode : u8 {
|
||||||
|
|
||||||
class PhotoViewer final : public Applet {
|
class PhotoViewer final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_);
|
explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
|
const Core::Frontend::PhotoViewerApplet& frontend_);
|
||||||
~PhotoViewer() override;
|
~PhotoViewer() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -62,6 +65,7 @@ public:
|
||||||
void ViewFinished();
|
void ViewFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
const Core::Frontend::PhotoViewerApplet& frontend;
|
const Core::Frontend::PhotoViewerApplet& frontend;
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
|
PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
|
||||||
|
@ -70,7 +74,7 @@ private:
|
||||||
|
|
||||||
class StubApplet final : public Applet {
|
class StubApplet final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit StubApplet(Core::System& system_, AppletId id_);
|
explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_);
|
||||||
~StubApplet() override;
|
~StubApplet() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -82,6 +86,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppletId id;
|
AppletId id;
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace Service::AM::Applets {
|
||||||
|
|
||||||
constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
|
constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
|
||||||
|
|
||||||
ProfileSelect::ProfileSelect(Core::System& system_,
|
ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
const Core::Frontend::ProfileSelectApplet& frontend_)
|
const Core::Frontend::ProfileSelectApplet& frontend_)
|
||||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
|
||||||
|
|
||||||
ProfileSelect::~ProfileSelect() = default;
|
ProfileSelect::~ProfileSelect() = default;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco
|
||||||
|
|
||||||
class ProfileSelect final : public Applet {
|
class ProfileSelect final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit ProfileSelect(Core::System& system_,
|
explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
const Core::Frontend::ProfileSelectApplet& frontend_);
|
const Core::Frontend::ProfileSelectApplet& frontend_);
|
||||||
~ProfileSelect() override;
|
~ProfileSelect() override;
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ public:
|
||||||
void SelectionComplete(std::optional<Common::UUID> uuid);
|
void SelectionComplete(std::optional<Common::UUID> uuid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
const Core::Frontend::ProfileSelectApplet& frontend;
|
const Core::Frontend::ProfileSelectApplet& frontend;
|
||||||
|
|
||||||
UserSelectionConfig config;
|
UserSelectionConfig config;
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
// Copyright 2018 yuzu emulator team
|
// Copyright 2021 yuzu Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/am/am.h"
|
|
||||||
#include "core/hle/service/am/applets/applets.h"
|
#include "core/hle/service/am/applets/applets.h"
|
||||||
|
#include "core/hle/service/am/applets/software_keyboard_types.h"
|
||||||
union ResultCode;
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
|
@ -22,45 +16,10 @@ class System;
|
||||||
|
|
||||||
namespace Service::AM::Applets {
|
namespace Service::AM::Applets {
|
||||||
|
|
||||||
enum class KeysetDisable : u32 {
|
|
||||||
Space = 0x02,
|
|
||||||
Address = 0x04,
|
|
||||||
Percent = 0x08,
|
|
||||||
Slashes = 0x10,
|
|
||||||
Numbers = 0x40,
|
|
||||||
DownloadCode = 0x80,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KeyboardConfig {
|
|
||||||
INSERT_PADDING_BYTES(4);
|
|
||||||
std::array<char16_t, 9> submit_text;
|
|
||||||
u16_le left_symbol_key;
|
|
||||||
u16_le right_symbol_key;
|
|
||||||
INSERT_PADDING_BYTES(1);
|
|
||||||
KeysetDisable keyset_disable_bitmask;
|
|
||||||
u32_le initial_cursor_position;
|
|
||||||
std::array<char16_t, 65> header_text;
|
|
||||||
std::array<char16_t, 129> sub_text;
|
|
||||||
std::array<char16_t, 257> guide_text;
|
|
||||||
u32_le length_limit;
|
|
||||||
INSERT_PADDING_BYTES(4);
|
|
||||||
u32_le is_password;
|
|
||||||
INSERT_PADDING_BYTES(5);
|
|
||||||
bool utf_8;
|
|
||||||
bool draw_background;
|
|
||||||
u32_le initial_string_offset;
|
|
||||||
u32_le initial_string_size;
|
|
||||||
u32_le user_dictionary_offset;
|
|
||||||
u32_le user_dictionary_size;
|
|
||||||
bool text_check;
|
|
||||||
u64_le text_check_callback;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect size.");
|
|
||||||
|
|
||||||
class SoftwareKeyboard final : public Applet {
|
class SoftwareKeyboard final : public Applet {
|
||||||
public:
|
public:
|
||||||
explicit SoftwareKeyboard(Core::System& system_,
|
explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
const Core::Frontend::SoftwareKeyboardApplet& frontend_);
|
Core::Frontend::SoftwareKeyboardApplet& frontend_);
|
||||||
~SoftwareKeyboard() override;
|
~SoftwareKeyboard() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
@ -70,17 +29,139 @@ public:
|
||||||
void ExecuteInteractive() override;
|
void ExecuteInteractive() override;
|
||||||
void Execute() override;
|
void Execute() override;
|
||||||
|
|
||||||
void WriteText(std::optional<std::u16string> text);
|
/**
|
||||||
|
* Submits the input text to the application.
|
||||||
|
* If text checking is enabled, the application will verify the input text.
|
||||||
|
* If use_utf8 is enabled, the input text will be converted to UTF-8 prior to being submitted.
|
||||||
|
* This should only be used by the normal software keyboard.
|
||||||
|
*
|
||||||
|
* @param result SwkbdResult enum
|
||||||
|
* @param submitted_text UTF-16 encoded string
|
||||||
|
*/
|
||||||
|
void SubmitTextNormal(SwkbdResult result, std::u16string submitted_text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the input text to the application.
|
||||||
|
* If utf8_mode is enabled, the input text will be converted to UTF-8 prior to being submitted.
|
||||||
|
* This should only be used by the inline software keyboard.
|
||||||
|
*
|
||||||
|
* @param reply_type SwkbdReplyType enum
|
||||||
|
* @param submitted_text UTF-16 encoded string
|
||||||
|
* @param cursor_position The current position of the text cursor
|
||||||
|
*/
|
||||||
|
void SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
|
||||||
|
s32 cursor_position);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Core::Frontend::SoftwareKeyboardApplet& frontend;
|
/// Initializes the normal software keyboard.
|
||||||
|
void InitializeForeground();
|
||||||
|
|
||||||
KeyboardConfig config;
|
/// Initializes the inline software keyboard.
|
||||||
std::u16string initial_text;
|
void InitializeBackground(LibraryAppletMode applet_mode);
|
||||||
bool complete = false;
|
|
||||||
bool is_inline = false;
|
/// Processes the text check sent by the application.
|
||||||
std::vector<u8> final_data;
|
void ProcessTextCheck();
|
||||||
|
|
||||||
|
/// Processes the inline software keyboard request command sent by the application.
|
||||||
|
void ProcessInlineKeyboardRequest();
|
||||||
|
|
||||||
|
/// Submits the input text and exits the applet.
|
||||||
|
void SubmitNormalOutputAndExit(SwkbdResult result, std::u16string submitted_text);
|
||||||
|
|
||||||
|
/// Submits the input text for text checking.
|
||||||
|
void SubmitForTextCheck(std::u16string submitted_text);
|
||||||
|
|
||||||
|
/// Sends a reply to the application after processing a request command.
|
||||||
|
void SendReply(SwkbdReplyType reply_type);
|
||||||
|
|
||||||
|
/// Changes the inline keyboard state.
|
||||||
|
void ChangeState(SwkbdState state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals the frontend to initialize the software keyboard with common parameters.
|
||||||
|
* This initializes either the normal software keyboard or the inline software keyboard
|
||||||
|
* depending on the state of is_background.
|
||||||
|
* Note that this does not cause the keyboard to appear.
|
||||||
|
* Use the respective Show*Keyboard() functions to cause the respective keyboards to appear.
|
||||||
|
*/
|
||||||
|
void InitializeFrontendKeyboard();
|
||||||
|
|
||||||
|
/// Signals the frontend to show the normal software keyboard.
|
||||||
|
void ShowNormalKeyboard();
|
||||||
|
|
||||||
|
/// Signals the frontend to show the text check dialog.
|
||||||
|
void ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message);
|
||||||
|
|
||||||
|
/// Signals the frontend to show the inline software keyboard.
|
||||||
|
void ShowInlineKeyboard();
|
||||||
|
|
||||||
|
/// Signals the frontend to hide the inline software keyboard.
|
||||||
|
void HideInlineKeyboard();
|
||||||
|
|
||||||
|
/// Signals the frontend that the current inline keyboard text has changed.
|
||||||
|
void InlineTextChanged();
|
||||||
|
|
||||||
|
/// Signals both the frontend and application that the software keyboard is exiting.
|
||||||
|
void ExitKeyboard();
|
||||||
|
|
||||||
|
// Inline Software Keyboard Requests
|
||||||
|
|
||||||
|
void RequestFinalize(const std::vector<u8>& request_data);
|
||||||
|
void RequestSetUserWordInfo(const std::vector<u8>& request_data);
|
||||||
|
void RequestSetCustomizeDic(const std::vector<u8>& request_data);
|
||||||
|
void RequestCalc(const std::vector<u8>& request_data);
|
||||||
|
void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
|
||||||
|
void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
|
||||||
|
void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
|
||||||
|
void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data);
|
||||||
|
|
||||||
|
// Inline Software Keyboard Replies
|
||||||
|
|
||||||
|
void ReplyFinishedInitialize();
|
||||||
|
void ReplyDefault();
|
||||||
|
void ReplyChangedString();
|
||||||
|
void ReplyMovedCursor();
|
||||||
|
void ReplyMovedTab();
|
||||||
|
void ReplyDecidedEnter();
|
||||||
|
void ReplyDecidedCancel();
|
||||||
|
void ReplyChangedStringUtf8();
|
||||||
|
void ReplyMovedCursorUtf8();
|
||||||
|
void ReplyDecidedEnterUtf8();
|
||||||
|
void ReplyUnsetCustomizeDic();
|
||||||
|
void ReplyReleasedUserWordInfo();
|
||||||
|
void ReplyUnsetCustomizedDictionaries();
|
||||||
|
void ReplyChangedStringV2();
|
||||||
|
void ReplyMovedCursorV2();
|
||||||
|
void ReplyChangedStringUtf8V2();
|
||||||
|
void ReplyMovedCursorUtf8V2();
|
||||||
|
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
|
Core::Frontend::SoftwareKeyboardApplet& frontend;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
|
SwkbdAppletVersion swkbd_applet_version;
|
||||||
|
|
||||||
|
SwkbdConfigCommon swkbd_config_common;
|
||||||
|
SwkbdConfigOld swkbd_config_old;
|
||||||
|
SwkbdConfigOld2 swkbd_config_old2;
|
||||||
|
SwkbdConfigNew swkbd_config_new;
|
||||||
|
std::u16string initial_text;
|
||||||
|
|
||||||
|
SwkbdState swkbd_state{SwkbdState::NotInitialized};
|
||||||
|
SwkbdInitializeArg swkbd_initialize_arg;
|
||||||
|
SwkbdCalcArg swkbd_calc_arg;
|
||||||
|
bool use_changed_string_v2{false};
|
||||||
|
bool use_moved_cursor_v2{false};
|
||||||
|
bool inline_use_utf8{false};
|
||||||
|
s32 current_cursor_position{};
|
||||||
|
|
||||||
|
std::u16string current_text;
|
||||||
|
|
||||||
|
bool is_background{false};
|
||||||
|
|
||||||
|
bool complete{false};
|
||||||
|
ResultCode status{RESULT_SUCCESS};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::AM::Applets
|
} // namespace Service::AM::Applets
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "common/bit_field.h"
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/swap.h"
|
||||||
|
|
||||||
|
namespace Service::AM::Applets {
|
||||||
|
|
||||||
|
constexpr std::size_t MAX_OK_TEXT_LENGTH = 8;
|
||||||
|
constexpr std::size_t MAX_HEADER_TEXT_LENGTH = 64;
|
||||||
|
constexpr std::size_t MAX_SUB_TEXT_LENGTH = 128;
|
||||||
|
constexpr std::size_t MAX_GUIDE_TEXT_LENGTH = 256;
|
||||||
|
constexpr std::size_t STRING_BUFFER_SIZE = 0x7D4;
|
||||||
|
|
||||||
|
enum class SwkbdAppletVersion : u32_le {
|
||||||
|
Version5 = 0x5, // 1.0.0
|
||||||
|
Version65542 = 0x10006, // 2.0.0 - 2.3.0
|
||||||
|
Version196615 = 0x30007, // 3.0.0 - 3.0.2
|
||||||
|
Version262152 = 0x40008, // 4.0.0 - 4.1.0
|
||||||
|
Version327689 = 0x50009, // 5.0.0 - 5.1.0
|
||||||
|
Version393227 = 0x6000B, // 6.0.0 - 7.0.1
|
||||||
|
Version524301 = 0x8000D, // 8.0.0+
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdType : u32 {
|
||||||
|
Normal,
|
||||||
|
NumberPad,
|
||||||
|
Qwerty,
|
||||||
|
Unknown3,
|
||||||
|
Latin,
|
||||||
|
SimplifiedChinese,
|
||||||
|
TraditionalChinese,
|
||||||
|
Korean,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdInitialCursorPosition : u32 {
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdPasswordMode : u32 {
|
||||||
|
Disabled,
|
||||||
|
Enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdTextDrawType : u32 {
|
||||||
|
Line,
|
||||||
|
Box,
|
||||||
|
DownloadCode,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdResult : u32 {
|
||||||
|
Ok,
|
||||||
|
Cancel,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdTextCheckResult : u32 {
|
||||||
|
Success,
|
||||||
|
Failure,
|
||||||
|
Confirm,
|
||||||
|
Silent,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdState : u32 {
|
||||||
|
NotInitialized = 0x0,
|
||||||
|
InitializedIsHidden = 0x1,
|
||||||
|
InitializedIsAppearing = 0x2,
|
||||||
|
InitializedIsShown = 0x3,
|
||||||
|
InitializedIsDisappearing = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdRequestCommand : u32 {
|
||||||
|
Finalize = 0x4,
|
||||||
|
SetUserWordInfo = 0x6,
|
||||||
|
SetCustomizeDic = 0x7,
|
||||||
|
Calc = 0xA,
|
||||||
|
SetCustomizedDictionaries = 0xB,
|
||||||
|
UnsetCustomizedDictionaries = 0xC,
|
||||||
|
SetChangedStringV2Flag = 0xD,
|
||||||
|
SetMovedCursorV2Flag = 0xE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SwkbdReplyType : u32 {
|
||||||
|
FinishedInitialize = 0x0,
|
||||||
|
Default = 0x1,
|
||||||
|
ChangedString = 0x2,
|
||||||
|
MovedCursor = 0x3,
|
||||||
|
MovedTab = 0x4,
|
||||||
|
DecidedEnter = 0x5,
|
||||||
|
DecidedCancel = 0x6,
|
||||||
|
ChangedStringUtf8 = 0x7,
|
||||||
|
MovedCursorUtf8 = 0x8,
|
||||||
|
DecidedEnterUtf8 = 0x9,
|
||||||
|
UnsetCustomizeDic = 0xA,
|
||||||
|
ReleasedUserWordInfo = 0xB,
|
||||||
|
UnsetCustomizedDictionaries = 0xC,
|
||||||
|
ChangedStringV2 = 0xD,
|
||||||
|
MovedCursorV2 = 0xE,
|
||||||
|
ChangedStringUtf8V2 = 0xF,
|
||||||
|
MovedCursorUtf8V2 = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SwkbdKeyDisableFlags {
|
||||||
|
union {
|
||||||
|
u32 raw{};
|
||||||
|
|
||||||
|
BitField<1, 1, u32> space;
|
||||||
|
BitField<2, 1, u32> at;
|
||||||
|
BitField<3, 1, u32> percent;
|
||||||
|
BitField<4, 1, u32> slash;
|
||||||
|
BitField<5, 1, u32> backslash;
|
||||||
|
BitField<6, 1, u32> numbers;
|
||||||
|
BitField<7, 1, u32> download_code;
|
||||||
|
BitField<8, 1, u32> username;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdKeyDisableFlags) == 0x4, "SwkbdKeyDisableFlags has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdConfigCommon {
|
||||||
|
SwkbdType type{};
|
||||||
|
std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
|
||||||
|
char16_t left_optional_symbol_key{};
|
||||||
|
char16_t right_optional_symbol_key{};
|
||||||
|
bool use_prediction{};
|
||||||
|
INSERT_PADDING_BYTES(1);
|
||||||
|
SwkbdKeyDisableFlags key_disable_flags{};
|
||||||
|
SwkbdInitialCursorPosition initial_cursor_position{};
|
||||||
|
std::array<char16_t, MAX_HEADER_TEXT_LENGTH + 1> header_text{};
|
||||||
|
std::array<char16_t, MAX_SUB_TEXT_LENGTH + 1> sub_text{};
|
||||||
|
std::array<char16_t, MAX_GUIDE_TEXT_LENGTH + 1> guide_text{};
|
||||||
|
u32 max_text_length{};
|
||||||
|
u32 min_text_length{};
|
||||||
|
SwkbdPasswordMode password_mode{};
|
||||||
|
SwkbdTextDrawType text_draw_type{};
|
||||||
|
bool enable_return_button{};
|
||||||
|
bool use_utf8{};
|
||||||
|
bool use_blur_background{};
|
||||||
|
INSERT_PADDING_BYTES(1);
|
||||||
|
u32 initial_string_offset{};
|
||||||
|
u32 initial_string_length{};
|
||||||
|
u32 user_dictionary_offset{};
|
||||||
|
u32 user_dictionary_entries{};
|
||||||
|
bool use_text_check{};
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdConfigCommon) == 0x3D4, "SwkbdConfigCommon has incorrect size.");
|
||||||
|
|
||||||
|
#pragma pack(push, 4)
|
||||||
|
// SwkbdAppletVersion 0x5, 0x10006
|
||||||
|
struct SwkbdConfigOld {
|
||||||
|
INSERT_PADDING_WORDS(1);
|
||||||
|
VAddr text_check_callback{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdConfigOld) == 0x3E0 - sizeof(SwkbdConfigCommon),
|
||||||
|
"SwkbdConfigOld has incorrect size.");
|
||||||
|
|
||||||
|
// SwkbdAppletVersion 0x30007, 0x40008, 0x50009
|
||||||
|
struct SwkbdConfigOld2 {
|
||||||
|
INSERT_PADDING_WORDS(1);
|
||||||
|
VAddr text_check_callback{};
|
||||||
|
std::array<u32, 8> text_grouping{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdConfigOld2) == 0x400 - sizeof(SwkbdConfigCommon),
|
||||||
|
"SwkbdConfigOld2 has incorrect size.");
|
||||||
|
|
||||||
|
// SwkbdAppletVersion 0x6000B, 0x8000D
|
||||||
|
struct SwkbdConfigNew {
|
||||||
|
std::array<u32, 8> text_grouping{};
|
||||||
|
std::array<u64, 24> customized_dictionary_set_entries{};
|
||||||
|
u8 total_customized_dictionary_set_entries{};
|
||||||
|
bool disable_cancel_button{};
|
||||||
|
INSERT_PADDING_BYTES(18);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdConfigNew) == 0x4C8 - sizeof(SwkbdConfigCommon),
|
||||||
|
"SwkbdConfigNew has incorrect size.");
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct SwkbdTextCheck {
|
||||||
|
SwkbdTextCheckResult text_check_result{};
|
||||||
|
std::array<char16_t, STRING_BUFFER_SIZE / 2> text_check_message{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdTextCheck) == 0x7D8, "SwkbdTextCheck has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdCalcArgFlags {
|
||||||
|
union {
|
||||||
|
u64 raw{};
|
||||||
|
|
||||||
|
BitField<0, 1, u64> set_initialize_arg;
|
||||||
|
BitField<1, 1, u64> set_volume;
|
||||||
|
BitField<2, 1, u64> appear;
|
||||||
|
BitField<3, 1, u64> set_input_text;
|
||||||
|
BitField<4, 1, u64> set_cursor_position;
|
||||||
|
BitField<5, 1, u64> set_utf8_mode;
|
||||||
|
BitField<6, 1, u64> unset_customize_dic;
|
||||||
|
BitField<7, 1, u64> disappear;
|
||||||
|
BitField<8, 1, u64> unknown;
|
||||||
|
BitField<9, 1, u64> set_key_top_translate_scale;
|
||||||
|
BitField<10, 1, u64> unset_user_word_info;
|
||||||
|
BitField<11, 1, u64> set_disable_hardware_keyboard;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdCalcArgFlags) == 0x8, "SwkbdCalcArgFlags has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdInitializeArg {
|
||||||
|
u32 unknown{};
|
||||||
|
bool library_applet_mode_flag{};
|
||||||
|
bool is_above_hos_500{};
|
||||||
|
INSERT_PADDING_BYTES(2);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdAppearArg {
|
||||||
|
SwkbdType type{};
|
||||||
|
std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
|
||||||
|
char16_t left_optional_symbol_key{};
|
||||||
|
char16_t right_optional_symbol_key{};
|
||||||
|
bool use_prediction{};
|
||||||
|
bool disable_cancel_button{};
|
||||||
|
SwkbdKeyDisableFlags key_disable_flags{};
|
||||||
|
u32 max_text_length{};
|
||||||
|
u32 min_text_length{};
|
||||||
|
bool enable_return_button{};
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
u32 flags{};
|
||||||
|
INSERT_PADDING_WORDS(6);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdAppearArg) == 0x48, "SwkbdAppearArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdCalcArg {
|
||||||
|
u32 unknown{};
|
||||||
|
u16 calc_arg_size{};
|
||||||
|
INSERT_PADDING_BYTES(2);
|
||||||
|
SwkbdCalcArgFlags flags{};
|
||||||
|
SwkbdInitializeArg initialize_arg{};
|
||||||
|
f32 volume{};
|
||||||
|
s32 cursor_position{};
|
||||||
|
SwkbdAppearArg appear_arg{};
|
||||||
|
std::array<char16_t, 0x1FA> input_text{};
|
||||||
|
bool utf8_mode{};
|
||||||
|
INSERT_PADDING_BYTES(1);
|
||||||
|
bool enable_backspace_button{};
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
bool key_top_as_floating{};
|
||||||
|
bool footer_scalable{};
|
||||||
|
bool alpha_enabled_in_input_mode{};
|
||||||
|
u8 input_mode_fade_type{};
|
||||||
|
bool disable_touch{};
|
||||||
|
bool disable_hardware_keyboard{};
|
||||||
|
INSERT_PADDING_BYTES(8);
|
||||||
|
f32 key_top_scale_x{};
|
||||||
|
f32 key_top_scale_y{};
|
||||||
|
f32 key_top_translate_x{};
|
||||||
|
f32 key_top_translate_y{};
|
||||||
|
f32 key_top_bg_alpha{};
|
||||||
|
f32 footer_bg_alpha{};
|
||||||
|
f32 balloon_scale{};
|
||||||
|
INSERT_PADDING_WORDS(4);
|
||||||
|
u8 se_group{};
|
||||||
|
INSERT_PADDING_BYTES(3);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdCalcArg) == 0x4A0, "SwkbdCalcArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdChangedStringArg {
|
||||||
|
u32 text_length{};
|
||||||
|
s32 dictionary_start_cursor_position{};
|
||||||
|
s32 dictionary_end_cursor_position{};
|
||||||
|
s32 cursor_position{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdChangedStringArg) == 0x10, "SwkbdChangedStringArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdMovedCursorArg {
|
||||||
|
u32 text_length{};
|
||||||
|
s32 cursor_position{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdMovedCursorArg) == 0x8, "SwkbdMovedCursorArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdMovedTabArg {
|
||||||
|
u32 text_length{};
|
||||||
|
s32 cursor_position{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdMovedTabArg) == 0x8, "SwkbdMovedTabArg has incorrect size.");
|
||||||
|
|
||||||
|
struct SwkbdDecidedEnterArg {
|
||||||
|
u32 text_length{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwkbdDecidedEnterArg) == 0x4, "SwkbdDecidedEnterArg has incorrect size.");
|
||||||
|
|
||||||
|
} // namespace Service::AM::Applets
|
|
@ -208,8 +208,9 @@ void ExtractSharedFonts(Core::System& system) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_)
|
WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
: Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
|
const Core::Frontend::WebBrowserApplet& frontend_)
|
||||||
|
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend(frontend_), system{system_} {}
|
||||||
|
|
||||||
WebBrowser::~WebBrowser() = default;
|
WebBrowser::~WebBrowser() = default;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace Service::AM::Applets {
|
||||||
|
|
||||||
class WebBrowser final : public Applet {
|
class WebBrowser final : public Applet {
|
||||||
public:
|
public:
|
||||||
WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_);
|
WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
|
const Core::Frontend::WebBrowserApplet& frontend_);
|
||||||
|
|
||||||
~WebBrowser() override;
|
~WebBrowser() override;
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ private:
|
||||||
void ExecuteWifi();
|
void ExecuteWifi();
|
||||||
void ExecuteLobby();
|
void ExecuteLobby();
|
||||||
|
|
||||||
|
LibraryAppletMode applet_mode;
|
||||||
const Core::Frontend::WebBrowserApplet& frontend;
|
const Core::Frontend::WebBrowserApplet& frontend;
|
||||||
|
|
||||||
bool complete{false};
|
bool complete{false};
|
||||||
|
|
|
@ -18,6 +18,7 @@ add_executable(yuzu
|
||||||
applets/profile_select.h
|
applets/profile_select.h
|
||||||
applets/software_keyboard.cpp
|
applets/software_keyboard.cpp
|
||||||
applets/software_keyboard.h
|
applets/software_keyboard.h
|
||||||
|
applets/software_keyboard.ui
|
||||||
applets/web_browser.cpp
|
applets/web_browser.cpp
|
||||||
applets/web_browser.h
|
applets/web_browser.h
|
||||||
bootmanager.cpp
|
bootmanager.cpp
|
||||||
|
@ -143,6 +144,9 @@ add_executable(yuzu
|
||||||
uisettings.h
|
uisettings.h
|
||||||
util/limitable_input_dialog.cpp
|
util/limitable_input_dialog.cpp
|
||||||
util/limitable_input_dialog.h
|
util/limitable_input_dialog.h
|
||||||
|
util/overlay_dialog.cpp
|
||||||
|
util/overlay_dialog.h
|
||||||
|
util/overlay_dialog.ui
|
||||||
util/sequence_dialog/sequence_dialog.cpp
|
util/sequence_dialog/sequence_dialog.cpp
|
||||||
util/sequence_dialog/sequence_dialog.h
|
util/sequence_dialog/sequence_dialog.h
|
||||||
util/url_request_interceptor.cpp
|
util/url_request_interceptor.cpp
|
||||||
|
|
|
@ -19,11 +19,11 @@ QtErrorDisplay::~QtErrorDisplay() = default;
|
||||||
void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const {
|
void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const {
|
||||||
callback = std::move(finished);
|
callback = std::move(finished);
|
||||||
emit MainWindowDisplayError(
|
emit MainWindowDisplayError(
|
||||||
tr("An error has occurred.\nPlease try again or contact the developer of the "
|
tr("Error Code: %1-%2 (0x%3)")
|
||||||
"software.\n\nError Code: %1-%2 (0x%3)")
|
|
||||||
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.raw, 8, 16, QChar::fromLatin1('0')));
|
.arg(error.raw, 8, 16, QChar::fromLatin1('0')),
|
||||||
|
tr("An error has occurred.\nPlease try again or contact the developer of the software."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
|
void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
|
||||||
|
@ -32,13 +32,14 @@ void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::secon
|
||||||
|
|
||||||
const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
|
const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
|
||||||
emit MainWindowDisplayError(
|
emit MainWindowDisplayError(
|
||||||
tr("An error occurred on %1 at %2.\nPlease try again or contact the "
|
tr("Error Code: %1-%2 (0x%3)")
|
||||||
"developer of the software.\n\nError Code: %3-%4 (0x%5)")
|
|
||||||
.arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
|
|
||||||
.arg(date_time.toString(QStringLiteral("h:mm:ss A")))
|
|
||||||
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.raw, 8, 16, QChar::fromLatin1('0')));
|
.arg(error.raw, 8, 16, QChar::fromLatin1('0')),
|
||||||
|
tr("An error occurred on %1 at %2.\nPlease try again or contact the developer of the "
|
||||||
|
"software.")
|
||||||
|
.arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
|
||||||
|
.arg(date_time.toString(QStringLiteral("h:mm:ss A"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text,
|
void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text,
|
||||||
|
@ -46,10 +47,11 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te
|
||||||
std::function<void()> finished) const {
|
std::function<void()> finished) const {
|
||||||
callback = std::move(finished);
|
callback = std::move(finished);
|
||||||
emit MainWindowDisplayError(
|
emit MainWindowDisplayError(
|
||||||
tr("An error has occurred.\nError Code: %1-%2 (0x%3)\n\n%4\n\n%5")
|
tr("Error Code: %1-%2 (0x%3)")
|
||||||
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
|
||||||
.arg(error.raw, 8, 16, QChar::fromLatin1('0'))
|
.arg(error.raw, 8, 16, QChar::fromLatin1('0')),
|
||||||
|
tr("An error has occurred.\n\n%1\n\n%2")
|
||||||
.arg(QString::fromStdString(dialog_text))
|
.arg(QString::fromStdString(dialog_text))
|
||||||
.arg(QString::fromStdString(fullscreen_text)));
|
.arg(QString::fromStdString(fullscreen_text)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
std::function<void()> finished) const override;
|
std::function<void()> finished) const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void MainWindowDisplayError(QString error) const;
|
void MainWindowDisplayError(QString error_code, QString error_text) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MainWindowFinishedError();
|
void MainWindowFinishedError();
|
||||||
|
|
|
@ -1,54 +1,228 @@
|
||||||
// Copyright 2018 yuzu Emulator Project
|
// Copyright 2021 yuzu Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QValidator>
|
#include <QValidator>
|
||||||
|
|
||||||
#include "core/frontend/applets/software_keyboard.h"
|
#include "core/frontend/applets/software_keyboard.h"
|
||||||
|
|
||||||
|
enum class HIDButton : u8;
|
||||||
|
|
||||||
|
class InputInterpreter;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class QtSoftwareKeyboardDialog;
|
||||||
|
}
|
||||||
|
|
||||||
class GMainWindow;
|
class GMainWindow;
|
||||||
class QDialogButtonBox;
|
|
||||||
class QLabel;
|
|
||||||
class QLineEdit;
|
|
||||||
class QVBoxLayout;
|
|
||||||
class QtSoftwareKeyboard;
|
|
||||||
|
|
||||||
class QtSoftwareKeyboardValidator final : public QValidator {
|
|
||||||
public:
|
|
||||||
explicit QtSoftwareKeyboardValidator(Core::Frontend::SoftwareKeyboardParameters parameters);
|
|
||||||
State validate(QString& input, int& pos) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Core::Frontend::SoftwareKeyboardParameters parameters;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QtSoftwareKeyboardDialog final : public QDialog {
|
class QtSoftwareKeyboardDialog final : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QtSoftwareKeyboardDialog(QWidget* parent,
|
QtSoftwareKeyboardDialog(QWidget* parent, Core::System& system_, bool is_inline_,
|
||||||
Core::Frontend::SoftwareKeyboardParameters parameters);
|
Core::Frontend::KeyboardInitializeParameters initialize_parameters_);
|
||||||
~QtSoftwareKeyboardDialog() override;
|
~QtSoftwareKeyboardDialog() override;
|
||||||
|
|
||||||
void accept() override;
|
void ShowNormalKeyboard(QPoint pos, QSize size);
|
||||||
|
|
||||||
|
void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message);
|
||||||
|
|
||||||
|
void ShowInlineKeyboard(Core::Frontend::InlineAppearParameters appear_parameters, QPoint pos,
|
||||||
|
QSize size);
|
||||||
|
|
||||||
|
void HideInlineKeyboard();
|
||||||
|
|
||||||
|
void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters);
|
||||||
|
|
||||||
|
void ExitKeyboard();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void SubmitNormalText(Service::AM::Applets::SwkbdResult result,
|
||||||
|
std::u16string submitted_text) const;
|
||||||
|
|
||||||
|
void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
|
||||||
|
std::u16string submitted_text, s32 cursor_position) const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void open() override;
|
||||||
void reject() override;
|
void reject() override;
|
||||||
|
|
||||||
std::u16string GetText() const;
|
protected:
|
||||||
|
/// We override the keyPressEvent for inputting text into the inline software keyboard.
|
||||||
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::u16string text;
|
enum class Direction {
|
||||||
|
Left,
|
||||||
|
Up,
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
};
|
||||||
|
|
||||||
QDialogButtonBox* buttons;
|
enum class BottomOSKIndex {
|
||||||
QLabel* header_label;
|
LowerCase,
|
||||||
QLabel* sub_label;
|
UpperCase,
|
||||||
QLabel* guide_label;
|
NumberPad,
|
||||||
QLabel* length_label;
|
};
|
||||||
QLineEdit* line_edit;
|
|
||||||
QVBoxLayout* layout;
|
|
||||||
|
|
||||||
Core::Frontend::SoftwareKeyboardParameters parameters;
|
/**
|
||||||
|
* Moves and resizes the window to a specified position and size.
|
||||||
|
*
|
||||||
|
* @param pos Top-left window position
|
||||||
|
* @param size Window size
|
||||||
|
*/
|
||||||
|
void MoveAndResizeWindow(QPoint pos, QSize size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rescales all keyboard elements to account for High DPI displays.
|
||||||
|
*
|
||||||
|
* @param width Window width
|
||||||
|
* @param height Window height
|
||||||
|
* @param dpi_scale Display scaling factor
|
||||||
|
*/
|
||||||
|
void RescaleKeyboardElements(float width, float height, float dpi_scale);
|
||||||
|
|
||||||
|
/// Sets the keyboard type based on initialize_parameters.
|
||||||
|
void SetKeyboardType();
|
||||||
|
|
||||||
|
/// Sets the password mode based on initialize_parameters.
|
||||||
|
void SetPasswordMode();
|
||||||
|
|
||||||
|
/// Sets the text draw type based on initialize_parameters.
|
||||||
|
void SetTextDrawType();
|
||||||
|
|
||||||
|
/// Sets the controller image at the bottom left of the software keyboard.
|
||||||
|
void SetControllerImage();
|
||||||
|
|
||||||
|
/// Disables buttons based on initialize_parameters.
|
||||||
|
void DisableKeyboardButtons();
|
||||||
|
|
||||||
|
/// Changes whether the backspace or/and ok buttons should be enabled or disabled.
|
||||||
|
void SetBackspaceOkEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the input text sent in based on the parameters in initialize_parameters.
|
||||||
|
*
|
||||||
|
* @param input_text Input text
|
||||||
|
*
|
||||||
|
* @returns True if the input text is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
bool ValidateInputText(const QString& input_text);
|
||||||
|
|
||||||
|
/// Switches between LowerCase and UpperCase (Shift and Caps Lock)
|
||||||
|
void ChangeBottomOSKIndex();
|
||||||
|
|
||||||
|
/// Processes a keyboard button click from the UI as normal keyboard input.
|
||||||
|
void NormalKeyboardButtonClicked(QPushButton* button);
|
||||||
|
|
||||||
|
/// Processes a keyboard button click from the UI as inline keyboard input.
|
||||||
|
void InlineKeyboardButtonClicked(QPushButton* button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a string of arbitrary length into the current_text at the current cursor position.
|
||||||
|
* This is only used for the inline software keyboard.
|
||||||
|
*/
|
||||||
|
void InlineTextInsertString(std::u16string_view string);
|
||||||
|
|
||||||
|
/// Setup the mouse hover workaround for "focusing" buttons. This should only be called once.
|
||||||
|
void SetupMouseHover();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles button presses and converts them into keyboard input.
|
||||||
|
*
|
||||||
|
* @tparam HIDButton The list of buttons that can be converted into keyboard input.
|
||||||
|
*/
|
||||||
|
template <HIDButton... T>
|
||||||
|
void HandleButtonPressedOnce();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles button holds and converts them into keyboard input.
|
||||||
|
*
|
||||||
|
* @tparam HIDButton The list of buttons that can be converted into keyboard input.
|
||||||
|
*/
|
||||||
|
template <HIDButton... T>
|
||||||
|
void HandleButtonHold();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates a button press to focus or click a keyboard button.
|
||||||
|
*
|
||||||
|
* @param button The button press to process.
|
||||||
|
*/
|
||||||
|
void TranslateButtonPress(HIDButton button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the focus of a button in a certain direction.
|
||||||
|
*
|
||||||
|
* @param direction The direction to move.
|
||||||
|
*/
|
||||||
|
void MoveButtonDirection(Direction direction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the text cursor in a certain direction.
|
||||||
|
*
|
||||||
|
* @param direction The direction to move.
|
||||||
|
*/
|
||||||
|
void MoveTextCursorDirection(Direction direction);
|
||||||
|
|
||||||
|
void StartInputThread();
|
||||||
|
void StopInputThread();
|
||||||
|
|
||||||
|
/// The thread where input is being polled and processed.
|
||||||
|
void InputThread();
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::QtSoftwareKeyboardDialog> ui;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
|
|
||||||
|
// True if it is the inline software keyboard.
|
||||||
|
bool is_inline;
|
||||||
|
|
||||||
|
// Common software keyboard initialize parameters.
|
||||||
|
Core::Frontend::KeyboardInitializeParameters initialize_parameters;
|
||||||
|
|
||||||
|
// Used only by the inline software keyboard since the QLineEdit or QTextEdit is hidden.
|
||||||
|
std::u16string current_text;
|
||||||
|
s32 cursor_position{0};
|
||||||
|
|
||||||
|
static constexpr std::size_t NUM_ROWS_NORMAL = 5;
|
||||||
|
static constexpr std::size_t NUM_COLUMNS_NORMAL = 12;
|
||||||
|
static constexpr std::size_t NUM_ROWS_NUMPAD = 4;
|
||||||
|
static constexpr std::size_t NUM_COLUMNS_NUMPAD = 4;
|
||||||
|
|
||||||
|
// Stores the normal keyboard layout.
|
||||||
|
std::array<std::array<std::array<QPushButton*, NUM_COLUMNS_NORMAL>, NUM_ROWS_NORMAL>, 2>
|
||||||
|
keyboard_buttons;
|
||||||
|
// Stores the numberpad keyboard layout.
|
||||||
|
std::array<std::array<QPushButton*, NUM_COLUMNS_NUMPAD>, NUM_ROWS_NUMPAD> numberpad_buttons;
|
||||||
|
|
||||||
|
// Contains a set of all buttons used in keyboard_buttons and numberpad_buttons.
|
||||||
|
std::array<QPushButton*, 110> all_buttons;
|
||||||
|
|
||||||
|
std::size_t row{0};
|
||||||
|
std::size_t column{0};
|
||||||
|
|
||||||
|
BottomOSKIndex bottom_osk_index{BottomOSKIndex::LowerCase};
|
||||||
|
std::atomic<bool> caps_lock_enabled{false};
|
||||||
|
|
||||||
|
std::unique_ptr<InputInterpreter> input_interpreter;
|
||||||
|
|
||||||
|
std::thread input_thread;
|
||||||
|
|
||||||
|
std::atomic<bool> input_thread_running{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet {
|
class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet {
|
||||||
|
@ -58,19 +232,54 @@ public:
|
||||||
explicit QtSoftwareKeyboard(GMainWindow& parent);
|
explicit QtSoftwareKeyboard(GMainWindow& parent);
|
||||||
~QtSoftwareKeyboard() override;
|
~QtSoftwareKeyboard() override;
|
||||||
|
|
||||||
void RequestText(std::function<void(std::optional<std::u16string>)> out,
|
void InitializeKeyboard(
|
||||||
Core::Frontend::SoftwareKeyboardParameters parameters) const override;
|
bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
|
||||||
void SendTextCheckDialog(std::u16string error_message,
|
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
|
||||||
std::function<void()> finished_check_) const override;
|
submit_normal_callback_,
|
||||||
|
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback_) override;
|
||||||
|
|
||||||
|
void ShowNormalKeyboard() const override;
|
||||||
|
|
||||||
|
void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) const override;
|
||||||
|
|
||||||
|
void ShowInlineKeyboard(
|
||||||
|
Core::Frontend::InlineAppearParameters appear_parameters) const override;
|
||||||
|
|
||||||
|
void HideInlineKeyboard() const override;
|
||||||
|
|
||||||
|
void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const override;
|
||||||
|
|
||||||
|
void ExitKeyboard() const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void MainWindowGetText(Core::Frontend::SoftwareKeyboardParameters parameters) const;
|
void MainWindowInitializeKeyboard(
|
||||||
void MainWindowTextCheckDialog(std::u16string error_message) const;
|
bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) const;
|
||||||
|
|
||||||
|
void MainWindowShowNormalKeyboard() const;
|
||||||
|
|
||||||
|
void MainWindowShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) const;
|
||||||
|
|
||||||
|
void MainWindowShowInlineKeyboard(
|
||||||
|
Core::Frontend::InlineAppearParameters appear_parameters) const;
|
||||||
|
|
||||||
|
void MainWindowHideInlineKeyboard() const;
|
||||||
|
|
||||||
|
void MainWindowInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const;
|
||||||
|
|
||||||
|
void MainWindowExitKeyboard() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MainWindowFinishedText(std::optional<std::u16string> text);
|
void SubmitNormalText(Service::AM::Applets::SwkbdResult result,
|
||||||
void MainWindowFinishedCheckDialog();
|
std::u16string submitted_text) const;
|
||||||
|
|
||||||
mutable std::function<void(std::optional<std::u16string>)> text_output;
|
void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
|
||||||
mutable std::function<void()> finished_check;
|
std::u16string submitted_text, s32 cursor_position) const;
|
||||||
|
|
||||||
|
mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
|
||||||
|
submit_normal_callback;
|
||||||
|
mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
|
||||||
|
submit_inline_callback;
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,6 +101,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
|
#include "util/overlay_dialog.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
#include "video_core/shader_notify.h"
|
#include "video_core/shader_notify.h"
|
||||||
#include "yuzu/about_dialog.h"
|
#include "yuzu/about_dialog.h"
|
||||||
|
@ -227,6 +228,8 @@ GMainWindow::GMainWindow()
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
discord_rpc->Update();
|
discord_rpc->Update();
|
||||||
|
|
||||||
|
RegisterMetaTypes();
|
||||||
|
|
||||||
InitializeWidgets();
|
InitializeWidgets();
|
||||||
InitializeDebugWidgets();
|
InitializeDebugWidgets();
|
||||||
InitializeRecentFileMenuActions();
|
InitializeRecentFileMenuActions();
|
||||||
|
@ -375,6 +378,55 @@ GMainWindow::~GMainWindow() {
|
||||||
delete render_window;
|
delete render_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::RegisterMetaTypes() {
|
||||||
|
// Register integral and floating point types
|
||||||
|
qRegisterMetaType<u8>("u8");
|
||||||
|
qRegisterMetaType<u16>("u16");
|
||||||
|
qRegisterMetaType<u32>("u32");
|
||||||
|
qRegisterMetaType<u64>("u64");
|
||||||
|
qRegisterMetaType<u128>("u128");
|
||||||
|
qRegisterMetaType<s8>("s8");
|
||||||
|
qRegisterMetaType<s16>("s16");
|
||||||
|
qRegisterMetaType<s32>("s32");
|
||||||
|
qRegisterMetaType<s64>("s64");
|
||||||
|
qRegisterMetaType<f32>("f32");
|
||||||
|
qRegisterMetaType<f64>("f64");
|
||||||
|
|
||||||
|
// Register string types
|
||||||
|
qRegisterMetaType<std::string>("std::string");
|
||||||
|
qRegisterMetaType<std::wstring>("std::wstring");
|
||||||
|
qRegisterMetaType<std::u8string>("std::u8string");
|
||||||
|
qRegisterMetaType<std::u16string>("std::u16string");
|
||||||
|
qRegisterMetaType<std::u32string>("std::u32string");
|
||||||
|
qRegisterMetaType<std::string_view>("std::string_view");
|
||||||
|
qRegisterMetaType<std::wstring_view>("std::wstring_view");
|
||||||
|
qRegisterMetaType<std::u8string_view>("std::u8string_view");
|
||||||
|
qRegisterMetaType<std::u16string_view>("std::u16string_view");
|
||||||
|
qRegisterMetaType<std::u32string_view>("std::u32string_view");
|
||||||
|
|
||||||
|
// Register applet types
|
||||||
|
|
||||||
|
// Controller Applet
|
||||||
|
qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
|
||||||
|
|
||||||
|
// Software Keyboard Applet
|
||||||
|
qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
|
||||||
|
"Core::Frontend::KeyboardInitializeParameters");
|
||||||
|
qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
|
||||||
|
"Core::Frontend::InlineAppearParameters");
|
||||||
|
qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
|
||||||
|
qRegisterMetaType<Service::AM::Applets::SwkbdResult>("Service::AM::Applets::SwkbdResult");
|
||||||
|
qRegisterMetaType<Service::AM::Applets::SwkbdTextCheckResult>(
|
||||||
|
"Service::AM::Applets::SwkbdTextCheckResult");
|
||||||
|
qRegisterMetaType<Service::AM::Applets::SwkbdReplyType>("Service::AM::Applets::SwkbdReplyType");
|
||||||
|
|
||||||
|
// Web Browser Applet
|
||||||
|
qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
|
||||||
|
|
||||||
|
// Register loader types
|
||||||
|
qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::ControllerSelectorReconfigureControllers(
|
void GMainWindow::ControllerSelectorReconfigureControllers(
|
||||||
const Core::Frontend::ControllerParameters& parameters) {
|
const Core::Frontend::ControllerParameters& parameters) {
|
||||||
QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
|
QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
|
||||||
|
@ -414,25 +466,112 @@ void GMainWindow::ProfileSelectorSelectProfile() {
|
||||||
emit ProfileSelectorFinishedSelection(uuid);
|
emit ProfileSelectorFinishedSelection(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::SoftwareKeyboardGetText(
|
void GMainWindow::SoftwareKeyboardInitialize(
|
||||||
const Core::Frontend::SoftwareKeyboardParameters& parameters) {
|
bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) {
|
||||||
QtSoftwareKeyboardDialog dialog(this, parameters);
|
if (software_keyboard) {
|
||||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
|
LOG_ERROR(Frontend, "The software keyboard is already initialized!");
|
||||||
Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
|
|
||||||
Qt::WindowCloseButtonHint);
|
|
||||||
dialog.setWindowModality(Qt::WindowModal);
|
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Rejected) {
|
|
||||||
emit SoftwareKeyboardFinishedText(std::nullopt);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit SoftwareKeyboardFinishedText(dialog.GetText());
|
software_keyboard = new QtSoftwareKeyboardDialog(render_window, Core::System::GetInstance(),
|
||||||
|
is_inline, std::move(initialize_parameters));
|
||||||
|
|
||||||
|
if (is_inline) {
|
||||||
|
connect(
|
||||||
|
software_keyboard, &QtSoftwareKeyboardDialog::SubmitInlineText, this,
|
||||||
|
[this](Service::AM::Applets::SwkbdReplyType reply_type, std::u16string submitted_text,
|
||||||
|
s32 cursor_position) {
|
||||||
|
emit SoftwareKeyboardSubmitInlineText(reply_type, submitted_text, cursor_position);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
} else {
|
||||||
|
connect(
|
||||||
|
software_keyboard, &QtSoftwareKeyboardDialog::SubmitNormalText, this,
|
||||||
|
[this](Service::AM::Applets::SwkbdResult result, std::u16string submitted_text) {
|
||||||
|
emit SoftwareKeyboardSubmitNormalText(result, submitted_text);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) {
|
void GMainWindow::SoftwareKeyboardShowNormal() {
|
||||||
QMessageBox::warning(this, tr("Text Check Failed"), QString::fromStdU16String(error_message));
|
if (!software_keyboard) {
|
||||||
emit SoftwareKeyboardFinishedCheckDialog();
|
LOG_ERROR(Frontend, "The software keyboard is not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& layout = render_window->GetFramebufferLayout();
|
||||||
|
|
||||||
|
const auto x = layout.screen.left;
|
||||||
|
const auto y = layout.screen.top;
|
||||||
|
const auto w = layout.screen.GetWidth();
|
||||||
|
const auto h = layout.screen.GetHeight();
|
||||||
|
|
||||||
|
software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SoftwareKeyboardShowTextCheck(
|
||||||
|
Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message) {
|
||||||
|
if (!software_keyboard) {
|
||||||
|
LOG_ERROR(Frontend, "The software keyboard is not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
software_keyboard->ShowTextCheckDialog(text_check_result, text_check_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SoftwareKeyboardShowInline(
|
||||||
|
Core::Frontend::InlineAppearParameters appear_parameters) {
|
||||||
|
if (!software_keyboard) {
|
||||||
|
LOG_ERROR(Frontend, "The software keyboard is not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& layout = render_window->GetFramebufferLayout();
|
||||||
|
|
||||||
|
const auto x =
|
||||||
|
static_cast<int>(layout.screen.left + (0.5f * layout.screen.GetWidth() *
|
||||||
|
((2.0f * appear_parameters.key_top_translate_x) +
|
||||||
|
(1.0f - appear_parameters.key_top_scale_x))));
|
||||||
|
const auto y =
|
||||||
|
static_cast<int>(layout.screen.top + (layout.screen.GetHeight() *
|
||||||
|
((2.0f * appear_parameters.key_top_translate_y) +
|
||||||
|
(1.0f - appear_parameters.key_top_scale_y))));
|
||||||
|
const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
|
||||||
|
const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
|
||||||
|
|
||||||
|
software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
|
||||||
|
render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SoftwareKeyboardHideInline() {
|
||||||
|
if (!software_keyboard) {
|
||||||
|
LOG_ERROR(Frontend, "The software keyboard is not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
software_keyboard->HideInlineKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SoftwareKeyboardInlineTextChanged(
|
||||||
|
Core::Frontend::InlineTextParameters text_parameters) {
|
||||||
|
if (!software_keyboard) {
|
||||||
|
LOG_ERROR(Frontend, "The software keyboard is not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
software_keyboard->InlineTextChanged(std::move(text_parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SoftwareKeyboardExit() {
|
||||||
|
if (!software_keyboard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
software_keyboard->ExitKeyboard();
|
||||||
|
|
||||||
|
software_keyboard = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
|
void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
|
||||||
|
@ -978,6 +1117,10 @@ void GMainWindow::ConnectWidgetEvents() {
|
||||||
connect(this, &GMainWindow::EmulationStopping, render_window,
|
connect(this, &GMainWindow::EmulationStopping, render_window,
|
||||||
&GRenderWindow::OnEmulationStopping);
|
&GRenderWindow::OnEmulationStopping);
|
||||||
|
|
||||||
|
// Software Keyboard Applet
|
||||||
|
connect(this, &GMainWindow::EmulationStarting, this, &GMainWindow::SoftwareKeyboardExit);
|
||||||
|
connect(this, &GMainWindow::EmulationStopping, this, &GMainWindow::SoftwareKeyboardExit);
|
||||||
|
|
||||||
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
|
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2187,15 +2330,6 @@ void GMainWindow::OnStartGame() {
|
||||||
|
|
||||||
emu_thread->SetRunning(true);
|
emu_thread->SetRunning(true);
|
||||||
|
|
||||||
qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
|
|
||||||
qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
|
|
||||||
"Core::Frontend::SoftwareKeyboardParameters");
|
|
||||||
qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
|
|
||||||
qRegisterMetaType<std::string>("std::string");
|
|
||||||
qRegisterMetaType<std::optional<std::u16string>>("std::optional<std::u16string>");
|
|
||||||
qRegisterMetaType<std::string_view>("std::string_view");
|
|
||||||
qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
|
|
||||||
|
|
||||||
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
|
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
|
||||||
|
|
||||||
ui.action_Start->setEnabled(false);
|
ui.action_Start->setEnabled(false);
|
||||||
|
@ -2244,8 +2378,11 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) {
|
||||||
BootGame(last_filename_booted, program_index);
|
BootGame(last_filename_booted, program_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ErrorDisplayDisplayError(QString body) {
|
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
|
||||||
QMessageBox::critical(this, tr("Error Display"), body);
|
OverlayDialog dialog(render_window, Core::System::GetInstance(), error_code, error_text,
|
||||||
|
QString{}, tr("OK"), Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
dialog.exec();
|
||||||
|
|
||||||
emit ErrorDisplayFinished();
|
emit ErrorDisplayFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,13 @@ enum class GameListRemoveTarget;
|
||||||
enum class InstalledEntryType;
|
enum class InstalledEntryType;
|
||||||
class GameListPlaceholder;
|
class GameListPlaceholder;
|
||||||
|
|
||||||
|
class QtSoftwareKeyboardDialog;
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
struct ControllerParameters;
|
struct ControllerParameters;
|
||||||
struct SoftwareKeyboardParameters;
|
struct InlineAppearParameters;
|
||||||
|
struct InlineTextParameters;
|
||||||
|
struct KeyboardInitializeParameters;
|
||||||
} // namespace Core::Frontend
|
} // namespace Core::Frontend
|
||||||
|
|
||||||
namespace DiscordRPC {
|
namespace DiscordRPC {
|
||||||
|
@ -57,8 +61,11 @@ class InputSubsystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service::AM::Applets {
|
namespace Service::AM::Applets {
|
||||||
|
enum class SwkbdResult : u32;
|
||||||
|
enum class SwkbdTextCheckResult : u32;
|
||||||
|
enum class SwkbdReplyType : u32;
|
||||||
enum class WebExitReason : u32;
|
enum class WebExitReason : u32;
|
||||||
}
|
} // namespace Service::AM::Applets
|
||||||
|
|
||||||
enum class EmulatedDirectoryTarget {
|
enum class EmulatedDirectoryTarget {
|
||||||
NAND,
|
NAND,
|
||||||
|
@ -128,8 +135,10 @@ signals:
|
||||||
|
|
||||||
void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid);
|
void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid);
|
||||||
|
|
||||||
void SoftwareKeyboardFinishedText(std::optional<std::u16string> text);
|
void SoftwareKeyboardSubmitNormalText(Service::AM::Applets::SwkbdResult result,
|
||||||
void SoftwareKeyboardFinishedCheckDialog();
|
std::u16string submitted_text);
|
||||||
|
void SoftwareKeyboardSubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
|
||||||
|
std::u16string submitted_text, s32 cursor_position);
|
||||||
|
|
||||||
void WebBrowserExtractOfflineRomFS();
|
void WebBrowserExtractOfflineRomFS();
|
||||||
void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url);
|
void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url);
|
||||||
|
@ -139,15 +148,24 @@ public slots:
|
||||||
void OnExecuteProgram(std::size_t program_index);
|
void OnExecuteProgram(std::size_t program_index);
|
||||||
void ControllerSelectorReconfigureControllers(
|
void ControllerSelectorReconfigureControllers(
|
||||||
const Core::Frontend::ControllerParameters& parameters);
|
const Core::Frontend::ControllerParameters& parameters);
|
||||||
void ErrorDisplayDisplayError(QString body);
|
void SoftwareKeyboardInitialize(
|
||||||
|
bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters);
|
||||||
|
void SoftwareKeyboardShowNormal();
|
||||||
|
void SoftwareKeyboardShowTextCheck(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
|
||||||
|
std::u16string text_check_message);
|
||||||
|
void SoftwareKeyboardShowInline(Core::Frontend::InlineAppearParameters appear_parameters);
|
||||||
|
void SoftwareKeyboardHideInline();
|
||||||
|
void SoftwareKeyboardInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters);
|
||||||
|
void SoftwareKeyboardExit();
|
||||||
|
void ErrorDisplayDisplayError(QString error_code, QString error_text);
|
||||||
void ProfileSelectorSelectProfile();
|
void ProfileSelectorSelectProfile();
|
||||||
void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters);
|
|
||||||
void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
|
|
||||||
void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
|
void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
|
||||||
bool is_local);
|
bool is_local);
|
||||||
void OnAppFocusStateChanged(Qt::ApplicationState state);
|
void OnAppFocusStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void RegisterMetaTypes();
|
||||||
|
|
||||||
void InitializeWidgets();
|
void InitializeWidgets();
|
||||||
void InitializeDebugWidgets();
|
void InitializeDebugWidgets();
|
||||||
void InitializeRecentFileMenuActions();
|
void InitializeRecentFileMenuActions();
|
||||||
|
@ -334,6 +352,9 @@ private:
|
||||||
// Disables the web applet for the rest of the emulated session
|
// Disables the web applet for the rest of the emulated session
|
||||||
bool disable_web_applet{};
|
bool disable_web_applet{};
|
||||||
|
|
||||||
|
// Applets
|
||||||
|
QtSoftwareKeyboardDialog* software_keyboard = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dropEvent(QDropEvent* event) override;
|
void dropEvent(QDropEvent* event) override;
|
||||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/frontend/input_interpreter.h"
|
||||||
|
#include "ui_overlay_dialog.h"
|
||||||
|
#include "yuzu/util/overlay_dialog.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr float BASE_TITLE_FONT_SIZE = 14.0f;
|
||||||
|
constexpr float BASE_FONT_SIZE = 18.0f;
|
||||||
|
constexpr float BASE_WIDTH = 1280.0f;
|
||||||
|
constexpr float BASE_HEIGHT = 720.0f;
|
||||||
|
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
|
OverlayDialog::OverlayDialog(QWidget* parent, Core::System& system, const QString& title_text,
|
||||||
|
const QString& body_text, const QString& left_button_text,
|
||||||
|
const QString& right_button_text, Qt::Alignment alignment,
|
||||||
|
bool use_rich_text_)
|
||||||
|
: QDialog(parent), ui{std::make_unique<Ui::OverlayDialog>()}, use_rich_text{use_rich_text_} {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowTitleHint |
|
||||||
|
Qt::WindowSystemMenuHint | Qt::CustomizeWindowHint);
|
||||||
|
setWindowModality(Qt::WindowModal);
|
||||||
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
|
||||||
|
if (use_rich_text) {
|
||||||
|
InitializeRichTextDialog(title_text, body_text, left_button_text, right_button_text,
|
||||||
|
alignment);
|
||||||
|
} else {
|
||||||
|
InitializeRegularTextDialog(title_text, body_text, left_button_text, right_button_text,
|
||||||
|
alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveAndResizeWindow();
|
||||||
|
|
||||||
|
// TODO (Morph): Remove this when InputInterpreter no longer relies on the HID backend
|
||||||
|
if (system.IsPoweredOn()) {
|
||||||
|
input_interpreter = std::make_unique<InputInterpreter>(system);
|
||||||
|
|
||||||
|
StartInputThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayDialog::~OverlayDialog() {
|
||||||
|
StopInputThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::InitializeRegularTextDialog(const QString& title_text, const QString& body_text,
|
||||||
|
const QString& left_button_text,
|
||||||
|
const QString& right_button_text,
|
||||||
|
Qt::Alignment alignment) {
|
||||||
|
ui->stackedDialog->setCurrentIndex(0);
|
||||||
|
|
||||||
|
ui->label_title->setText(title_text);
|
||||||
|
ui->label_dialog->setText(body_text);
|
||||||
|
ui->button_cancel->setText(left_button_text);
|
||||||
|
ui->button_ok_label->setText(right_button_text);
|
||||||
|
|
||||||
|
ui->label_dialog->setAlignment(alignment);
|
||||||
|
|
||||||
|
if (title_text.isEmpty()) {
|
||||||
|
ui->label_title->hide();
|
||||||
|
ui->verticalLayout_2->setStretch(0, 0);
|
||||||
|
ui->verticalLayout_2->setStretch(1, 219);
|
||||||
|
ui->verticalLayout_2->setStretch(2, 82);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_button_text.isEmpty()) {
|
||||||
|
ui->button_cancel->hide();
|
||||||
|
ui->button_cancel->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right_button_text.isEmpty()) {
|
||||||
|
ui->button_ok_label->hide();
|
||||||
|
ui->button_ok_label->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(
|
||||||
|
ui->button_cancel, &QPushButton::clicked, this,
|
||||||
|
[this](bool) {
|
||||||
|
StopInputThread();
|
||||||
|
QDialog::reject();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(
|
||||||
|
ui->button_ok_label, &QPushButton::clicked, this,
|
||||||
|
[this](bool) {
|
||||||
|
StopInputThread();
|
||||||
|
QDialog::accept();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::InitializeRichTextDialog(const QString& title_text, const QString& body_text,
|
||||||
|
const QString& left_button_text,
|
||||||
|
const QString& right_button_text,
|
||||||
|
Qt::Alignment alignment) {
|
||||||
|
ui->stackedDialog->setCurrentIndex(1);
|
||||||
|
|
||||||
|
ui->label_title_rich->setText(title_text);
|
||||||
|
ui->text_browser_dialog->setText(body_text);
|
||||||
|
ui->button_cancel_rich->setText(left_button_text);
|
||||||
|
ui->button_ok_rich->setText(right_button_text);
|
||||||
|
|
||||||
|
// TODO (Morph/Rei): Replace this with something that works better
|
||||||
|
ui->text_browser_dialog->setAlignment(alignment);
|
||||||
|
|
||||||
|
if (title_text.isEmpty()) {
|
||||||
|
ui->label_title_rich->hide();
|
||||||
|
ui->verticalLayout_3->setStretch(0, 0);
|
||||||
|
ui->verticalLayout_3->setStretch(1, 438);
|
||||||
|
ui->verticalLayout_3->setStretch(2, 82);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_button_text.isEmpty()) {
|
||||||
|
ui->button_cancel_rich->hide();
|
||||||
|
ui->button_cancel_rich->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right_button_text.isEmpty()) {
|
||||||
|
ui->button_ok_rich->hide();
|
||||||
|
ui->button_ok_rich->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(
|
||||||
|
ui->button_cancel_rich, &QPushButton::clicked, this,
|
||||||
|
[this](bool) {
|
||||||
|
StopInputThread();
|
||||||
|
QDialog::reject();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(
|
||||||
|
ui->button_ok_rich, &QPushButton::clicked, this,
|
||||||
|
[this](bool) {
|
||||||
|
StopInputThread();
|
||||||
|
QDialog::accept();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::MoveAndResizeWindow() {
|
||||||
|
const auto pos = parentWidget()->mapToGlobal(parentWidget()->rect().topLeft());
|
||||||
|
const auto width = static_cast<float>(parentWidget()->width());
|
||||||
|
const auto height = static_cast<float>(parentWidget()->height());
|
||||||
|
|
||||||
|
// High DPI
|
||||||
|
const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
|
||||||
|
|
||||||
|
const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
|
||||||
|
const auto body_text_font_size =
|
||||||
|
BASE_FONT_SIZE * (((width / BASE_WIDTH) + (height / BASE_HEIGHT)) / 2.0f) / dpi_scale;
|
||||||
|
const auto button_text_font_size = BASE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
|
||||||
|
|
||||||
|
QFont title_text_font(QStringLiteral("MS Shell Dlg 2"), title_text_font_size, QFont::Normal);
|
||||||
|
QFont body_text_font(QStringLiteral("MS Shell Dlg 2"), body_text_font_size, QFont::Normal);
|
||||||
|
QFont button_text_font(QStringLiteral("MS Shell Dlg 2"), button_text_font_size, QFont::Normal);
|
||||||
|
|
||||||
|
if (use_rich_text) {
|
||||||
|
ui->label_title_rich->setFont(title_text_font);
|
||||||
|
ui->text_browser_dialog->setFont(body_text_font);
|
||||||
|
ui->button_cancel_rich->setFont(button_text_font);
|
||||||
|
ui->button_ok_rich->setFont(button_text_font);
|
||||||
|
} else {
|
||||||
|
ui->label_title->setFont(title_text_font);
|
||||||
|
ui->label_dialog->setFont(body_text_font);
|
||||||
|
ui->button_cancel->setFont(button_text_font);
|
||||||
|
ui->button_ok_label->setFont(button_text_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog::move(pos);
|
||||||
|
QDialog::resize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <HIDButton... T>
|
||||||
|
void OverlayDialog::HandleButtonPressedOnce() {
|
||||||
|
const auto f = [this](HIDButton button) {
|
||||||
|
if (input_interpreter->IsButtonPressedOnce(button)) {
|
||||||
|
TranslateButtonPress(button);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(f(T), ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::TranslateButtonPress(HIDButton button) {
|
||||||
|
QPushButton* left_button = use_rich_text ? ui->button_cancel_rich : ui->button_cancel;
|
||||||
|
QPushButton* right_button = use_rich_text ? ui->button_ok_rich : ui->button_ok_label;
|
||||||
|
|
||||||
|
// TODO (Morph): Handle QTextBrowser text scrolling
|
||||||
|
// TODO (Morph): focusPrevious/NextChild() doesn't work well with the rich text dialog, fix it
|
||||||
|
|
||||||
|
switch (button) {
|
||||||
|
case HIDButton::A:
|
||||||
|
case HIDButton::B:
|
||||||
|
if (left_button->hasFocus()) {
|
||||||
|
left_button->click();
|
||||||
|
} else if (right_button->hasFocus()) {
|
||||||
|
right_button->click();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HIDButton::DLeft:
|
||||||
|
case HIDButton::LStickLeft:
|
||||||
|
focusPreviousChild();
|
||||||
|
break;
|
||||||
|
case HIDButton::DRight:
|
||||||
|
case HIDButton::LStickRight:
|
||||||
|
focusNextChild();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::StartInputThread() {
|
||||||
|
if (input_thread_running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_thread_running = true;
|
||||||
|
|
||||||
|
input_thread = std::thread(&OverlayDialog::InputThread, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::StopInputThread() {
|
||||||
|
input_thread_running = false;
|
||||||
|
|
||||||
|
if (input_thread.joinable()) {
|
||||||
|
input_thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDialog::InputThread() {
|
||||||
|
while (input_thread_running) {
|
||||||
|
input_interpreter->PollInput();
|
||||||
|
|
||||||
|
HandleButtonPressedOnce<HIDButton::A, HIDButton::B, HIDButton::DLeft, HIDButton::DRight,
|
||||||
|
HIDButton::LStickLeft, HIDButton::LStickRight>();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
enum class HIDButton : u8;
|
||||||
|
|
||||||
|
class InputInterpreter;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class OverlayDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OverlayDialog is an interactive dialog that accepts controller input (while a game is running)
|
||||||
|
* This dialog attempts to replicate the look and feel of the Nintendo Switch's overlay dialogs and
|
||||||
|
* provide some extra features such as embedding HTML/Rich Text content in a QTextBrowser.
|
||||||
|
* The OverlayDialog provides 2 modes: one to embed regular text into a QLabel and another to embed
|
||||||
|
* HTML/Rich Text content into a QTextBrowser.
|
||||||
|
*/
|
||||||
|
class OverlayDialog final : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OverlayDialog(QWidget* parent, Core::System& system, const QString& title_text,
|
||||||
|
const QString& body_text, const QString& left_button_text,
|
||||||
|
const QString& right_button_text,
|
||||||
|
Qt::Alignment alignment = Qt::AlignCenter, bool use_rich_text_ = false);
|
||||||
|
~OverlayDialog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Initializes a text dialog with a QLabel storing text.
|
||||||
|
* Only use this for short text as the dialog buttons would be squashed with longer text.
|
||||||
|
*
|
||||||
|
* @param title_text Title text to be displayed
|
||||||
|
* @param body_text Main text to be displayed
|
||||||
|
* @param left_button_text Left button text. If empty, the button is hidden and disabled
|
||||||
|
* @param right_button_text Right button text. If empty, the button is hidden and disabled
|
||||||
|
* @param alignment Main text alignment
|
||||||
|
*/
|
||||||
|
void InitializeRegularTextDialog(const QString& title_text, const QString& body_text,
|
||||||
|
const QString& left_button_text,
|
||||||
|
const QString& right_button_text, Qt::Alignment alignment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a text dialog with a QTextBrowser storing text.
|
||||||
|
* This is ideal for longer text or rich text content. A scrollbar is shown for longer text.
|
||||||
|
*
|
||||||
|
* @param title_text Title text to be displayed
|
||||||
|
* @param body_text Main text to be displayed
|
||||||
|
* @param left_button_text Left button text. If empty, the button is hidden and disabled
|
||||||
|
* @param right_button_text Right button text. If empty, the button is hidden and disabled
|
||||||
|
* @param alignment Main text alignment
|
||||||
|
*/
|
||||||
|
void InitializeRichTextDialog(const QString& title_text, const QString& body_text,
|
||||||
|
const QString& left_button_text, const QString& right_button_text,
|
||||||
|
Qt::Alignment alignment);
|
||||||
|
|
||||||
|
/// Moves and resizes the dialog to be fully overlayed on top of the parent window.
|
||||||
|
void MoveAndResizeWindow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles button presses and converts them into keyboard input.
|
||||||
|
*
|
||||||
|
* @tparam HIDButton The list of buttons that can be converted into keyboard input.
|
||||||
|
*/
|
||||||
|
template <HIDButton... T>
|
||||||
|
void HandleButtonPressedOnce();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates a button press to focus or click either the left or right buttons.
|
||||||
|
*
|
||||||
|
* @param button The button press to process.
|
||||||
|
*/
|
||||||
|
void TranslateButtonPress(HIDButton button);
|
||||||
|
|
||||||
|
void StartInputThread();
|
||||||
|
void StopInputThread();
|
||||||
|
|
||||||
|
/// The thread where input is being polled and processed.
|
||||||
|
void InputThread();
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::OverlayDialog> ui;
|
||||||
|
|
||||||
|
bool use_rich_text;
|
||||||
|
|
||||||
|
std::unique_ptr<InputInterpreter> input_interpreter;
|
||||||
|
|
||||||
|
std::thread input_thread;
|
||||||
|
|
||||||
|
std::atomic<bool> input_thread_running{};
|
||||||
|
};
|
|
@ -0,0 +1,404 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>OverlayDialog</class>
|
||||||
|
<widget class="QDialog" name="OverlayDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1280</width>
|
||||||
|
<height>720</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QStackedWidget" name="stackedDialog">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="lineDialog">
|
||||||
|
<layout class="QGridLayout" name="lineDialogGridLayout" rowstretch="210,300,210" columnstretch="250,780,250">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QWidget" name="contentDialog" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="70,149,82">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_title">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_dialog">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="buttonsDialog" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_cancel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_ok_label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>OK</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="richDialog">
|
||||||
|
<layout class="QGridLayout" name="richDialogGridLayout" rowstretch="100,520,100" columnstretch="165,950,165">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QWidget" name="contentRichDialog" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="70,368,82">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_title_rich">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="text_browser_dialog">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="html">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:18pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="buttonsRichDialog" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_cancel_rich">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_ok_rich">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>OK</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../../dist/icons/overlay/overlay.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|