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

- - +