#include "StdAfx.h" #include "ScrollbarWidget.h" #include "SlotConnectable.h" #include "WebApp.h" #include "DC.h" #include "../Bfx.Abstract.Engine/Import.Begin.h" #include "../Bfx.Abstract.Model.PrintEngine/Utilities/ImageFileUtilities.h" #include "../Bfx.Abstract.Interpreter/IsInFunction.h" #include "../Bfx.Abstract.Engine/Import.End.h" #include #include #include using namespace std; using namespace boost; using namespace boost::assign; using namespace BitFactory; using namespace BitFactory::UI::Web; using namespace BitFactory::UI::Architecture; Pixel::Scalar BitFactory::UI::Web::Scrollbar() { return Pixel::Scalar( 22 ); } class ScrollbarWidget::Impl : public SlotConnectable { Wt::JSlot myScrollJS; Wt::JSignal< int > myScrolled; int myScrolledOffset; String myOrientation; Wt::WContainerWidget* myC; ScrollbarWidget* mySelf; public: Impl( const ScrollbarWidget* self ) : mySelf( const_cast< ScrollbarWidget* >( self ) ) , myScrolled( this, "scrolled" ) , myScrolledOffset( 0 ) { myScrolled.connect( SLOT( this, Impl::Scrolled ) ); } void Init( const String& orientation, const std::vector< Wt::WWidget* >& toScroll ) { myOrientation = orientation; mySelf->addWidget( myC = new Wt::WContainerWidget ); String js = "function(obj, event) {"; foreach_auto( w, toScroll ) js += "$('#" + w->id() + "').scroll" + myOrientation + "(obj.scroll" + myOrientation + ");"; js += myScrolled.createCall( "obj.scroll" + myOrientation ) + ";"; js += "}"; myScrollJS.setJavaScript( js ); mySelf->scrolled().connect( myScrollJS ); } void ResizeImpl( const Pixel::Size& viewed, const Pixel::Size& all ) { mySelf->resize( viewed.Width().Get(), viewed.Height().Get() ); myC->resize( all.Width().Get(), all.Height().Get() ); } void Scrolled( int offset ) { myScrolledOffset = offset; } int Offset() { return myScrolledOffset; } void ScrollTo( int pos ) { GetWebApp()->doJavaScript( mySelf->jsRef() + ".scroll" + myOrientation + " += " + to_string( pos ) ); } }; X_PIMPL_IMPLEMENTATION( ScrollbarWidget ) ScrollbarWidget::ScrollbarWidget( const String& orientation, const std::vector< Wt::WWidget* >& toScroll, Wt::WContainerWidget* p ) : Wt::WContainerWidget( p ) { GetPimpl()->Init( orientation, toScroll ); } Pixel::Scalar ScrollbarWidget::GetScrollOffset() const { return Pixel::Scalar( GetPimpl()->Offset() ); } void ScrollbarWidget::ResizeImpl( const Pixel::Size& viewed, const Pixel::Size& all ) { GetPimpl()->ResizeImpl( viewed, all ); } void ScrollbarWidget::ScrollTo( const Pixel::Scalar& position ) { GetPimpl()->ScrollTo( position.Get() ); } HScrollbarWidget::HScrollbarWidget( const std::vector< Wt::WWidget* >& toScroll, Wt::WContainerWidget* p ) : ScrollbarWidget( "Left", toScroll, p ) { foreach_auto( w, toScroll ) GetWidgetParent< AbsolutePositionContainerBase >( w )->SetHorizontalScrollbar( this ); setOverflow( Wt::WContainerWidget::OverflowScroll, Wt::Horizontal ); setOverflow( Wt::WContainerWidget::OverflowHidden, Wt::Vertical ); } void HScrollbarWidget::Resize( const Pixel::Scalar& viewed, const Pixel::Scalar& all ) { ResizeImpl( Pixel::Size( viewed, Scrollbar() ), Pixel::Size( all, 1 ) ); } VScrollbarWidget::VScrollbarWidget( const std::vector< Wt::WWidget* >& toScroll, Wt::WContainerWidget* p ) : ScrollbarWidget( "Top", toScroll, p ) { foreach_auto( w, toScroll ) { GetWidgetParent< AbsolutePositionContainerBase >( w )->SetVerticalScrollbar( this ); if( auto interact = dynamic_cast< Wt::WInteractWidget* >( w ) ) interact->mouseWheel().connect( [&]( const Wt::WMouseEvent& e ) { ScrollTo( Pixel::Scalar( -10 * e.wheelDelta() ) ); }); } setOverflow( Wt::WContainerWidget::OverflowHidden, Wt::Horizontal ); setOverflow( Wt::WContainerWidget::OverflowScroll, Wt::Vertical ); } void VScrollbarWidget::Resize( const Pixel::Scalar& viewed, const Pixel::Scalar& all ) { ResizeImpl( Pixel::Size( Scrollbar(), viewed ), Pixel::Size( 1, all ) ); }