-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
frontend: Replace add source dropdown with dialog #12067
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
0c8caa9 to
370391e
Compare
|
Testing on Ubuntu 24.04,
one visual bug : |
4c4c9e7 to
f08d92b
Compare
80e620b to
2501fb3
Compare
08da97b to
5bf01aa
Compare
3e0730e to
abddce3
Compare
348d8f2 to
b738ffd
Compare
|
This has been updated with a bunch of cleanup and optimizations by @Lain-B. It is ready for proper testing and review now |
b738ffd to
4d25de7
Compare
PatTheMav
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First very superficial review, the Singleton pattern in the ThumbnailManager is an issue and appears at first glance like a responsibility inversion, will have to analyse this more deeply first.
There a few Qt-isms and C-isms that should use modern C++ style instead.
fb6ec34 to
b5e91c7
Compare
b5e91c7 to
3a82155
Compare
3a82155 to
62a8220
Compare
Co-Authored-By: Lain <[email protected]>
62a8220 to
515b431
Compare
|
Pushed some final cleanup as separate commits to make review of those changes easier. As far as I am concerned, this PR is now ready for merge pending final code review. |
PatTheMav
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I noticed is that the text input box to create a new source does not have input focus automatically.
At least in my first attempts at using the new dialog, I didn't understand that this was indeed a text input field. Styling-wise it seemed like a label to me and it was only by clicking into it (and thus getting keyboard focus including a text input cursor) that I understood that I could type in it.
Some interfaces work around this discoverability problem by giving the input box a blinking text cursor, thereby suggesting "you can/should type something in here".
This probably only makes sense when no existing source of the same type is available, because you'd have no choice but to create the first one of that type. For accessibility reasons the text input probably should not have automatic focus if any existing source is available for selection, which only leaves with the input box being visually too generic to be identified as such.
| std::string typeId = type.toStdString(); | ||
| const char *unversionedId = typeId.c_str(); | ||
|
|
||
| if (strcmp(id, window->id) == 0) | ||
| window->ui->sourceList->addItem(QT_UTF8(name)); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source) | ||
| { | ||
| OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect *>(data); | ||
| const char *name = obs_source_get_name(source); | ||
| const char *id = obs_source_get_unversioned_id(source); | ||
|
|
||
| if (strcmp(id, window->id) == 0) { | ||
| OBSBasic *main = OBSBasic::Get(); | ||
| OBSScene scene = main->GetCurrentScene(); | ||
|
|
||
| obs_sceneitem_t *existing = obs_scene_get_group(scene, name); | ||
| if (!existing) | ||
| window->ui->sourceList->addItem(QT_UTF8(name)); | ||
| if (strcmp(unversionedId, "scene") == 0) { | ||
| return Str("Basic.Scene"); | ||
| } | ||
|
|
||
| return true; | ||
| const char *id = obs_get_latest_input_type_id(unversionedId); | ||
| return obs_source_get_display_name(id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| std::string typeId = type.toStdString(); | |
| const char *unversionedId = typeId.c_str(); | |
| if (strcmp(id, window->id) == 0) | |
| window->ui->sourceList->addItem(QT_UTF8(name)); | |
| return true; | |
| } | |
| bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source) | |
| { | |
| OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect *>(data); | |
| const char *name = obs_source_get_name(source); | |
| const char *id = obs_source_get_unversioned_id(source); | |
| if (strcmp(id, window->id) == 0) { | |
| OBSBasic *main = OBSBasic::Get(); | |
| OBSScene scene = main->GetCurrentScene(); | |
| obs_sceneitem_t *existing = obs_scene_get_group(scene, name); | |
| if (!existing) | |
| window->ui->sourceList->addItem(QT_UTF8(name)); | |
| if (strcmp(unversionedId, "scene") == 0) { | |
| return Str("Basic.Scene"); | |
| } | |
| return true; | |
| const char *id = obs_get_latest_input_type_id(unversionedId); | |
| return obs_source_get_display_name(id); | |
| if (type == "scene") { | |
| return Str("Basic.Scene"); | |
| } | |
| std::string unversionedId{type.toUtf8().constData()}; | |
| std::string_view inputTypeId = obs_get_latest_input_type_id(unversionedId.c_str()); | |
| std::string_view displayId = obs_source_get_display_name(inputTypeId.data()); | |
| if (displayId) { | |
| return displayId.data(); | |
| } else { | |
| return nullptr; | |
| } |
As this is a C++ implementation, I'd prefer if this also leans into C++ functionality:
QStringcan do comparisons against an (implicitly UTF-8 encoded) string constant, so we can use that directly (and don't need to reach down to lower level C viastrcmp).std::string(at least in C++17, with C++20 and more recent we should then usestd::u8string) then takes ownership of the temporary UTF-8 string Qt will generate from its internal UTF-16 variant (if nothing "owns" the data returned byconstData(), it will be deallocated once the temporary goes out of scope).- After that
std::string_viewis used as a C++ container for the data allocated bylibobs(avoiding copies). - Finally the underlying
const char *pointer created byobs_source_get_display_nameis returned.
Note that this also requires handling the fail condition (either libobs library call returning nullptr) necessary and thus makes it explicit that the function itself can (and will) return a nullptr itself (so callers need to be able to handle that as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just checked the C++ docs a bit more and it might be that the function can even be changed to return std::string_view directly as it will automatically be converted into const char*, std::string, or std::string_view depending on the caller's needs.
It still obfuscates that the string is owned by libobs (and was created by obs_source_get_display_name) and needs to be manually freed at some point, but that's C libraries for ya.
|
|
||
| if (!items.count()) | ||
| return; | ||
| dstr_printf(&new_name, format, name, ++inc + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually I'd prefer if this function would use C++ string types rather than lower-level C code, however C++17 does not have good built-in string formatting options and I'd like to think that using a printf-like variant here will be more readable than a bunch of std::string-style append operations.
| #include <functional> | ||
| #include <deque> | ||
|
|
||
| class ThumbnailItem : public QObject { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ii ThumbnailItem a "public" object (i.e. used by other code then ThumbnailManager?
Same question about the Thumbnail class?
| static constexpr int cx = 320; | ||
| static constexpr int cy = 180; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why this doesn't use a size type like QSize or OBS::Rect that makes it clear that these are indeed not 2 independent values but have a combined meaning?
|
Another thing I noticed is that deprecated source types like "Window Capture" and "Desktop Capture" are presented as bona-fide source types and are neither displayed with lower priority in the left-hand list, nor do they retain a deprecation marker. |
5c8532e to
6bea4f1
Compare
|
Fixed the above visual issues
I toyed with this idea, but since the items are multi-selectable and can be unselected by clicking, double clicking was a bit confusing.
I aimed to distinguish it with the lack of an icon. Adding a separator is also non-trivial due to how simplistic QListWidgets are heh |
Can confirm, also did a round of all themes to check for other visual issues, found none.
While I agree it is a visual distinction, it does, in my opinion, make it stand out less, as the eye is naturally drawn to the icons as "markers" of the list. Without the presence of such a marker, the "Recently added" does not impart that it is a list item at first sight.
Would it be possible to make it not be the same list but in a separate one(that's what I had in mind in the mockup), or not a list item at all, but still behave like one? |
RytoEX
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure that new code complies with #12567.







Description
Replaces the add source context menu with a brand new window.
Adds new FlowFrame and FlowLayout for automatic wrapping widget frame
Adds ThumbnailManager class
Adds new dialog for adding sources
Sources Dock Menu
New Window
obs64_E0SOtuhy93.mp4
Motivation and Context
The current process for adding a source is rather cumbersome, especially when adding a source that already exists. Ideally users should be re-using Sources whenever it makes sense, so one of the goals of this PR is exposing that better than the old radio button and list selection.
How Has This Been Tested?
Created a number of different sources.
Types of changes
Checklist: