diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 46f512a10..e0cfea4b5 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -114,6 +114,9 @@ int gs_create(graphics_t *pgraphics, const char *module, graphics_t graphics = bzalloc(sizeof(struct graphics_subsystem)); pthread_mutex_init_value(&graphics->mutex); + if (!data->num_backbuffers) + data->num_backbuffers = 1; + graphics->module = os_dlopen(module); if (!graphics->module) { errcode = GS_ERROR_MODULENOTFOUND; diff --git a/libobs/obs-display.c b/libobs/obs-display.c index b9de28ce9..88282730c 100644 --- a/libobs/obs-display.c +++ b/libobs/obs-display.c @@ -48,11 +48,22 @@ obs_display_t obs_display_create(struct gs_init_data *graphics_data) { struct obs_display *display = bzalloc(sizeof(struct obs_display)); + gs_entercontext(obs_graphics()); + + if (!graphics_data->num_backbuffers) + graphics_data->num_backbuffers = 1; + if (!obs_display_init(display, graphics_data)) { obs_display_destroy(display); display = NULL; + } else { + pthread_mutex_lock(&obs->data.displays_mutex); + da_push_back(obs->data.displays, &display); + pthread_mutex_unlock(&obs->data.displays_mutex); } + gs_leavecontext(); + return display; } @@ -74,7 +85,10 @@ void obs_display_destroy(obs_display_t display) da_erase_item(obs->data.displays, &display); pthread_mutex_unlock(&obs->data.displays_mutex); + gs_entercontext(obs_graphics()); obs_display_free(display); + gs_leavecontext(); + bfree(display); } } diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c index a665cedb6..8a4df55e9 100644 --- a/libobs/obs-encoder.c +++ b/libobs/obs-encoder.c @@ -208,7 +208,7 @@ obs_data_t obs_encoder_defaults(const char *id) return NULL; } -obs_properties_t obs_encoder_properties(const char *id, const char *locale) +obs_properties_t obs_get_encoder_properties(const char *id, const char *locale) { const struct obs_encoder_info *ei = get_encoder_info(id); if (ei && ei->properties) @@ -216,6 +216,14 @@ obs_properties_t obs_encoder_properties(const char *id, const char *locale) return NULL; } +obs_properties_t obs_encoder_properties(obs_encoder_t encoder, + const char *locale) +{ + if (encoder && encoder->info.properties) + return encoder->info.properties(locale); + return NULL; +} + void obs_encoder_update(obs_encoder_t encoder, obs_data_t settings) { if (!encoder) return; diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 0df14a72a..7465fa852 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -130,14 +130,42 @@ void free_module(struct obs_module *mod) bfree(mod->name); } +#define REGISTER_OBS_DEF(size_var, structure, dest, info) \ + do { \ + struct structure data = {0}; \ + if (!size_var) { \ + blog(LOG_ERROR, "Tried to register " #structure \ + " outside of obs_module_load"); \ + return; \ + } \ + \ + memcpy(&data, info, size_var); \ + da_push_back(dest, &data); \ + } while (false) + +#define CHECK_REQUIRED_VAL(info, val, func) \ + do { \ + if (!info->val) {\ + blog(LOG_ERROR, "Required value '" #val " for" \ + "'%s' not found. " #func \ + " failed.", info->id); \ + return; \ + } \ + } while (false) + void obs_register_source(const struct obs_source_info *info) { struct obs_source_info data = {0}; struct darray *array; - if (!info) { - blog(LOG_ERROR, "obs_register_source: NULL info"); - return; + CHECK_REQUIRED_VAL(info, getname, obs_register_source); + CHECK_REQUIRED_VAL(info, create, obs_register_source); + CHECK_REQUIRED_VAL(info, destroy, obs_register_source); + + if (info->type == OBS_SOURCE_TYPE_INPUT && + info->output_flags & OBS_SOURCE_VIDEO) { + CHECK_REQUIRED_VAL(info, getwidth, obs_register_source); + CHECK_REQUIRED_VAL(info, getheight, obs_register_source); } if (!cur_source_info_size) { @@ -163,29 +191,6 @@ void obs_register_source(const struct obs_source_info *info) darray_push_back(sizeof(struct obs_source_info), array, &data); } -#define REGISTER_OBS_DEF(size_var, structure, dest, info) \ - do { \ - struct structure data = {0}; \ - if (!size_var) { \ - blog(LOG_ERROR, "Tried to register " #structure \ - " outside of obs_module_load"); \ - return; \ - } \ - \ - memcpy(&data, info, size_var); \ - da_push_back(dest, &data); \ - } while (false) - -#define CHECK_REQUIRED_VAL(info, val, func) \ - do { \ - if (!info->val) {\ - blog(LOG_ERROR, "Required value '" #val " for" \ - "'%s' not found. " #func \ - " failed.", info->id); \ - return; \ - } \ - } while (false) - void obs_register_output(const struct obs_output_info *info) { CHECK_REQUIRED_VAL(info, getname, obs_register_output); diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 6b80f36c7..064edee34 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -128,7 +128,7 @@ obs_data_t obs_output_defaults(const char *id) return NULL; } -obs_properties_t obs_output_properties(const char *id, const char *locale) +obs_properties_t obs_get_output_properties(const char *id, const char *locale) { const struct obs_output_info *info = find_output(id); if (info && info->properties) @@ -136,6 +136,13 @@ obs_properties_t obs_output_properties(const char *id, const char *locale) return NULL; } +obs_properties_t obs_output_properties(obs_output_t output, const char *locale) +{ + if (output && output->info.properties) + return output->info.properties(locale); + return NULL; +} + void obs_output_update(obs_output_t output, obs_data_t settings) { if (!output) return; diff --git a/libobs/obs-properties.c b/libobs/obs-properties.c index e7e64e19b..fc5c7b7dc 100644 --- a/libobs/obs-properties.c +++ b/libobs/obs-properties.c @@ -315,7 +315,7 @@ const char *obs_property_description(obs_property_t p) return p ? p->desc : NULL; } -enum obs_property_type obs_property_type(obs_property_t p) +enum obs_property_type obs_property_get_type(obs_property_t p) { return p ? p->type : OBS_PROPERTY_INVALID; } diff --git a/libobs/obs-properties.h b/libobs/obs-properties.h index 95e3bb324..3a0506ad7 100644 --- a/libobs/obs-properties.h +++ b/libobs/obs-properties.h @@ -87,7 +87,7 @@ EXPORT void obs_property_list_add_item(obs_property_t p, EXPORT const char * obs_property_name(obs_property_t p); EXPORT const char * obs_property_description(obs_property_t p); -EXPORT enum obs_property_type obs_property_type(obs_property_t p); +EXPORT enum obs_property_type obs_property_get_type(obs_property_t p); EXPORT bool obs_property_next(obs_property_t *p); diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 83f1096f6..7561acd3c 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -327,7 +327,7 @@ obs_data_t obs_source_settings(enum obs_source_type type, const char *id) return NULL; } -obs_properties_t obs_source_properties(enum obs_source_type type, +obs_properties_t obs_get_source_properties(enum obs_source_type type, const char *id, const char *locale) { const struct obs_source_info *info = get_source_info(type, id); @@ -336,6 +336,13 @@ obs_properties_t obs_source_properties(enum obs_source_type type, return NULL; } +obs_properties_t obs_source_properties(obs_source_t source, const char *locale) +{ + if (source && source->info.properties) + return source->info.properties(locale); + return NULL; +} + uint32_t obs_source_get_output_flags(obs_source_t source) { return source ? source->info.output_flags : 0; diff --git a/libobs/obs-source.h b/libobs/obs-source.h index a87d802b5..ac827ed54 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -132,6 +132,12 @@ struct obs_source_info { /** Destroys the private data for the source */ void (*destroy)(void *data); + /** Returns the width of the source. Required if input and video */ + uint32_t (*getwidth)(void *data); + + /** Returns the height of the source. Required if input and video */ + uint32_t (*getheight)(void *data); + /* ----------------------------------------------------------------- */ /* Optional implementation */ @@ -210,12 +216,6 @@ struct obs_source_info { */ void (*video_render)(void *data, effect_t effect); - /** @return The width of the source */ - uint32_t (*getwidth)(void *data); - - /** @return The height of the source */ - uint32_t (*getheight)(void *data); - /** * Called to filter raw async video data. * diff --git a/libobs/obs.h b/libobs/obs.h index 67c2dbaf1..3a4a7c076 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1,5 +1,5 @@ /****************************************************************************** - Copyright (C) 2013 by Hugh Bailey + Copyright (C) 2013-2014 by Hugh Bailey This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ struct obs_encoder; struct obs_service; typedef struct obs_display *obs_display_t; -typedef struct obs_view *obs_view_t; +typedef struct obs_view *obs_view_t; typedef struct obs_source *obs_source_t; typedef struct obs_scene *obs_scene_t; typedef struct obs_scene_item *obs_sceneitem_t; @@ -438,13 +438,20 @@ EXPORT bool obs_source_removed(obs_source_t source); EXPORT uint32_t obs_source_get_output_flags(obs_source_t source); /** Gets the default settings for a source type */ -EXPORT obs_data_t obs_source_defaults(enum obs_source_type type, +EXPORT obs_data_t obs_get_source_defaults(enum obs_source_type type, const char *id); /** Returns the property list, if any. Free with obs_properties_destroy */ -EXPORT obs_properties_t obs_source_properties(enum obs_source_type type, +EXPORT obs_properties_t obs_get_source_properties(enum obs_source_type type, const char *id, const char *locale); +/** + * Returns the properties list for a specific existing source. Free with + * obs_properties_destroy + */ +EXPORT obs_properties_t obs_source_properties(obs_source_t source, + const char *locale); + /** Updates settings for this source */ EXPORT void obs_source_update(obs_source_t source, obs_data_t settings); @@ -662,7 +669,14 @@ EXPORT bool obs_output_active(obs_output_t output); EXPORT obs_data_t obs_output_defaults(const char *id); /** Returns the property list, if any. Free with obs_properties_destroy */ -EXPORT obs_properties_t obs_output_properties(const char *id, +EXPORT obs_properties_t obs_get_output_properties(const char *id, + const char *locale); + +/** + * Returns the property list of an existing output, if any. Free with + * obs_properties_destroy + */ +EXPORT obs_properties_t obs_output_properties(obs_output_t output, const char *locale); /** Updates the settings for this output context */ @@ -742,7 +756,14 @@ EXPORT void obs_encoder_stop(obs_encoder_t encoder, EXPORT obs_data_t obs_encoder_defaults(const char *id); /** Returns the property list, if any. Free with obs_properties_destroy */ -EXPORT obs_properties_t obs_encoder_properties(const char *id, +EXPORT obs_properties_t obs_get_encoder_properties(const char *id, + const char *locale); + +/** + * Returns the property list of an existing encoder, if any. Free with + * obs_properties_destroy + */ +EXPORT obs_properties_t obs_encoder_properties(obs_encoder_t encoder, const char *locale); /** diff --git a/libobs/obs.hpp b/libobs/obs.hpp index 425f4704d..f7c823faa 100644 --- a/libobs/obs.hpp +++ b/libobs/obs.hpp @@ -63,10 +63,91 @@ public: }; using OBSSource = OBSRef; -using OBSScene = OBSRef; +using OBSScene = OBSRef; using OBSSceneItem = OBSRef; - using OBSData = OBSRef; using OBSDataArray = OBSRef; + +/* objects that are not meant to be instanced */ +template class OBSObj { + T obj; + +public: + inline OBSObj() : obj(nullptr) {} + inline OBSObj(T obj_) : obj(obj_) {} + + inline ~OBSObj() {destroy(obj);} + + inline OBSObj &operator=(T obj_) + { + if (obj_ != obj) + destroy(obj); + obj = obj_; + return *this; + } + + inline operator T() const {return obj;} + + inline bool operator==(T p) const {return obj == p;} + inline bool operator!=(T p) const {return obj != p;} +}; + +using OBSDisplay = OBSObj; +using OBSEncoder = OBSObj; +using OBSView = OBSObj; +using OBSOutput = OBSObj; + +/* signal handler connection */ +class OBSSignal { + signal_handler_t handler; + const char *signal; + signal_callback_t callback; + void *param; + +public: + inline OBSSignal() + : handler (nullptr), + signal (nullptr), + callback (nullptr), + param (nullptr) + {} + + inline OBSSignal(signal_handler_t handler_, + const char *signal_, + signal_callback_t callback_, + void *param_) + : handler (handler_), + signal (signal_), + callback (callback_), + param (param_) + { + signal_handler_connect(handler, signal, callback, param); + } + + inline void Disconnect() + { + signal_handler_disconnect(handler, signal, callback, param); + handler = nullptr; + signal = nullptr; + callback = nullptr; + param = nullptr; + } + + inline ~OBSSignal() {Disconnect();} + + inline void Connect(signal_handler_t handler_, + const char *signal_, + signal_callback_t callback_, + void *param_) + { + Disconnect(); + + handler = handler_; + signal = signal_; + callback = callback_; + param = param_; + signal_handler_connect(handler, signal, callback, param); + } +}; diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 1f2b87603..00a25a7c1 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -51,7 +51,9 @@ set(obs_SOURCES obs-app.cpp window-basic-main.cpp window-basic-settings.cpp + window-basic-properties.cpp window-namedialog.cpp + properties-view.cpp qt-wrappers.cpp) set(obs_HEADERS @@ -60,14 +62,18 @@ set(obs_HEADERS window-main.hpp window-basic-main.hpp window-basic-settings.hpp + window-basic-properties.hpp window-namedialog.hpp + properties-view.hpp + display-helpers.hpp qt-display.hpp qt-wrappers.hpp) set(obs_UI forms/NameDialog.ui forms/OBSBasic.ui - forms/OBSBasicSettings.ui) + forms/OBSBasicSettings.ui + forms/OBSBasicProperties.ui) set(obs_QRC forms/obs.qrc) diff --git a/obs/display-helpers.hpp b/obs/display-helpers.hpp new file mode 100644 index 000000000..de19e5ab6 --- /dev/null +++ b/obs/display-helpers.hpp @@ -0,0 +1,42 @@ +/****************************************************************************** + Copyright (C) 2014 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#pragma once + +static inline void GetScaleAndCenterPos( + int baseCX, int baseCY, int windowCX, int windowCY, + int &x, int &y, float &scale) +{ + double windowAspect, baseAspect; + int newCX, newCY; + + windowAspect = double(windowCX) / double(windowCY); + baseAspect = double(baseCX) / double(baseCY); + + if (windowAspect > baseAspect) { + scale = float(windowCY) / float(baseCY); + newCX = int(double(windowCY) * baseAspect); + newCY = windowCY; + } else { + scale = float(windowCX) / float(baseCX); + newCX = windowCX; + newCY = int(float(windowCX) / baseAspect); + } + + x = windowCX/2 - newCX/2; + y = windowCY/2 - newCY/2; +} diff --git a/obs/forms/OBSBasic.ui b/obs/forms/OBSBasic.ui index f60778f46..a1d3d9bb5 100644 --- a/obs/forms/OBSBasic.ui +++ b/obs/forms/OBSBasic.ui @@ -433,7 +433,7 @@ - false + true diff --git a/obs/forms/OBSBasicProperties.ui b/obs/forms/OBSBasicProperties.ui new file mode 100644 index 000000000..f8260da98 --- /dev/null +++ b/obs/forms/OBSBasicProperties.ui @@ -0,0 +1,48 @@ + + + OBSBasicProperties + + + + 0 + 0 + 841 + 479 + + + + Dialog + + + true + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + + + + + OBSQTDisplay + QWidget +
qt-display.hpp
+ 1 +
+
+ + +
diff --git a/obs/properties-view.cpp b/obs/properties-view.cpp new file mode 100644 index 000000000..fbd905f1b --- /dev/null +++ b/obs/properties-view.cpp @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include +#include +#include +#include "qt-wrappers.hpp" +#include "properties-view.hpp" +#include + +using namespace std; + +OBSPropertiesView::OBSPropertiesView(OBSData settings_, + obs_properties_t properties_, void *obj_, + PropertiesUpdateCallback callback_) + : QScrollArea (nullptr), + properties (properties_), + settings (settings_), + obj (obj_), + callback (callback_) +{ + widget = new QWidget(); + + QFormLayout *layout = new QFormLayout; + widget->setLayout(layout); + + QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Preferred); + widget->setSizePolicy(policy); + layout->setSizeConstraint(QLayout::SetMaximumSize); + layout->setLabelAlignment(Qt::AlignRight); + + obs_property_t property = obs_properties_first(properties); + + while (property) { + AddProperty(property, layout); + obs_property_next(&property); + } + + setWidget(widget); + setSizePolicy(policy); +} + +QWidget *OBSPropertiesView::NewWidget(obs_property_t prop, QWidget *widget, + const char *signal) +{ + WidgetInfo *info = new WidgetInfo(this, prop, widget); + connect(widget, signal, info, SLOT(ControlChanged())); + children.push_back(std::move(unique_ptr(info))); + return widget; +} + +QWidget *OBSPropertiesView::AddCheckbox(obs_property_t prop) +{ + const char *desc = obs_property_description(prop); + + return NewWidget(prop, new QCheckBox(QT_UTF8(desc)), + SIGNAL(stateChanged(int))); +} + +QWidget *OBSPropertiesView::AddText(obs_property_t prop) +{ + return NewWidget(prop, new QLineEdit(), + SIGNAL(textEdited(const QString &))); +} + +void OBSPropertiesView::AddPath(obs_property_t prop, QFormLayout *layout) +{ + /* TODO */ + UNUSED_PARAMETER(prop); + UNUSED_PARAMETER(layout); +} + +QWidget *OBSPropertiesView::AddInt(obs_property_t prop) +{ + QSpinBox *spin = new QSpinBox(); + spin->setMinimum(obs_property_int_min(prop)); + spin->setMaximum(obs_property_int_max(prop)); + spin->setSingleStep(obs_property_int_step(prop)); + + return NewWidget(prop, spin, SIGNAL(valueChanged(int))); +} + +QWidget *OBSPropertiesView::AddFloat(obs_property_t prop) +{ + QDoubleSpinBox *spin = new QDoubleSpinBox(); + spin->setMinimum(obs_property_float_min(prop)); + spin->setMaximum(obs_property_float_max(prop)); + spin->setSingleStep(obs_property_float_step(prop)); + + return NewWidget(prop, spin, SIGNAL(valueChanged(double))); +} + +QWidget *OBSPropertiesView::AddList(obs_property_t prop) +{ + QComboBox *combo = new QComboBox(); + obs_combo_type type = obs_property_list_type(prop); + size_t count = obs_property_list_item_count(prop); + + for (size_t i = 0; i < count; i++) { + const char *name = obs_property_list_item_name(prop, i); + const char *val = obs_property_list_item_value(prop, i); + combo->addItem(QT_UTF8(name), QT_UTF8(val)); + } + + if (type == OBS_COMBO_TYPE_EDITABLE) { + combo->setEditable(true); + return NewWidget(prop, combo, + SLOT(editTextChanged(const QString &))); + } + + return NewWidget(prop, combo, SIGNAL(currentIndexChanged(int))); +} + +void OBSPropertiesView::AddProperty(obs_property_t property, + QFormLayout *layout) +{ + obs_property_type type = obs_property_get_type(property); + + QWidget *widget = nullptr; + + switch (type) { + case OBS_PROPERTY_INVALID: + return; + case OBS_PROPERTY_BOOL: + widget = AddCheckbox(property); + break; + case OBS_PROPERTY_INT: + widget = AddInt(property); + break; + case OBS_PROPERTY_FLOAT: + widget = AddFloat(property); + break; + case OBS_PROPERTY_TEXT: + widget = AddText(property); + break; + case OBS_PROPERTY_PATH: + AddPath(property, layout); + break; + case OBS_PROPERTY_LIST: + widget = AddList(property); + break; + case OBS_PROPERTY_COLOR: + /* TODO */ + break; + } + + if (!widget) + return; + + QLabel *label = nullptr; + if (type != OBS_PROPERTY_BOOL) + label = new QLabel(QT_UTF8(obs_property_description(property))); + + layout->addRow(label, widget); +} + +void WidgetInfo::BoolChanged(const char *setting) +{ + QCheckBox *checkbox = static_cast(widget); + obs_data_setbool(view->settings, setting, + checkbox->checkState() == Qt::Checked); +} + +void WidgetInfo::IntChanged(const char *setting) +{ + QSpinBox *spin = static_cast(widget); + obs_data_setint(view->settings, setting, spin->value()); +} + +void WidgetInfo::FloatChanged(const char *setting) +{ + QDoubleSpinBox *spin = static_cast(widget); + obs_data_setdouble(view->settings, setting, spin->value()); +} + +void WidgetInfo::TextChanged(const char *setting) +{ + QLineEdit *edit = static_cast(widget); + obs_data_setstring(view->settings, setting, QT_TO_UTF8(edit->text())); +} + +void WidgetInfo::PathChanged(const char *setting) +{ + /* TODO */ + UNUSED_PARAMETER(setting); +} + +void WidgetInfo::ListChanged(const char *setting) +{ + QComboBox *combo = static_cast(widget); + obs_combo_format format = obs_property_list_format(property); + obs_combo_type type = obs_property_list_type(property); + + string val; + if (type == OBS_COMBO_TYPE_EDITABLE) { + val = QT_TO_UTF8(combo->currentText()); + } else { + int index = combo->currentIndex(); + if (index != -1) { + QVariant variant = combo->itemData(index); + val = QT_TO_UTF8(variant.toString()); + } + } + + switch (format) { + case OBS_COMBO_FORMAT_INVALID: + return; + case OBS_COMBO_FORMAT_INT: + obs_data_setint(view->settings, setting, stol(val)); + break; + case OBS_COMBO_FORMAT_FLOAT: + obs_data_setdouble(view->settings, setting, stod(val)); + break; + case OBS_COMBO_FORMAT_STRING: + obs_data_setstring(view->settings, setting, val.c_str()); + break; + } +} + +void WidgetInfo::ColorChanged(const char *setting) +{ + /* TODO */ + UNUSED_PARAMETER(setting); +} + +void WidgetInfo::ControlChanged() +{ + const char *setting = obs_property_name(property); + obs_property_type type = obs_property_get_type(property); + + switch (type) { + case OBS_PROPERTY_INVALID: return; + case OBS_PROPERTY_BOOL: BoolChanged(setting); break; + case OBS_PROPERTY_INT: IntChanged(setting); break; + case OBS_PROPERTY_FLOAT: FloatChanged(setting); break; + case OBS_PROPERTY_TEXT: TextChanged(setting); break; + case OBS_PROPERTY_PATH: PathChanged(setting); break; + case OBS_PROPERTY_LIST: ListChanged(setting); break; + case OBS_PROPERTY_COLOR: ColorChanged(setting); break; + } + + view->callback(view->obj, view->settings); +} diff --git a/obs/properties-view.hpp b/obs/properties-view.hpp new file mode 100644 index 000000000..c0d8d6730 --- /dev/null +++ b/obs/properties-view.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include + +class QFormLayout; +class OBSPropertiesView; + +typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t settings); + +/* ------------------------------------------------------------------------- */ + +class WidgetInfo : public QObject { + Q_OBJECT + +private: + OBSPropertiesView *view; + obs_property_t property; + QWidget *widget; + + void BoolChanged(const char *setting); + void IntChanged(const char *setting); + void FloatChanged(const char *setting); + void TextChanged(const char *setting); + void PathChanged(const char *setting); + void ListChanged(const char *setting); + void ColorChanged(const char *setting); + +public: + inline WidgetInfo(OBSPropertiesView *view_, obs_property_t prop, + QWidget *widget_) + : view(view_), property(prop), widget(widget_) + {} + +public slots: + void ControlChanged(); +}; + +/* ------------------------------------------------------------------------- */ + +class OBSPropertiesView : public QScrollArea { + Q_OBJECT + + friend class WidgetInfo; + +private: + QWidget *widget; + obs_properties_t properties; + OBSData settings; + void *obj; + PropertiesUpdateCallback callback; + std::vector> children; + + QWidget *NewWidget(obs_property_t prop, QWidget *widget, + const char *signal); + + QWidget *AddCheckbox(obs_property_t prop); + QWidget *AddText(obs_property_t prop); + void AddPath(obs_property_t prop, QFormLayout *layout); + QWidget *AddInt(obs_property_t prop); + QWidget *AddFloat(obs_property_t prop); + QWidget *AddList(obs_property_t prop); + + void AddProperty(obs_property_t property, QFormLayout *layout); + +public: + OBSPropertiesView(OBSData settings, + obs_properties_t properties, + void *obj, PropertiesUpdateCallback callback); + + inline ~OBSPropertiesView() + { + obs_properties_destroy(properties); + } +}; diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 5241d8f51..e50d58b93 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -29,7 +29,9 @@ #include "window-basic-settings.hpp" #include "window-namedialog.hpp" #include "window-basic-main.hpp" +#include "window-basic-properties.hpp" #include "qt-wrappers.hpp" +#include "display-helpers.hpp" #include "ui_OBSBasic.h" @@ -43,6 +45,7 @@ OBSBasic::OBSBasic(QWidget *parent) outputTest (NULL), sceneChanging (false), resizeTimer (0), + properties (nullptr), ui (new Ui::OBSBasic) { ui->setupUi(this); @@ -51,7 +54,7 @@ OBSBasic::OBSBasic(QWidget *parent) static inline bool HasAudioDevices(const char *source_id) { const char *output_id = source_id; - obs_properties_t props = obs_source_properties( + obs_properties_t props = obs_get_source_properties( OBS_SOURCE_TYPE_INPUT, output_id, App()->GetLocale()); size_t count = 0; @@ -182,6 +185,9 @@ void OBSBasic::OBSInit() OBSBasic::~OBSBasic() { + if (properties) + delete properties; + /* free the lists before shutting down to remove the scene/item * references */ ui->sources->clear(); @@ -499,26 +505,13 @@ void OBSBasic::ResetAudioDevices() void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy) { - double targetAspect, baseAspect; QSize targetSize; /* resize preview panel to fix to the top section of the window */ - targetSize = ui->preview->size(); - targetAspect = double(targetSize.width()) / double(targetSize.height()); - baseAspect = double(cx) / double(cy); - - if (targetAspect > baseAspect) { - previewScale = float(targetSize.height()) / float(cy); - cx = targetSize.height() * baseAspect; - cy = targetSize.height(); - } else { - previewScale = float(targetSize.width()) / float(cx); - cx = targetSize.width(); - cy = targetSize.width() / baseAspect; - } - - previewX = targetSize.width() /2 - cx/2; - previewY = targetSize.height()/2 - cy/2; + targetSize = ui->preview->size(); + GetScaleAndCenterPos(int(cx), int(cy), + targetSize.width(), targetSize.height(), + previewX, previewY, previewScale); if (isVisible()) { if (resizeTimer) @@ -769,6 +762,14 @@ void OBSBasic::on_actionRemoveSource_triggered() void OBSBasic::on_actionSourceProperties_triggered() { + OBSSceneItem item = GetCurrentSceneItem(); + OBSSource source = obs_sceneitem_getsource(item); + + if (source) { + delete properties; + properties = new OBSBasicProperties(this, source); + properties->Init(); + } } void OBSBasic::on_actionSourceUp_triggered() @@ -915,3 +916,8 @@ config_t OBSBasic::Config() const { return basicConfig; } + +void OBSBasic::UnloadProperties() +{ + properties = nullptr; +} diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index f551d10a2..7e8008779 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -21,6 +21,7 @@ #include #include #include "window-main.hpp" +#include "window-basic-properties.hpp" #include @@ -42,6 +43,8 @@ private: ConfigFile basicConfig; + OBSBasicProperties *properties; + void GetFPSCommon(uint32_t &num, uint32_t &den) const; void GetFPSInteger(uint32_t &num, uint32_t &den) const; void GetFPSFraction(uint32_t &num, uint32_t &den) const; @@ -93,6 +96,8 @@ public: void SaveProject(); void LoadProject(); + void UnloadProperties(); + protected: virtual void closeEvent(QCloseEvent *event) override; virtual void changeEvent(QEvent *event) override; diff --git a/obs/window-basic-properties.cpp b/obs/window-basic-properties.cpp new file mode 100644 index 000000000..ec00c6f08 --- /dev/null +++ b/obs/window-basic-properties.cpp @@ -0,0 +1,127 @@ +/****************************************************************************** + Copyright (C) 2014 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include "obs-app.hpp" +#include "window-basic-properties.hpp" +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" +#include "display-helpers.hpp" + +using namespace std; + +OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) + : QDialog (parent), + main (qobject_cast(parent)), + resizeTimer (0), + ui (new Ui::OBSBasicProperties), + source (source_), + removedSignal (obs_source_signalhandler(source), "remove", + OBSBasicProperties::SourceRemoved, this) +{ + setAttribute(Qt::WA_DeleteOnClose); + + ui->setupUi(this); + + OBSData settings = obs_source_getsettings(source); + obs_data_release(settings); + + view = new OBSPropertiesView(settings, + obs_source_properties(source, App()->GetLocale()), + source, (PropertiesUpdateCallback)obs_source_update); + + layout()->addWidget(view); + layout()->setAlignment(view, Qt::AlignRight); + view->show(); +} + +void OBSBasicProperties::SourceRemoved(void *data, calldata_t params) +{ + QMetaObject::invokeMethod(static_cast(data), + "close"); + + UNUSED_PARAMETER(params); +} + +void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) +{ + OBSBasicProperties *window = static_cast(data); + + if (!window->source) + return; + + uint32_t sourceCX = obs_source_getwidth(window->source); + uint32_t sourceCY = obs_source_getheight(window->source); + + int x, y; + float scale; + + GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); + + gs_matrix_push(); + gs_matrix_scale3f(scale, scale, 1.0f); + gs_matrix_translate3f(-x, -y, 0.0f); + obs_source_video_render(window->source); + gs_matrix_pop(); +} + +void OBSBasicProperties::closeEvent(QCloseEvent *event) +{ + main->UnloadProperties(); + UNUSED_PARAMETER(event); +} + +void OBSBasicProperties::resizeEvent(QResizeEvent *event) +{ + if (isVisible()) { + if (resizeTimer) + killTimer(resizeTimer); + resizeTimer = startTimer(100); + } + + UNUSED_PARAMETER(event); +} + +void OBSBasicProperties::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == resizeTimer) { + killTimer(resizeTimer); + resizeTimer = 0; + + QSize size = ui->preview->size(); + obs_display_resize(display, size.width(), size.height()); + } +} + +void OBSBasicProperties::Init() +{ + gs_init_data init_data = {}; + + show(); + App()->processEvents(); + + QSize previewSize = ui->preview->size(); + init_data.cx = uint32_t(previewSize.width()); + init_data.cy = uint32_t(previewSize.height()); + init_data.format = GS_RGBA; + QTToGSWindow(ui->preview->winId(), init_data.window); + + display = obs_display_create(&init_data); + + if (display) + obs_display_add_draw_callback(display, + OBSBasicProperties::DrawPreview, this); +} diff --git a/obs/window-basic-properties.hpp b/obs/window-basic-properties.hpp new file mode 100644 index 000000000..fd5d01cd2 --- /dev/null +++ b/obs/window-basic-properties.hpp @@ -0,0 +1,56 @@ +/****************************************************************************** + Copyright (C) 2014 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#pragma once + +#include +#include + +#include + +#include "properties-view.hpp" + +class OBSBasic; + +#include "ui_OBSBasicProperties.h" + +class OBSBasicProperties : public QDialog { + Q_OBJECT + +private: + OBSBasic *main; + int resizeTimer; + + std::unique_ptr ui; + OBSSource source; + OBSDisplay display; + OBSSignal removedSignal; + OBSPropertiesView *view; + + static void SourceRemoved(void *data, calldata_t params); + static void DrawPreview(void *data, uint32_t cx, uint32_t cy); + +public: + OBSBasicProperties(QWidget *parent, OBSSource source_); + + void Init(); + +protected: + virtual void closeEvent(QCloseEvent *event) override; + virtual void resizeEvent(QResizeEvent *event) override; + virtual void timerEvent(QTimerEvent *event) override; +}; diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index 7278245c7..ae53d690e 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -374,9 +374,9 @@ void OBSBasicSettings::LoadAudioDevices() const char *input_id = App()->InputAudioSource(); const char *output_id = App()->OutputAudioSource(); - obs_properties_t input_props = obs_source_properties( + obs_properties_t input_props = obs_get_source_properties( OBS_SOURCE_TYPE_INPUT, input_id, App()->GetLocale()); - obs_properties_t output_props = obs_source_properties( + obs_properties_t output_props = obs_get_source_properties( OBS_SOURCE_TYPE_INPUT, output_id, App()->GetLocale()); if (input_props) { diff --git a/plugins/win-capture/monitor-capture.c b/plugins/win-capture/monitor-capture.c index cd0287446..6363950f1 100644 --- a/plugins/win-capture/monitor-capture.c +++ b/plugins/win-capture/monitor-capture.c @@ -138,6 +138,18 @@ static void monitor_capture_render(void *data, effect_t effect) dc_capture_render(&capture->data, capture->opaque_effect); } +static uint32_t monitor_capture_width(void *data) +{ + struct monitor_capture *capture = data; + return capture->data.width; +} + +static uint32_t monitor_capture_height(void *data) +{ + struct monitor_capture *capture = data; + return capture->data.height; +} + struct obs_source_info monitor_capture_info = { .id = "monitor_capture", .type = OBS_SOURCE_TYPE_INPUT, @@ -145,6 +157,8 @@ struct obs_source_info monitor_capture_info = { .getname = monitor_capture_getname, .create = monitor_capture_create, .destroy = monitor_capture_destroy, + .getwidth = monitor_capture_width, + .getheight = monitor_capture_height, .defaults = monitor_capture_defaults, .video_render = monitor_capture_render, .video_tick = monitor_capture_tick diff --git a/plugins/win-wasapi/win-wasapi.cpp b/plugins/win-wasapi/win-wasapi.cpp index 81a19cdb2..b9ca54a6d 100644 --- a/plugins/win-wasapi/win-wasapi.cpp +++ b/plugins/win-wasapi/win-wasapi.cpp @@ -44,6 +44,8 @@ class WASAPISource { bool ProcessCaptureData(); + inline void Start(); + inline void Stop(); void Reconnect(); bool InitDevice(IMMDeviceEnumerator *enumerator); @@ -55,11 +57,13 @@ class WASAPISource { bool TryInitialize(); + void UpdateSettings(obs_data_t settings); + public: WASAPISource(obs_data_t settings, obs_source_t source_, bool input); inline ~WASAPISource(); - void UpdateSettings(obs_data_t settings); + void Update(obs_data_t settings); }; WASAPISource::WASAPISource(obs_data_t settings, obs_source_t source_, @@ -81,6 +85,11 @@ WASAPISource::WASAPISource(obs_data_t settings, obs_source_t source_, if (!receiveSignal.Valid()) throw "Could not create receive signal"; + Start(); +} + +inline void WASAPISource::Start() +{ if (!TryInitialize()) { blog(LOG_INFO, "[WASAPISource::WASAPISource] " "Device '%s' not found. Waiting for device", @@ -89,18 +98,25 @@ WASAPISource::WASAPISource(obs_data_t settings, obs_source_t source_, } } -inline WASAPISource::~WASAPISource() +inline void WASAPISource::Stop() { - if (active) - blog(LOG_INFO, "WASAPI: Device '%s' Terminated", - device_name.c_str()); - SetEvent(stopSignal); - if (active) + if (active) { + blog(LOG_INFO, "WASAPI: Device '%s' Terminated", + device_name.c_str()); WaitForSingleObject(captureThread, INFINITE); + } + if (reconnecting) WaitForSingleObject(reconnectThread, INFINITE); + + ResetEvent(stopSignal); +} + +inline WASAPISource::~WASAPISource() +{ + Stop(); } void WASAPISource::UpdateSettings(obs_data_t settings) @@ -110,6 +126,20 @@ void WASAPISource::UpdateSettings(obs_data_t settings) isDefaultDevice = _strcmpi(device_id.c_str(), "default") == 0; } +void WASAPISource::Update(obs_data_t settings) +{ + string newDevice = obs_data_getstring(settings, "device_id"); + bool restart = newDevice.compare(device_id) != 0; + + if (restart) + Stop(); + + UpdateSettings(settings); + + if (restart) + Start(); +} + bool WASAPISource::InitDevice(IMMDeviceEnumerator *enumerator) { HRESULT res; @@ -431,6 +461,11 @@ static void DestroyWASAPISource(void *obj) delete static_cast(obj); } +static void UpdateWASAPISource(void *obj, obs_data_t settings) +{ + static_cast(obj)->Update(settings); +} + static obs_properties_t GetWASAPIProperties(const char *locale, bool input) { obs_properties_t props = obs_properties_create(); @@ -477,6 +512,7 @@ void RegisterWASAPIInput() info.getname = GetWASAPIInputName; info.create = CreateWASAPIInput; info.destroy = DestroyWASAPISource; + info.update = UpdateWASAPISource; info.defaults = GetWASAPIDefaults; info.properties = GetWASAPIPropertiesInput; obs_register_source(&info); @@ -491,6 +527,7 @@ void RegisterWASAPIOutput() info.getname = GetWASAPIOutputName; info.create = CreateWASAPIOutput; info.destroy = DestroyWASAPISource; + info.update = UpdateWASAPISource; info.defaults = GetWASAPIDefaults; info.properties = GetWASAPIPropertiesOutput; obs_register_source(&info); diff --git a/vs/2013/obs-studio/obs-studio.vcxproj b/vs/2013/obs-studio/obs-studio.vcxproj index 06154bde6..573c9300a 100644 --- a/vs/2013/obs-studio/obs-studio.vcxproj +++ b/vs/2013/obs-studio/obs-studio.vcxproj @@ -20,6 +20,7 @@ + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -39,6 +40,24 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing properties-view.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing properties-view.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing properties-view.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing properties-view.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -94,8 +113,27 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing window-basic-properties.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing window-basic-properties.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing window-basic-properties.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing window-basic-properties.hpp... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\..\..\libobs" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I.\..\..\..\obs" + + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -137,14 +175,20 @@ + + true true + + true + true + true true @@ -153,6 +197,10 @@ true true + + true + true + true true @@ -179,6 +227,10 @@ true true + + true + true + true true @@ -187,6 +239,10 @@ true true + + true + true + true true @@ -354,6 +410,26 @@ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" + + + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" + + {B12702AD-ABFB-343A-A199-8E24837244A3} Qt4VSv1.0 diff --git a/vs/2013/obs-studio/obs-studio.vcxproj.filters b/vs/2013/obs-studio/obs-studio.vcxproj.filters index bb732c91b..fa7d69938 100644 --- a/vs/2013/obs-studio/obs-studio.vcxproj.filters +++ b/vs/2013/obs-studio/obs-studio.vcxproj.filters @@ -65,6 +65,15 @@ Header Files + + Form Files + + + Header Files + + + Header Files + @@ -85,6 +94,12 @@ Header Files + + Header Files + + + Generated Files + @@ -144,6 +159,24 @@ Generated Files\Release + + Source Files + + + Generated Files\Debug + + + Generated Files\Release + + + Generated Files\Debug + + + Generated Files\Release + + + Source Files +