From 02ac4a169b4b39b41a947d03561035b92b9b2c8f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 6 May 2025 03:54:03 +0200 Subject: [PATCH] XV-Display: establish wiring for the controller and verify logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Here we face the problem that the buttons in the play control panel need to be connected to the controller, which sits in the viewer panel. Obviously a direct connection is not correct, since there could be several panels, and furthermore the controller should be a service and addressed by commands via UI-Bus. But this is an experiment, and we'll have to figure out anyway how the playback-display-connection works, as one of the next tasks for the »Playback Vertical Slice« Thus we'll use the PanelManager to fetch the first viewer panel, and then forward to the controller calls. With this setup, the controller logic can be verified by printing to STDOUT. TODO: we are not yet invoking any XVideo code.... --- src/stage/interact/interaction-director.cpp | 2 +- src/stage/model/element-access.hpp | 2 +- src/stage/panel/play-panel.cpp | 75 ++++++++++++++++--- src/stage/panel/play-panel.hpp | 29 +++++-- src/stage/panel/viewer-panel.cpp | 7 +- src/stage/panel/viewer-panel.hpp | 3 +- src/steam/engine/worker/tick-service.hpp | 17 +++-- wiki/thinkPad.ichthyo.mm | 83 ++++++++++++++++++--- 8 files changed, 175 insertions(+), 43 deletions(-) diff --git a/src/stage/interact/interaction-director.cpp b/src/stage/interact/interaction-director.cpp index 0153e18ad..a7df1b289 100644 --- a/src/stage/interact/interaction-director.cpp +++ b/src/stage/interact/interaction-director.cpp @@ -140,7 +140,7 @@ namespace interact { return injectTimeline (spec); })) .mutateAttrib(ATTR_fork, [&](TreeMutator::Handle buff) - { // »Attribute Mutator« : how enter an object field as nested scope + { // »Attribute Mutator« : how to enter an object field as nested scope REQUIRE (assets_); assets_->buildMutator(buff); })); diff --git a/src/stage/model/element-access.hpp b/src/stage/model/element-access.hpp index a8035c880..d9548c3e4 100644 --- a/src/stage/model/element-access.hpp +++ b/src/stage/model/element-access.hpp @@ -110,7 +110,7 @@ namespace model { * UI-Coordinates. Rather we have to deal with a small set of possible base interfaces, * and thus the actual [access function](\ref #performAccessTo) returns a _variant record_ * holding a pointer, and internally tagged with the base interface type to apply. Now the - * public API functions are templated to the _result type as expected by the invoking clinent_ + * public API functions are templated to the _result type as expected by the invoking client_ * and thus we get a matrix of possible cases; when the expected result type is _reachable by * dynamic downcast_ from the actual base interface type returned by the internal access function, * we can perform this `dynamic_cast`. Otherwise the returned result proxy object is marked as empty. diff --git a/src/stage/panel/play-panel.cpp b/src/stage/panel/play-panel.cpp index 5846c04ac..3cf2f2b27 100644 --- a/src/stage/panel/play-panel.cpp +++ b/src/stage/panel/play-panel.cpp @@ -1,8 +1,8 @@ /* - PlayPanel - Dockable panel to hold the video display widgets and controls + PlayPanel - Dockable panel to hold the play control and switchboard Copyright (C) - 2008, Joel Holdsworth + 2025, Hermann Vosseler   **Lumiera** is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the @@ -14,31 +14,41 @@ /** @file play-panel.cpp ** Implementation of a dockable panel for player control and timecode display + ** + ** @todo 5/2025 This is an experiment or demo to find out if our XV-Widget is still usable. + ** The actual solution obviously should not use a direct wired connection to the ViewerPanel, + ** but rather communicate with the »Player« subsystem down in Steam-Layer + ** ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1403 : try to port XvDisplayer to GTK-3 */ #include "stage/gtk-base.hpp" #include "stage/panel/play-panel.hpp" +#include "stage/panel/viewer-panel.hpp" #include "stage/workspace/workspace-window.hpp" #include "stage/ui-bus.hpp" ///////////////////////////////////TODO why are we forced to include this after workspace-window.hpp ?? Ambiguity between std::ref and boost::reference_wrapper #include "stage/display-service.hpp" -using namespace Gtk; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! -using namespace stage::widget; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! -using namespace stage::controller; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! - namespace stage { namespace panel { + using Gtk::StockID; + using sigc::mem_fun; + + PlayPanel::PlayPanel (workspace::PanelManager& panelManager - ,Gdl::DockItem& dockItem) + ,Gdl::DockItem& dockItem) : Panel{panelManager, dockItem, getTitle(), getStockID()} - , display_{} - , demoPlayback_{[this](void * const buffer){ display_.pushFrame(buffer); }} + , buttons_{} + , buttonStop_{StockID(GTK_STOCK_MEDIA_STOP)} + , buttonPlay_{StockID(GTK_STOCK_MEDIA_PLAY)} + , buttonPause_{StockID(GTK_STOCK_MEDIA_PAUSE)} ////////////////////////TICKET #1030 : Stock-items are deprecated and will be removed with GTK-4 { - //----- Pack in the Widgets -----// - pack_start(display_, PACK_EXPAND_WIDGET); + buttons_.append (buttonPlay_, mem_fun(*this, &PlayPanel::dispatchPlay)); + buttons_.append (buttonPause_, mem_fun(*this, &PlayPanel::dispatchPause)); + buttons_.append (buttonStop_, mem_fun(*this, &PlayPanel::dispatchStop)); + pack_start(buttons_, Gtk::PACK_SHRINK); } const char* @@ -54,4 +64,47 @@ namespace panel { } + /* === create an internal wiring to the Controller === */ + + // Preliminary workaround -- use a shortcut /////////////////////////////////////////////////////TICKET #1105 : need a generic scheme to access UI components + // Directly grab into the first ViewerPanel we can get hold off + // The real solution should use the UI-Bus! + + PlayPanel::ViewLink& + PlayPanel::accessViewer() + { + if (not viewer_) + { + int panelID = workspace::PanelManager::findPanelID(); + if (panelManager_.hasPanel (panelID)) + viewer_.connect (dynamic_cast (panelManager_.showPanel (panelID))); + } + return viewer_; + } + + void + PlayPanel::dispatchStop() + { + auto& view{accessViewer()}; + if (view) + view->demoPlayback_.stop(); + } + + void + PlayPanel::dispatchPlay() + { + auto& view{accessViewer()}; + if (view) + view->demoPlayback_.play(); + } + + void + PlayPanel::dispatchPause() + { + auto& view{accessViewer()}; + if (view) + view->demoPlayback_.pause(); + } + + }}// namespace stage::panel diff --git a/src/stage/panel/play-panel.hpp b/src/stage/panel/play-panel.hpp index 35102d46b..6f511d201 100644 --- a/src/stage/panel/play-panel.hpp +++ b/src/stage/panel/play-panel.hpp @@ -1,8 +1,8 @@ /* - VIEWER-PANEL.hpp - Dockable panel to hold the video display widgets and controls + PLAY-PANEL.hpp - Dockable panel to hold the play control and switchboard Copyright (C) - 2008, Joel Holdsworth + 2025, Hermann Vosseler   **Lumiera** is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the @@ -21,26 +21,41 @@ #include "stage/panel/panel.hpp" -#include "stage/widget/video-display-widget.hpp" -#include "stage/ctrl/demo-controller.hpp" +#include "stage/widget/button-bar.hpp" +#include "stage/model/w-link.hpp" namespace stage { namespace panel { + class ViewerPanel; + + /** - * A panel to display the video output. + * A »media player« panel. */ class PlayPanel : public Panel { - widget::VideoDisplayWidget display_; - ctrl::DemoController demoPlayback_; + widget::ButtonBar buttons_; + widget::MiniButton buttonStop_; + widget::MiniButton buttonPlay_; + widget::MiniButton buttonPause_; public: PlayPanel (workspace::PanelManager&, Gdl::DockItem&); static const char* getTitle(); static const gchar* getStockID(); + + private: + void dispatchStop(); + void dispatchPlay(); + void dispatchPause(); + + using ViewLink = model::WLink; + ViewLink viewer_; + + ViewLink& accessViewer(); }; }}// namespace stage::panel diff --git a/src/stage/panel/viewer-panel.cpp b/src/stage/panel/viewer-panel.cpp index 48bda5fcd..49a4916d3 100644 --- a/src/stage/panel/viewer-panel.cpp +++ b/src/stage/panel/viewer-panel.cpp @@ -3,6 +3,7 @@ Copyright (C) 2008, Joel Holdsworth + 2025, Hermann Vosseler   **Lumiera** is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the @@ -24,10 +25,6 @@ #include "stage/display-service.hpp" -using namespace Gtk; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! -using namespace stage::widget; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! -using namespace stage::controller; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please! - namespace stage { namespace panel { @@ -38,7 +35,7 @@ namespace panel { , demoPlayback_{[this](void * const buffer){ display_.pushFrame(buffer); }} { //----- Pack in the Widgets -----// - pack_start(display_, PACK_EXPAND_WIDGET); + pack_start(display_, Gtk::PACK_EXPAND_WIDGET); } const char* diff --git a/src/stage/panel/viewer-panel.hpp b/src/stage/panel/viewer-panel.hpp index 02b1cadae..8efc3fcba 100644 --- a/src/stage/panel/viewer-panel.hpp +++ b/src/stage/panel/viewer-panel.hpp @@ -34,13 +34,14 @@ namespace panel { : public Panel { widget::VideoDisplayWidget display_; - ctrl::DemoController demoPlayback_; public: ViewerPanel (workspace::PanelManager&, Gdl::DockItem&); static const char* getTitle(); static const gchar* getStockID(); + + ctrl::DemoController demoPlayback_; }; }}// namespace stage::panel diff --git a/src/steam/engine/worker/tick-service.hpp b/src/steam/engine/worker/tick-service.hpp index 6fc94af51..0bbf5d674 100644 --- a/src/steam/engine/worker/tick-service.hpp +++ b/src/steam/engine/worker/tick-service.hpp @@ -36,6 +36,7 @@ #include #include +#include namespace steam { @@ -54,16 +55,17 @@ namespace node { : lib::ThreadJoinable<> { typedef function Tick; - volatile uint timespan_; + std::atomic_uint timespan_; /** poll interval for new settings in wait state */ - static const uint POLL_TIMEOUT = 1000; + static const uint POLL_TIMEOUT = 10000; public: TickService (Tick callback) : ThreadJoinable("Tick generator (dummy)" , bind (&TickService::timerLoop, this, callback) ) + , timespan_{POLL_TIMEOUT} { INFO (steam, "TickService started."); } @@ -71,8 +73,8 @@ namespace node { ~TickService () { timespan_ = 0; - auto res = this->join(); - WARN_IF (res, steam, "Failure in TickService"); + if (not this->join()) + WARN (steam, "Failure in TickService"); usleep (200000); // additional delay allowing GTK to dispatch the last output INFO (steam, "TickService shutdown."); @@ -99,15 +101,16 @@ namespace node { private: void timerLoop(Tick periodicFun) { - timespan_ = POLL_TIMEOUT; - while (0 < timespan_) + do { if (timespan_ > POLL_TIMEOUT) periodicFun(); usleep (timespan_); } - TRACE (proc_dbg, "Tick Thread timer loop exiting..."); + while (timespan_); //(possible yet very unlikely race with ctor) + // + TRACE (proc_dbg, "Tick Thread timer loop exiting..."); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 139cbfcdc..7540c9f14 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -129779,7 +129779,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + + @@ -129795,8 +129796,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + @@ -129807,7 +129808,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129852,8 +129853,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) Ausgangspunkt sind verschiedene Icons für Musik-Player, die eine stilisierte Compact-Kasette zeigen. Das bringt mich auf die Idee, auf die Steenbeck-Schneidemaschinen anzuspielen, mit den großen Rollen, bzw. auf eine Magnetton-Maschine ... und dann könnte man ein »Playhead« aus einem »Play/Pause«-Symbol erzeugen

- - +
@@ -129916,8 +129916,72 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
- - + + + + + + + + + + + + + + + + + + +

+ siehe InteractionDirector::injectTimeline() +

+ +
+
+ + + + + + + + + + + + + + + + + + +

+ ist aber leider nicht implementiert... +

+ +
+
+
+ + + + + + + + + + + + + + + + +
@@ -157880,8 +157944,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo Das ist essentiell; gute Icons zeichnen ist eine Kunst

- - +