/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "boxes/abstract_box.h" #include "ui/wrap/vertical_layout.h" #include namespace st { extern const style::margins &boxRowPadding; } // namespace st class GenericBox : public BoxContent { public: // InitMethod::operator()(not_null box, InitArgs...) // init(box, args...) template < typename InitMethod, typename ...InitArgs, typename = decltype(std::declval>()( std::declval>(), std::declval>()...))> GenericBox( QWidget*, InitMethod &&init, InitArgs &&...args); void setWidth(int width) { _width = width; } void setFocusCallback(Fn callback) { _focus = callback; } int rowsCount() const { return _content->count(); } template < typename Widget, typename = std::enable_if_t< std::is_base_of_v>> Widget *insertRow( int atPosition, object_ptr &&child, const style::margins &margin = st::boxRowPadding) { return _content->insert( atPosition, std::move(child), margin); } template < typename Widget, typename = std::enable_if_t< std::is_base_of_v>> Widget *addRow( object_ptr &&child, const style::margins &margin = st::boxRowPadding) { return _content->add(std::move(child), margin); } void addSkip(int height); void setInnerFocus() override { if (_focus) { _focus(); } } protected: void prepare() override; private: template struct Initer { template < typename OtherMethod, typename ...OtherArgs, typename = std::enable_if_t< std::is_constructible_v>> Initer(OtherMethod &&method, OtherArgs &&...args); void operator()(not_null box); template void call( not_null box, std::index_sequence); InitMethod method; std::tuple args; }; template auto MakeIniter(InitMethod &&method, InitArgs &&...args) -> Initer, std::decay_t...>; FnMut)> _init; Fn _focus; object_ptr _content; int _width = 0; }; template template GenericBox::Initer::Initer( OtherMethod &&method, OtherArgs &&...args) : method(std::forward(method)) , args(std::forward(args)...) { } template inline void GenericBox::Initer::operator()( not_null box) { call(box, std::make_index_sequence()); } template template inline void GenericBox::Initer::call( not_null box, std::index_sequence) { std::invoke(method, box, std::get(args)...); } template inline auto GenericBox::MakeIniter(InitMethod &&method, InitArgs &&...args) -> Initer, std::decay_t...> { return { std::forward(method), std::forward(args)... }; } template inline GenericBox::GenericBox( QWidget*, InitMethod &&init, InitArgs &&...args) : _init( MakeIniter( std::forward(init), std::forward(args)...)) , _content(this) { }