@@ -76,6 +76,14 @@ namespace djv
7676 std::shared_ptr<ftk::Label> infoLabel;
7777 std::shared_ptr<ftk::Label> renderLabel;
7878 std::map<models::HUDItem, std::shared_ptr<ftk::IWidget> > hudWidgets;
79+ // ! What is being compared, and how many images arrived for it: a
80+ // ! comparison with no B file draws black, which four different
81+ // ! things all look like.
82+ tl::Compare compare = tl::Compare::A;
83+ std::shared_ptr<models::FilesModelItem> a;
84+ std::vector<std::shared_ptr<models::FilesModelItem> > b;
85+ std::shared_ptr<ftk::Label> compareLabel;
86+
7987 bool toastActive = false ;
8088 std::shared_ptr<ftk::Label> toastLabel;
8189 std::shared_ptr<ftk::Timer> toastTimer;
@@ -88,6 +96,8 @@ namespace djv
8896 std::shared_ptr<ftk::Observer<tl::PlayerCacheInfo> > cacheObserver;
8997 std::shared_ptr<ftk::Observer<double > > fpsObserver;
9098 std::shared_ptr<ftk::Observer<size_t > > droppedFramesObserver;
99+ std::shared_ptr<ftk::Observer<std::shared_ptr<models::FilesModelItem> > > aObserver;
100+ std::shared_ptr<ftk::ListObserver<std::shared_ptr<models::FilesModelItem> > > bObserver;
91101 std::shared_ptr<ftk::Observer<tl::CompareOptions> > compareOptionsObserver;
92102 std::shared_ptr<ftk::Observer<tl::OCIOOptions> > ocioOptionsObserver;
93103 std::shared_ptr<ftk::Observer<tl::LUTOptions> > lutOptionsObserver;
@@ -192,6 +202,11 @@ namespace djv
192202 p.hudLayouts [models::HUDPos::BottomLeft]->setVAlign (ftk::VAlign::Bottom);
193203 p.hudLayouts [models::HUDPos::BottomRight]->setVAlign (ftk::VAlign::Bottom);
194204
205+ p.compareLabel = ftk::Label::create (context);
206+ p.compareLabel ->setMarginRole (ftk::SizeRole::MarginSmall);
207+ p.compareLabel ->setBackgroundRole (ftk::ColorRole::Overlay);
208+ p.compareLabel ->setVisible (false );
209+
195210 p.toastLabel = ftk::Label::create (context);
196211 p.toastLabel ->setMarginRole (ftk::SizeRole::MarginSmall);
197212 p.toastLabel ->setBackgroundRole (ftk::ColorRole::Overlay);
@@ -211,6 +226,19 @@ namespace djv
211226 context, ftk::Orientation::Vertical, p.hudLayout );
212227 spacer->setStretch (ftk::Stretch::Expanding);
213228
229+ auto noBLayout = ftk::HorizontalLayout::create (context, p.hudLayout );
230+ noBLayout->setVAlign (ftk::VAlign::Center);
231+ spacer = ftk::Spacer::create (
232+ context, ftk::Orientation::Horizontal, noBLayout);
233+ spacer->setStretch (ftk::Stretch::Expanding);
234+ p.compareLabel ->setParent (noBLayout);
235+ spacer = ftk::Spacer::create (
236+ context, ftk::Orientation::Horizontal, noBLayout);
237+ spacer->setStretch (ftk::Stretch::Expanding);
238+ spacer = ftk::Spacer::create (
239+ context, ftk::Orientation::Vertical, p.hudLayout );
240+ spacer->setStretch (ftk::Stretch::Expanding);
241+
214242 auto bottomLayout = ftk::VerticalLayout::create (context, p.hudLayout );
215243 bottomLayout->setSpacingRole (ftk::SizeRole::SpacingSmall);
216244 auto toastLayout = ftk::HorizontalLayout::create (context, bottomLayout);
@@ -248,11 +276,29 @@ namespace djv
248276 _hudUpdate ();
249277 });
250278
279+ p.aObserver = ftk::Observer<std::shared_ptr<models::FilesModelItem> >::create (
280+ app->getFilesModel ()->observeA (),
281+ [this ](const std::shared_ptr<models::FilesModelItem>& value)
282+ {
283+ _p->a = value;
284+ _compareUpdate ();
285+ });
286+
287+ p.bObserver = ftk::ListObserver<std::shared_ptr<models::FilesModelItem> >::create (
288+ app->getFilesModel ()->observeB (),
289+ [this ](const std::vector<std::shared_ptr<models::FilesModelItem> >& value)
290+ {
291+ _p->b = value;
292+ _compareUpdate ();
293+ });
294+
251295 p.compareOptionsObserver = ftk::Observer<tl::CompareOptions>::create (
252296 app->getFilesModel ()->observeCompareOptions (),
253297 [this ](const tl::CompareOptions& value)
254298 {
299+ _p->compare = value.compare ;
255300 setCompareOptions (value);
301+ _compareUpdate ();
256302 });
257303
258304 p.ocioOptionsObserver = ftk::Observer<tl::OCIOOptions>::create (
@@ -539,6 +585,7 @@ namespace djv
539585 {
540586 FTK_P ();
541587 p.videoFramesSize = value.size ();
588+ _compareUpdate ();
542589 p.missing = false ;
543590 p.heldFrom .reset ();
544591 // The first source, which is the one the time in the
@@ -709,6 +756,43 @@ namespace djv
709756 setDisplayOptions (displayOptionsList);
710757 }
711758
759+ void Viewport::_compareUpdate ()
760+ {
761+ FTK_P ();
762+ // Everything but A needs a B file that is not the A file. Neither
763+ // draws anything, and an empty picture is the one thing a black
764+ // frame, an unreadable file and a comparison out of sync all look
765+ // like as well.
766+ std::string s;
767+ if (p.compare != tl::Compare::A)
768+ {
769+ if (p.videoFramesSize < 2 )
770+ {
771+ s = " No B file selected" ;
772+ }
773+ else if (p.a && !p.b .empty ())
774+ {
775+ // Only when there is nothing else in B: a file compared
776+ // with itself alongside others still has something to
777+ // show.
778+ const bool allA = std::all_of (
779+ p.b .begin (),
780+ p.b .end (),
781+ [this ](const std::shared_ptr<models::FilesModelItem>& i)
782+ {
783+ return i == _p->a ;
784+ });
785+ if (allA)
786+ {
787+ s = " A and B are the same file" ;
788+ }
789+ }
790+ }
791+ p.compareLabel ->setText (s);
792+ p.compareLabel ->setVisible (!s.empty ());
793+ ftk::setScreenshotTag (p.compareLabel , !s.empty () ? " View.Compare" : " " );
794+ }
795+
712796 void Viewport::_hudUpdate ()
713797 {
714798 FTK_P ();
0 commit comments