mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	qt: Add UI to configure mouse buttons
Supports setting the five mouse buttons to any valid controller button/keyboard key (Left, Right, Middle, Foward, Back)
This commit is contained in:
		
							parent
							
								
									f1aec256d7
								
							
						
					
					
						commit
						2e1dd9c649
					
				| @ -27,6 +27,8 @@ add_executable(yuzu | ||||
|     configuration/configure_graphics.h | ||||
|     configuration/configure_input.cpp | ||||
|     configuration/configure_input.h | ||||
|     configuration/configure_mouse_advanced.cpp | ||||
|     configuration/configure_mouse_advanced.h | ||||
|     configuration/configure_system.cpp | ||||
|     configuration/configure_system.h | ||||
|     configuration/configure_web.cpp | ||||
| @ -76,6 +78,7 @@ set(UIS | ||||
|     configuration/configure_general.ui | ||||
|     configuration/configure_graphics.ui | ||||
|     configuration/configure_input.ui | ||||
|     configuration/configure_mouse_advanced.ui | ||||
|     configuration/configure_system.ui | ||||
|     configuration/configure_web.ui | ||||
|     hotkeys.ui | ||||
|  | ||||
							
								
								
									
										211
									
								
								src/yuzu/configuration/configure_mouse_advanced.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/yuzu/configuration/configure_mouse_advanced.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,211 @@ | ||||
| // Copyright 2016 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <algorithm> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| #include <QKeyEvent> | ||||
| #include <QMenu> | ||||
| #include <QMessageBox> | ||||
| #include <QTimer> | ||||
| #include "common/assert.h" | ||||
| #include "common/param_package.h" | ||||
| #include "input_common/main.h" | ||||
| #include "ui_configure_mouse_advanced.h" | ||||
| #include "yuzu/configuration/config.h" | ||||
| #include "yuzu/configuration/configure_mouse_advanced.h" | ||||
| 
 | ||||
| static QString getKeyName(int key_code) { | ||||
|     switch (key_code) { | ||||
|     case Qt::Key_Shift: | ||||
|         return QObject::tr("Shift"); | ||||
|     case Qt::Key_Control: | ||||
|         return QObject::tr("Ctrl"); | ||||
|     case Qt::Key_Alt: | ||||
|         return QObject::tr("Alt"); | ||||
|     case Qt::Key_Meta: | ||||
|         return ""; | ||||
|     default: | ||||
|         return QKeySequence(key_code).toString(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static QString ButtonToText(const Common::ParamPackage& param) { | ||||
|     if (!param.Has("engine")) { | ||||
|         return QObject::tr("[not set]"); | ||||
|     } else if (param.Get("engine", "") == "keyboard") { | ||||
|         return getKeyName(param.Get("code", 0)); | ||||
|     } else if (param.Get("engine", "") == "sdl") { | ||||
|         if (param.Has("hat")) { | ||||
|             return QString(QObject::tr("Hat %1 %2")) | ||||
|                 .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str()); | ||||
|         } | ||||
|         if (param.Has("axis")) { | ||||
|             return QString(QObject::tr("Axis %1%2")) | ||||
|                 .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str()); | ||||
|         } | ||||
|         if (param.Has("button")) { | ||||
|             return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str()); | ||||
|         } | ||||
|         return QString(); | ||||
|     } else { | ||||
|         return QObject::tr("[unknown]"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent) | ||||
|     : QDialog(parent), ui(std::make_unique<Ui::ConfigureMouseAdvanced>()), | ||||
|       timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { | ||||
|     ui->setupUi(this); | ||||
|     setFocusPolicy(Qt::ClickFocus); | ||||
| 
 | ||||
|     button_map = { | ||||
|         ui->left_button, ui->right_button, ui->middle_button, ui->forward_button, ui->back_button, | ||||
|     }; | ||||
| 
 | ||||
|     for (int button_id = 0; button_id < Settings::NativeMouseButton::NumMouseButtons; button_id++) { | ||||
|         if (!button_map[button_id]) | ||||
|             continue; | ||||
|         button_map[button_id]->setContextMenuPolicy(Qt::CustomContextMenu); | ||||
|         connect(button_map[button_id], &QPushButton::released, [=]() { | ||||
|             handleClick( | ||||
|                 button_map[button_id], | ||||
|                 [=](const Common::ParamPackage& params) { buttons_param[button_id] = params; }, | ||||
|                 InputCommon::Polling::DeviceType::Button); | ||||
|         }); | ||||
|         connect(button_map[button_id], &QPushButton::customContextMenuRequested, | ||||
|                 [=](const QPoint& menu_location) { | ||||
|                     QMenu context_menu; | ||||
|                     context_menu.addAction(tr("Clear"), [&] { | ||||
|                         buttons_param[button_id].Clear(); | ||||
|                         button_map[button_id]->setText(tr("[not set]")); | ||||
|                     }); | ||||
|                     context_menu.addAction(tr("Restore Default"), [&] { | ||||
|                         buttons_param[button_id] = | ||||
|                             Common::ParamPackage{InputCommon::GenerateKeyboardParam( | ||||
|                                 Config::default_mouse_buttons[button_id])}; | ||||
|                         button_map[button_id]->setText(ButtonToText(buttons_param[button_id])); | ||||
|                     }); | ||||
|                     context_menu.exec(button_map[button_id]->mapToGlobal(menu_location)); | ||||
|                 }); | ||||
|     } | ||||
| 
 | ||||
|     connect(ui->buttonClearAll, &QPushButton::released, [this] { ClearAll(); }); | ||||
|     connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); }); | ||||
| 
 | ||||
|     timeout_timer->setSingleShot(true); | ||||
|     connect(timeout_timer.get(), &QTimer::timeout, [this]() { setPollingResult({}, true); }); | ||||
| 
 | ||||
|     connect(poll_timer.get(), &QTimer::timeout, [this]() { | ||||
|         Common::ParamPackage params; | ||||
|         for (auto& poller : device_pollers) { | ||||
|             params = poller->GetNextInput(); | ||||
|             if (params.Has("engine")) { | ||||
|                 setPollingResult(params, false); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     loadConfiguration(); | ||||
|     resize(0, 0); | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::applyConfiguration() { | ||||
|     std::transform(buttons_param.begin(), buttons_param.end(), | ||||
|                    Settings::values.mouse_buttons.begin(), | ||||
|                    [](const Common::ParamPackage& param) { return param.Serialize(); }); | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::loadConfiguration() { | ||||
|     std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(), | ||||
|                    buttons_param.begin(), | ||||
|                    [](const std::string& str) { return Common::ParamPackage(str); }); | ||||
|     updateButtonLabels(); | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::restoreDefaults() { | ||||
|     for (int button_id = 0; button_id < Settings::NativeMouseButton::NumMouseButtons; button_id++) { | ||||
|         buttons_param[button_id] = Common::ParamPackage{ | ||||
|             InputCommon::GenerateKeyboardParam(Config::default_mouse_buttons[button_id])}; | ||||
|     } | ||||
| 
 | ||||
|     updateButtonLabels(); | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::ClearAll() { | ||||
|     for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { | ||||
|         if (button_map[i] && button_map[i]->isEnabled()) | ||||
|             buttons_param[i].Clear(); | ||||
|     } | ||||
| 
 | ||||
|     updateButtonLabels(); | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::updateButtonLabels() { | ||||
|     for (int button = 0; button < Settings::NativeMouseButton::NumMouseButtons; button++) { | ||||
|         button_map[button]->setText(ButtonToText(buttons_param[button])); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::handleClick( | ||||
|     QPushButton* button, std::function<void(const Common::ParamPackage&)> new_input_setter, | ||||
|     InputCommon::Polling::DeviceType type) { | ||||
|     button->setText(tr("[press key]")); | ||||
|     button->setFocus(); | ||||
| 
 | ||||
|     const auto iter = std::find(button_map.begin(), button_map.end(), button); | ||||
|     ASSERT(iter != button_map.end()); | ||||
|     const auto index = std::distance(button_map.begin(), iter); | ||||
|     ASSERT(index < Settings::NativeButton::NumButtons && index >= 0); | ||||
| 
 | ||||
|     input_setter = new_input_setter; | ||||
| 
 | ||||
|     device_pollers = InputCommon::Polling::GetPollers(type); | ||||
| 
 | ||||
|     // Keyboard keys can only be used as button devices
 | ||||
|     want_keyboard_keys = type == InputCommon::Polling::DeviceType::Button; | ||||
| 
 | ||||
|     for (auto& poller : device_pollers) { | ||||
|         poller->Start(); | ||||
|     } | ||||
| 
 | ||||
|     grabKeyboard(); | ||||
|     grabMouse(); | ||||
|     timeout_timer->start(5000); // Cancel after 5 seconds
 | ||||
|     poll_timer->start(200);     // Check for new inputs every 200ms
 | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::setPollingResult(const Common::ParamPackage& params, bool abort) { | ||||
|     releaseKeyboard(); | ||||
|     releaseMouse(); | ||||
|     timeout_timer->stop(); | ||||
|     poll_timer->stop(); | ||||
|     for (auto& poller : device_pollers) { | ||||
|         poller->Stop(); | ||||
|     } | ||||
| 
 | ||||
|     if (!abort) { | ||||
|         (*input_setter)(params); | ||||
|     } | ||||
| 
 | ||||
|     updateButtonLabels(); | ||||
|     input_setter = boost::none; | ||||
| } | ||||
| 
 | ||||
| void ConfigureMouseAdvanced::keyPressEvent(QKeyEvent* event) { | ||||
|     if (!input_setter || !event) | ||||
|         return; | ||||
| 
 | ||||
|     if (event->key() != Qt::Key_Escape) { | ||||
|         if (want_keyboard_keys) { | ||||
|             setPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())}, | ||||
|                              false); | ||||
|         } else { | ||||
|             // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop polling
 | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     setPollingResult({}, true); | ||||
| } | ||||
							
								
								
									
										67
									
								
								src/yuzu/configuration/configure_mouse_advanced.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/yuzu/configuration/configure_mouse_advanced.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| // Copyright 2016 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <QDialog> | ||||
| #include <QWidget> | ||||
| #include <boost/optional.hpp> | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| class QCheckBox; | ||||
| class QPushButton; | ||||
| class QTimer; | ||||
| 
 | ||||
| namespace Ui { | ||||
| class ConfigureMouseAdvanced; | ||||
| } | ||||
| 
 | ||||
| class ConfigureMouseAdvanced : public QDialog { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     explicit ConfigureMouseAdvanced(QWidget* parent); | ||||
| 
 | ||||
|     void applyConfiguration(); | ||||
| 
 | ||||
| private: | ||||
|     std::unique_ptr<Ui::ConfigureMouseAdvanced> ui; | ||||
| 
 | ||||
|     /// This will be the the setting function when an input is awaiting configuration.
 | ||||
|     boost::optional<std::function<void(const Common::ParamPackage&)>> input_setter; | ||||
| 
 | ||||
|     std::array<QPushButton*, Settings::NativeMouseButton::NumMouseButtons> button_map; | ||||
|     std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons> buttons_param; | ||||
| 
 | ||||
|     std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; | ||||
| 
 | ||||
|     std::unique_ptr<QTimer> timeout_timer; | ||||
|     std::unique_ptr<QTimer> poll_timer; | ||||
| 
 | ||||
|     /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
 | ||||
|     /// keyboard events are ignored.
 | ||||
|     bool want_keyboard_keys = false; | ||||
| 
 | ||||
|     /// Load configuration settings.
 | ||||
|     void loadConfiguration(); | ||||
|     /// Restore all buttons to their default values.
 | ||||
|     void restoreDefaults(); | ||||
|     /// Clear all input configuration
 | ||||
|     void ClearAll(); | ||||
| 
 | ||||
|     /// Update UI to reflect current configuration.
 | ||||
|     void updateButtonLabels(); | ||||
| 
 | ||||
|     /// Called when the button was pressed.
 | ||||
|     void handleClick(QPushButton* button, | ||||
|                      std::function<void(const Common::ParamPackage&)> new_input_setter, | ||||
|                      InputCommon::Polling::DeviceType type); | ||||
| 
 | ||||
|     /// Finish polling and configure input using the input_setter
 | ||||
|     void setPollingResult(const Common::ParamPackage& params, bool abort); | ||||
| 
 | ||||
|     /// Handle key press events.
 | ||||
|     void keyPressEvent(QKeyEvent* event) override; | ||||
| }; | ||||
							
								
								
									
										261
									
								
								src/yuzu/configuration/configure_mouse_advanced.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								src/yuzu/configuration/configure_mouse_advanced.ui
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,261 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>ConfigureMouseAdvanced</class> | ||||
|  <widget class="QDialog" name="ConfigureMouseAdvanced"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>250</width> | ||||
|     <height>261</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Configure Mouse</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|    <item> | ||||
|     <widget class="QGroupBox" name="gridGroupBox"> | ||||
|      <property name="title"> | ||||
|       <string>Mouse Buttons</string> | ||||
|      </property> | ||||
|      <layout class="QGridLayout" name="gridLayout"> | ||||
|       <item row="0" column="4"> | ||||
|        <spacer name="horizontalSpacer_2"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|         <property name="sizeType"> | ||||
|          <enum>QSizePolicy::Fixed</enum> | ||||
|         </property> | ||||
|         <property name="sizeHint" stdset="0"> | ||||
|          <size> | ||||
|           <width>20</width> | ||||
|           <height>20</height> | ||||
|          </size> | ||||
|         </property> | ||||
|        </spacer> | ||||
|       </item> | ||||
|       <item row="0" column="3"> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_4"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="label_3"> | ||||
|             <property name="text"> | ||||
|              <string>Right:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="right_button"> | ||||
|           <property name="minimumSize"> | ||||
|            <size> | ||||
|             <width>75</width> | ||||
|             <height>0</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item row="0" column="0"> | ||||
|        <spacer name="horizontalSpacer"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|         <property name="sizeType"> | ||||
|          <enum>QSizePolicy::Fixed</enum> | ||||
|         </property> | ||||
|         <property name="sizeHint" stdset="0"> | ||||
|          <size> | ||||
|           <width>20</width> | ||||
|           <height>20</height> | ||||
|          </size> | ||||
|         </property> | ||||
|        </spacer> | ||||
|       </item> | ||||
|       <item row="2" column="1"> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="label_2"> | ||||
|             <property name="text"> | ||||
|              <string>Middle:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="middle_button"> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item row="3" column="1"> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_5"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_4"> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="label_4"> | ||||
|             <property name="minimumSize"> | ||||
|              <size> | ||||
|               <width>54</width> | ||||
|               <height>0</height> | ||||
|              </size> | ||||
|             </property> | ||||
|             <property name="text"> | ||||
|              <string>Back:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="back_button"> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item row="0" column="1"> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="label"> | ||||
|             <property name="text"> | ||||
|              <string>Left:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="left_button"> | ||||
|           <property name="minimumSize"> | ||||
|            <size> | ||||
|             <width>75</width> | ||||
|             <height>0</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item row="3" column="3"> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_5"> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="label_5"> | ||||
|             <property name="text"> | ||||
|              <string>Forward:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="forward_button"> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <layout class="QHBoxLayout" name="horizontalLayout_6"> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="buttonClearAll"> | ||||
|        <property name="text"> | ||||
|         <string>Clear All</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="buttonRestoreDefaults"> | ||||
|        <property name="text"> | ||||
|         <string>Restore Defaults</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <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> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
|     <widget class="QDialogButtonBox" name="buttonBox"> | ||||
|      <property name="standardButtons"> | ||||
|       <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <resources/> | ||||
|  <connections> | ||||
|   <connection> | ||||
|    <sender>buttonBox</sender> | ||||
|    <signal>accepted()</signal> | ||||
|    <receiver>ConfigureMouseAdvanced</receiver> | ||||
|    <slot>accept()</slot> | ||||
|    <hints> | ||||
|     <hint type="sourcelabel"> | ||||
|      <x>124</x> | ||||
|      <y>266</y> | ||||
|     </hint> | ||||
|     <hint type="destinationlabel"> | ||||
|      <x>124</x> | ||||
|      <y>143</y> | ||||
|     </hint> | ||||
|    </hints> | ||||
|   </connection> | ||||
|   <connection> | ||||
|    <sender>buttonBox</sender> | ||||
|    <signal>rejected()</signal> | ||||
|    <receiver>ConfigureMouseAdvanced</receiver> | ||||
|    <slot>reject()</slot> | ||||
|    <hints> | ||||
|     <hint type="sourcelabel"> | ||||
|      <x>124</x> | ||||
|      <y>266</y> | ||||
|     </hint> | ||||
|     <hint type="destinationlabel"> | ||||
|      <x>124</x> | ||||
|      <y>143</y> | ||||
|     </hint> | ||||
|    </hints> | ||||
|   </connection> | ||||
|  </connections> | ||||
| </ui> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zach Hilman
						Zach Hilman