1 /* 2 Copyright (c) 2012-2020 Maarten Baert <maarten-baert@hotmail.com> 3 4 This file is part of SimpleScreenRecorder. 5 6 SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 SimpleScreenRecorder is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with SimpleScreenRecorder. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #pragma once 21 #include "Global.h" 22 23 #include "ProfileBox.h" 24 25 #if SSR_USE_ALSA 26 #include "ALSAInput.h" 27 #endif 28 #if SSR_USE_PULSEAUDIO 29 #include "PulseAudioInput.h" 30 #endif 31 32 class QComboBoxWithSignal : public QComboBox { 33 Q_OBJECT 34 35 public: 36 QComboBoxWithSignal(QWidget* parent); 37 38 virtual void showPopup() override; 39 virtual void hidePopup() override; 40 41 signals: 42 void popupShown(); 43 void popupHidden(); 44 45 }; 46 47 class QSpinBoxWithSignal : public QSpinBox { 48 Q_OBJECT 49 50 public: 51 QSpinBoxWithSignal(QWidget* parent); 52 53 virtual void focusInEvent(QFocusEvent* event) override; 54 virtual void focusOutEvent(QFocusEvent* event) override; 55 56 signals: 57 void focusIn(); 58 void focusOut(); 59 60 }; 61 62 class ScreenLabelWindow : public QWidget { 63 Q_OBJECT 64 65 private: 66 QString m_text; 67 QFont m_font; 68 69 public: 70 ScreenLabelWindow(QWidget* parent, const QString& text); 71 72 protected: 73 virtual void paintEvent(QPaintEvent* event) override; 74 75 }; 76 77 class RecordingFrameWindow : public QWidget { 78 Q_OBJECT 79 80 private: 81 bool m_outside; 82 QPixmap m_texture; 83 84 public: 85 static constexpr int BORDER_WIDTH = 4; 86 87 public: 88 RecordingFrameWindow(QWidget* parent, bool outside); 89 90 void SetRectangle(const QRect& r); 91 92 private: 93 void UpdateMask(); 94 95 protected: 96 virtual void resizeEvent(QResizeEvent* event) override; 97 virtual void paintEvent(QPaintEvent* event) override; 98 99 }; 100 101 class MainWindow; 102 103 class PageInput : public QWidget { 104 Q_OBJECT 105 106 public: 107 enum enum_video_area { 108 VIDEO_AREA_SCREEN, 109 VIDEO_AREA_FIXED, 110 VIDEO_AREA_CURSOR, 111 #if SSR_USE_OPENGL_RECORDING 112 VIDEO_AREA_GLINJECT, 113 #endif 114 #if SSR_USE_V4L2 115 VIDEO_AREA_V4L2, 116 #endif 117 VIDEO_AREA_COUNT // must be last 118 }; 119 enum enum_audio_backend { 120 #if SSR_USE_ALSA 121 AUDIO_BACKEND_ALSA, 122 #endif 123 #if SSR_USE_PULSEAUDIO 124 AUDIO_BACKEND_PULSEAUDIO, 125 #endif 126 #if SSR_USE_JACK 127 AUDIO_BACKEND_JACK, 128 #endif 129 AUDIO_BACKEND_COUNT // must be last 130 }; 131 132 private: 133 MainWindow *m_main_window; 134 135 bool m_grabbing, m_selecting_window; 136 std::unique_ptr<RecordingFrameWindow> m_rubber_band, m_recording_frame; 137 QRect m_rubber_band_rect, m_select_window_outer_rect, m_select_window_inner_rect; 138 139 #if SSR_USE_ALSA 140 std::vector<ALSAInput::Source> m_alsa_sources; 141 #endif 142 #if SSR_USE_PULSEAUDIO 143 bool m_pulseaudio_available; 144 std::vector<PulseAudioInput::Source> m_pulseaudio_sources; 145 #endif 146 147 #if SSR_USE_OPENGL_RECORDING 148 QString m_glinject_channel; 149 bool m_glinject_relax_permissions; 150 QString m_glinject_command, m_glinject_working_directory; 151 bool m_glinject_auto_launch; 152 bool m_glinject_limit_fps; 153 #endif 154 155 std::vector<ScreenLabelWindow*> m_screen_labels; 156 157 ProfileBox *m_profile_box; 158 159 QButtonGroup *m_buttongroup_video_area; 160 QComboBoxWithSignal *m_combobox_screens; 161 QCheckBox *m_checkbox_follow_fullscreen; 162 QPushButton *m_pushbutton_video_select_rectangle, *m_pushbutton_video_select_window; 163 #if SSR_USE_OPENGL_RECORDING 164 QPushButton *m_pushbutton_video_opengl_settings; 165 #endif 166 #if SSR_USE_V4L2 167 QLineEdit *m_lineedit_v4l2_device; 168 #endif 169 QLabel *m_label_video_x, *m_label_video_y, *m_label_video_w, *m_label_video_h; 170 QSpinBoxWithSignal *m_spinbox_video_x, *m_spinbox_video_y, *m_spinbox_video_w, *m_spinbox_video_h; 171 QSpinBox *m_spinbox_video_frame_rate; 172 QCheckBox *m_checkbox_scale; 173 QLabel *m_label_video_scaled_w, *m_label_video_scaled_h; 174 QSpinBox *m_spinbox_video_scaled_w, *m_spinbox_video_scaled_h; 175 QCheckBox *m_checkbox_record_cursor; 176 177 QCheckBox *m_checkbox_audio_enable; 178 QLabel *m_label_audio_backend; 179 QComboBox *m_combobox_audio_backend; 180 #if SSR_USE_ALSA 181 QLabel *m_label_alsa_source; 182 QComboBox *m_combobox_alsa_source; 183 QPushButton *m_pushbutton_alsa_refresh; 184 #endif 185 #if SSR_USE_PULSEAUDIO 186 QLabel *m_label_pulseaudio_source; 187 QComboBox *m_combobox_pulseaudio_source; 188 QPushButton *m_pushbutton_pulseaudio_refresh; 189 #endif 190 #if SSR_USE_JACK 191 QCheckBox *m_checkbox_jack_connect_system_capture, *m_checkbox_jack_connect_system_playback; 192 #endif 193 194 public: 195 PageInput(MainWindow* main_window); 196 197 void LoadSettings(QSettings* settings); 198 void SaveSettings(QSettings* settings); 199 200 private: 201 static void LoadProfileSettingsCallback(QSettings* settings, void* userdata); 202 static void SaveProfileSettingsCallback(QSettings* settings, void* userdata); 203 void LoadProfileSettings(QSettings* settings); 204 void SaveProfileSettings(QSettings* settings); 205 206 public: 207 bool Validate(); 208 209 #if SSR_USE_ALSA 210 QString GetALSASourceName(); 211 #endif 212 #if SSR_USE_PULSEAUDIO 213 QString GetPulseAudioSourceName(); 214 #endif 215 216 private: 217 #if SSR_USE_ALSA 218 unsigned int FindALSASource(const QString& name); 219 #endif 220 #if SSR_USE_PULSEAUDIO 221 unsigned int FindPulseAudioSource(const QString& name); 222 #endif 223 224 protected: 225 virtual void mousePressEvent(QMouseEvent* event) override; 226 virtual void mouseReleaseEvent(QMouseEvent* event) override; 227 virtual void mouseMoveEvent(QMouseEvent* event) override; 228 virtual void keyPressEvent(QKeyEvent* event) override; 229 230 private: 231 void StartGrabbing(); 232 void StopGrabbing(); 233 void UpdateRubberBand(); 234 void SetVideoAreaFromRubberBand(); 235 236 void LoadScreenConfigurations(); 237 #if SSR_USE_ALSA 238 void LoadALSASources(); 239 #endif 240 #if SSR_USE_PULSEAUDIO 241 void LoadPulseAudioSources(); 242 #endif 243 244 public slots: 245 void OnUpdateRecordingFrame(); 246 void OnUpdateVideoAreaFields(); 247 void OnUpdateVideoScaleFields(); 248 void OnUpdateAudioFields(); 249 250 private slots: 251 void OnFocusChange(QWidget* old, QWidget* now); 252 #if QT_VERSION_MAJOR >= 5 253 void OnScreenAdded(QScreen* screen); 254 #endif 255 void OnUpdateScreenConfiguration(); 256 #if SSR_USE_ALSA 257 void OnUpdateALSASources(); 258 #endif 259 #if SSR_USE_PULSEAUDIO 260 void OnUpdatePulseAudioSources(); 261 #endif 262 void OnIdentifyScreens(); 263 void OnStopIdentifyScreens(); 264 void OnStartSelectRectangle(); 265 void OnStartSelectWindow(); 266 #if SSR_USE_OPENGL_RECORDING 267 void OnGLInjectDialog(); 268 #endif 269 void OnContinue(); 270 271 public: GetProfile()272 inline unsigned int GetProfile() { return m_profile_box->GetProfile(); } GetVideoArea()273 inline enum_video_area GetVideoArea() { return (enum_video_area) clamp(m_buttongroup_video_area->checkedId(), 0, VIDEO_AREA_COUNT - 1); } GetVideoAreaScreen()274 inline unsigned int GetVideoAreaScreen() { return m_combobox_screens->currentIndex(); } GetVideoAreaFollowFullscreen()275 inline bool GetVideoAreaFollowFullscreen() { return m_checkbox_follow_fullscreen->isChecked(); } 276 #if SSR_USE_V4L2 GetVideoV4L2Device()277 inline QString GetVideoV4L2Device() { return m_lineedit_v4l2_device->text(); } 278 #endif GetVideoX()279 inline unsigned int GetVideoX() { return m_spinbox_video_x->value(); } GetVideoY()280 inline unsigned int GetVideoY() { return m_spinbox_video_y->value(); } GetVideoW()281 inline unsigned int GetVideoW() { return m_spinbox_video_w->value(); } GetVideoH()282 inline unsigned int GetVideoH() { return m_spinbox_video_h->value(); } GetVideoFrameRate()283 inline unsigned int GetVideoFrameRate() { return m_spinbox_video_frame_rate->value(); } GetVideoScalingEnabled()284 inline bool GetVideoScalingEnabled() { return m_checkbox_scale->isChecked(); } GetVideoScaledW()285 inline unsigned int GetVideoScaledW() { return m_spinbox_video_scaled_w->value(); } GetVideoScaledH()286 inline unsigned int GetVideoScaledH() { return m_spinbox_video_scaled_h->value(); } GetVideoRecordCursor()287 inline bool GetVideoRecordCursor() { return m_checkbox_record_cursor->isChecked(); } GetAudioEnabled()288 inline bool GetAudioEnabled() { return m_checkbox_audio_enable->isChecked(); } GetAudioBackend()289 inline enum_audio_backend GetAudioBackend() { return (enum_audio_backend) clamp(m_combobox_audio_backend->currentIndex(), 0, AUDIO_BACKEND_COUNT - 1); } 290 #if SSR_USE_ALSA GetALSASource()291 inline unsigned int GetALSASource() { return clamp(m_combobox_alsa_source->currentIndex(), 0, (int) m_alsa_sources.size() - 1); } 292 #endif 293 #if SSR_USE_PULSEAUDIO GetPulseAudioSource()294 inline unsigned int GetPulseAudioSource() { return clamp(m_combobox_pulseaudio_source->currentIndex(), 0, (int) m_pulseaudio_sources.size() - 1); } 295 #endif 296 #if SSR_USE_JACK GetJackConnectSystemCapture()297 inline bool GetJackConnectSystemCapture() { return m_checkbox_jack_connect_system_capture->isChecked(); } GetJackConnectSystemPlayback()298 inline bool GetJackConnectSystemPlayback() { return m_checkbox_jack_connect_system_playback->isChecked(); } 299 #endif 300 #if SSR_USE_OPENGL_RECORDING GetGLInjectChannel()301 inline QString GetGLInjectChannel() { return m_glinject_channel; } GetGLInjectRelaxPermissions()302 inline bool GetGLInjectRelaxPermissions() { return m_glinject_relax_permissions; } GetGLInjectCommand()303 inline QString GetGLInjectCommand() { return m_glinject_command; } GetGLInjectWorkingDirectory()304 inline QString GetGLInjectWorkingDirectory() { return m_glinject_working_directory; } GetGLInjectAutoLaunch()305 inline bool GetGLInjectAutoLaunch() { return m_glinject_auto_launch; } GetGLInjectLimitFPS()306 inline bool GetGLInjectLimitFPS() { return m_glinject_limit_fps; } 307 #endif 308 SetProfile(unsigned int profile)309 inline void SetProfile(unsigned int profile) { m_profile_box->SetProfile(profile); } SetVideoArea(enum_video_area area)310 inline void SetVideoArea(enum_video_area area) { QAbstractButton *b = m_buttongroup_video_area->button(area); if(b != NULL) b->setChecked(true); } SetVideoAreaScreen(unsigned int screen)311 inline void SetVideoAreaScreen(unsigned int screen) { m_combobox_screens->setCurrentIndex(clamp(screen, 0u, (unsigned int) m_combobox_screens->count() - 1)); } SetVideoAreaFollowFullscreen(bool follow_fulscreen)312 inline void SetVideoAreaFollowFullscreen(bool follow_fulscreen) { m_checkbox_follow_fullscreen->setChecked(follow_fulscreen); } 313 #if SSR_USE_V4L2 SetVideoV4L2Device(const QString & device)314 inline void SetVideoV4L2Device(const QString& device) { m_lineedit_v4l2_device->setText(device); } 315 #endif SetVideoX(unsigned int x)316 inline void SetVideoX(unsigned int x) { m_spinbox_video_x->setValue(x); } SetVideoY(unsigned int y)317 inline void SetVideoY(unsigned int y) { m_spinbox_video_y->setValue(y); } SetVideoW(unsigned int w)318 inline void SetVideoW(unsigned int w) { m_spinbox_video_w->setValue(w); } SetVideoH(unsigned int h)319 inline void SetVideoH(unsigned int h) { m_spinbox_video_h->setValue(h); } SetVideoFrameRate(unsigned int frame_rate)320 inline void SetVideoFrameRate(unsigned int frame_rate) { m_spinbox_video_frame_rate->setValue(frame_rate); } SetVideoScalingEnabled(bool enable)321 inline void SetVideoScalingEnabled(bool enable) { m_checkbox_scale->setChecked(enable); } SetVideoScaledW(unsigned int scaled_w)322 inline void SetVideoScaledW(unsigned int scaled_w) { m_spinbox_video_scaled_w->setValue(scaled_w); } SetVideoScaledH(unsigned int scaled_h)323 inline void SetVideoScaledH(unsigned int scaled_h) { m_spinbox_video_scaled_h->setValue(scaled_h); } SetVideoRecordCursor(bool show)324 inline void SetVideoRecordCursor(bool show) { m_checkbox_record_cursor->setChecked(show); } SetAudioEnabled(bool enable)325 inline void SetAudioEnabled(bool enable) { m_checkbox_audio_enable->setChecked(enable); } SetAudioBackend(enum_audio_backend backend)326 inline void SetAudioBackend(enum_audio_backend backend) { m_combobox_audio_backend->setCurrentIndex(clamp((int) backend, 0, AUDIO_BACKEND_COUNT - 1)); } 327 #if SSR_USE_ALSA SetALSASource(unsigned int source)328 inline void SetALSASource(unsigned int source) { m_combobox_alsa_source->setCurrentIndex(clamp(source, 0u, (unsigned int) m_alsa_sources.size() - 1)); } 329 #endif 330 #if SSR_USE_PULSEAUDIO SetPulseAudioSource(unsigned int source)331 inline void SetPulseAudioSource(unsigned int source) { m_combobox_pulseaudio_source->setCurrentIndex(clamp(source, 0u, (unsigned int) m_pulseaudio_sources.size() - 1)); } 332 #endif 333 #if SSR_USE_JACK SetJackConnectSystemCapture(bool connect)334 inline void SetJackConnectSystemCapture(bool connect) { m_checkbox_jack_connect_system_capture->setChecked(connect); } SetJackConnectSystemPlayback(bool connect)335 inline void SetJackConnectSystemPlayback(bool connect) { m_checkbox_jack_connect_system_playback->setChecked(connect); } 336 #endif 337 #if SSR_USE_OPENGL_RECORDING SetGLInjectChannel(const QString & channel)338 inline void SetGLInjectChannel(const QString& channel) { m_glinject_channel = channel; } SetGLInjectRelaxPermissions(bool relax_permissions)339 inline void SetGLInjectRelaxPermissions(bool relax_permissions) { m_glinject_relax_permissions = relax_permissions; } SetGLInjectCommand(const QString & command)340 inline void SetGLInjectCommand(const QString& command) { m_glinject_command = command; } SetGLInjectWorkingDirectory(const QString & glinject_working_directory)341 inline void SetGLInjectWorkingDirectory(const QString& glinject_working_directory) { m_glinject_working_directory = glinject_working_directory; } SetGLInjectAutoLaunch(bool auto_launch)342 inline void SetGLInjectAutoLaunch(bool auto_launch) { m_glinject_auto_launch = auto_launch; } SetGLInjectLimitFPS(bool limit_fps)343 inline void SetGLInjectLimitFPS(bool limit_fps) { m_glinject_limit_fps = limit_fps; } 344 #endif 345 346 }; 347