]> git.sesse.net Git - nageru/commitdiff
Make signal mapping changeable by right-clicking on the preview.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 22 Jan 2016 00:43:20 +0000 (01:43 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 22 Jan 2016 00:43:20 +0000 (01:43 +0100)
bmusb
glwidget.cpp
glwidget.h
mixer.h
theme.cpp
theme.h
theme.lua

diff --git a/bmusb b/bmusb
index 4a275155fbd23690652c0478b12363d254f84e16..cd4dd0ed2eaf14fc50f0601295c821a41b603490 160000 (submodule)
--- a/bmusb
+++ b/bmusb
@@ -1 +1 @@
-Subproject commit 4a275155fbd23690652c0478b12363d254f84e16
+Subproject commit cd4dd0ed2eaf14fc50f0601295c821a41b603490
index 3d5b0f97abe86a494bedda4ee5607e14499a2be2..e71ac405721bf53d94fb3caffd05711ee8c17f06 100644 (file)
@@ -6,6 +6,8 @@
 #include <qevent.h>  // Needs to come before egl.h.
 #include <epoxy/gl.h>
 #include <epoxy/egl.h>
+#include <QAction>
+#include <QMenu>
 #include <QSurfaceFormat>
 #include <movit/resource_pool.h>
 
@@ -31,6 +33,7 @@ class QWidget;
 #include <string>
 
 using namespace std;
+using namespace std::placeholders;
 
 GLWidget::GLWidget(QWidget *parent)
     : QGLWidget(parent, global_share_widget)
@@ -59,6 +62,15 @@ void GLWidget::initializeGL()
                emit resolution_updated(output);
        });
 
+       if (output >= Mixer::OUTPUT_INPUT0) {
+               int signal_num = global_mixer->get_channel_signal(output);
+               if (signal_num != -1) {
+                       setContextMenuPolicy(Qt::CustomContextMenu);
+                       connect(this, &QWidget::customContextMenuRequested,
+                               bind(&GLWidget::show_context_menu, this, signal_num, _1));
+               }
+       }
+
        glDisable(GL_BLEND);
        glDisable(GL_DEPTH_TEST);
        glDepthMask(GL_FALSE);
@@ -99,3 +111,29 @@ void GLWidget::mousePressEvent(QMouseEvent *event)
 {
        emit clicked();
 }
+
+void GLWidget::show_context_menu(int signal_num, const QPoint &pos)
+{
+       QPoint global_pos = mapToGlobal(pos);
+
+       QMenu menu;
+       QActionGroup group(&menu);
+
+       unsigned num_cards = global_mixer->get_num_cards();
+       unsigned current_card = global_mixer->map_signal(signal_num);
+       for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
+               QString description(QString::fromStdString(global_mixer->get_card_description(card_index)));
+               QAction *action = new QAction(description, &group);
+               action->setCheckable(true);
+               if (current_card == card_index) {
+                       action->setChecked(true);
+               }
+               action->setData(card_index);
+               menu.addAction(action);
+       }
+       QAction *selected_item = menu.exec(global_pos);
+       if (selected_item) {
+               unsigned card_index = selected_item->data().toInt(nullptr);
+               global_mixer->set_signal_mapping(signal_num, card_index);
+       }
+}
index 857d733c42cf90e77ee51bf97aecdecea03d2231..ed5e48696ebf6f7bf606e86b9fb89f21db4b716b 100644 (file)
@@ -48,6 +48,9 @@ signals:
        void transition_names_updated(std::vector<std::string> transition_names);
        void resolution_updated(Mixer::Output output);
 
+private slots:
+       void show_context_menu(int signal_num, const QPoint &pos);
+
 private:
        Mixer::Output output;
        GLuint vao, program_num;
diff --git a/mixer.h b/mixer.h
index 3c1a952a81575ec80bfdb56f63252e0fdf4847e9..32e8168f64cc96a62c3cdc58a51d4773417c7e48 100644 (file)
--- a/mixer.h
+++ b/mixer.h
@@ -126,6 +126,21 @@ public:
                return theme->get_channel_name(channel);
        }
 
+       int get_channel_signal(unsigned channel) const
+       {
+               return theme->get_channel_signal(channel);
+       }
+
+       int map_signal(unsigned channel)
+       {
+               return theme->map_signal(channel);
+       }
+
+       void set_signal_mapping(int signal, int card)
+       {
+               return theme->set_signal_mapping(signal, card);
+       }
+
        bool get_supports_set_wb(unsigned channel) const
        {
                return theme->get_supports_set_wb(channel);
@@ -209,6 +224,13 @@ public:
 
        void reset_meters();
 
+       unsigned get_num_cards() const { return num_cards; }
+
+       std::string get_card_description(unsigned card_index) const {
+               assert(card_index < num_cards);
+               return cards[card_index].usb->get_description();
+       }
+
 private:
        void bm_frame(unsigned card_index, uint16_t timecode,
                FrameAllocator::Frame video_frame, size_t video_offset, uint16_t video_format,
index 3f387f81e3de2706b9d0c3c4c7ce3cddd00ff81b..0c74a8b88c76b1acdb0b779440371c7f51eef0c8 100644 (file)
--- a/theme.cpp
+++ b/theme.cpp
@@ -782,6 +782,22 @@ string Theme::get_channel_name(unsigned channel)
        return ret;
 }
 
+int Theme::get_channel_signal(unsigned channel)
+{
+       unique_lock<mutex> lock(m);
+       lua_getglobal(L, "channel_signal");
+       lua_pushnumber(L, channel);
+       if (lua_pcall(L, 1, 1, 0) != 0) {
+               fprintf(stderr, "error running function `channel_signal': %s\n", lua_tostring(L, -1));
+               exit(1);
+       }
+
+       int ret = luaL_checknumber(L, 1);
+       lua_pop(L, 1);
+       assert(lua_gettop(L) == 0);
+       return ret;
+}
+
 bool Theme::get_supports_set_wb(unsigned channel)
 {
        unique_lock<mutex> lock(m);
@@ -837,14 +853,23 @@ vector<string> Theme::get_transition_names(float t)
 
 int Theme::map_signal(int signal_num)
 {
+       unique_lock<mutex> lock(map_m);
+       if (signal_to_card_mapping.count(signal_num)) {
+               return signal_to_card_mapping[signal_num];
+       }
        if (signal_num >= int(num_cards)) {
-               if (signals_warned_about.insert(signal_num).second) {
-                       fprintf(stderr, "WARNING: Theme asked for input %d, but we only have %u card(s).\n", signal_num, num_cards);
-                       fprintf(stderr, "Mapping to card %d instead.\n", signal_num % num_cards);
-               }
-               signal_num %= num_cards;
+               fprintf(stderr, "WARNING: Theme asked for input %d, but we only have %u card(s).\n", signal_num, num_cards);
+               fprintf(stderr, "Mapping to card %d instead.\n", signal_num % num_cards);
        }
-       return signal_num;
+       signal_to_card_mapping[signal_num] = signal_num % num_cards;
+       return signal_num % num_cards;
+}
+
+void Theme::set_signal_mapping(int signal_num, int card_num)
+{
+       unique_lock<mutex> lock(map_m);
+       assert(card_num < int(num_cards));
+       signal_to_card_mapping[signal_num] = card_num;
 }
 
 void Theme::transition_clicked(int transition_num, float t)
diff --git a/theme.h b/theme.h
index 48039734a840f58f90924b514eeaaf27f1f61657..660a2cd7962024a767230bfb9c49735ed8bb94fd 100644 (file)
--- a/theme.h
+++ b/theme.h
@@ -54,7 +54,9 @@ public:
 
        int get_num_channels() const { return num_channels; }
        int map_signal(int signal_num);
+       void set_signal_mapping(int signal_num, int card_num);
        std::string get_channel_name(unsigned channel);
+       int get_channel_signal(unsigned channel);
        bool get_supports_set_wb(unsigned channel);
        void set_wb(unsigned channel, double r, double g, double b);
 
@@ -75,7 +77,9 @@ private:
        movit::ResourcePool *resource_pool;
        int num_channels;
        unsigned num_cards;
-       std::set<int> signals_warned_about;
+
+       std::mutex map_m;
+       std::map<int, int> signal_to_card_mapping;  // Protected by <map_m>.
 
        friend class LiveInputWrapper;
 };
index f561613aa88c33fd5dff538bd199122d7c425368..243b352670182c7bbd3c56dffe761bf32d5e268f 100644 (file)
--- a/theme.lua
+++ b/theme.lua
@@ -298,6 +298,21 @@ function channel_name(channel)
        end
 end
 
+-- API ENTRY POINT
+-- Returns, given a channel number, which signal it corresponds to (starting from 0).
+-- Should return -1 if the channel does not correspond to a simple signal.
+-- Called once for each channel, at the start of the program.
+-- Will never be called for live (0) or preview (1).
+function channel_signal(channel)
+       if channel == 2 then
+               return 0
+       elseif channel == 3 then
+               return 1
+       else
+               return -1
+       end
+end
+
 -- API ENTRY POINT
 -- Returns if a given channel supports setting white balance (starting from 2).
 -- Called only once for each channel, at the start of the program.