Button moving after page refresh
Hi
Thanks for your awesome framework
I have customized the Wt::WPushButton widget as follows:
class RegisterBtn : public Wt::WPushButton
{
public:
RegisterBtn() :
Wt::WPushButton (Wt::WString::tr("button.register.text"))
{
resize(Wt::WLength(175, Wt::LengthUnit::Pixel), Wt::WLength(60, Wt::LengthUnit::Pixel));
decorationStyle().setBackgroundColor(Wt::WColor("#c76639"));
setAttributeValue("style",
"font-family: arial;"
"font-size: 40px;"
"font-weight: normal;"
"border-radius: 10px;"
"cursor: pointer;");
auto authWidget = dynamic_cast<myApp*>(Wt::WApplication::instance())->authWidget();
clicked().connect([=](){
authWidget->registerNewUser();
});
authWidget->login().changed().connect([=](){
setHidden(authWidget->login().loggedIn());
});
setHidden(authWidget->login().loggedIn());
}
};
and added it to the page as follows:
class HeroSection : public Wt::WContainerWidget {
public:
HeroSection(Wt::LayoutDirection dir)
{
setObjectName ("HeroSection");
setHeight (Wt::WLength (heightMax_));
setMaximumSize (Wt::WLength (widthMax_, Wt::LengthUnit::Pixel), Wt::WLength (heightMax_, Wt::LengthUnit::Pixel));
setMargin (Wt::WLength::Auto, Wt::Side::Right | Wt::Side::Left);
setStyleClass ("hero");
auto mainLayout = setLayout(std::make_unique<Wt::WVBoxLayout>());
mainLayout->setSpacing (0);
mainLayout->setContentsMargins (13, 0, 13, 0);
auto middleBox = mainLayout->addWidget<Wt::WContainerWidget>(std::make_unique<Wt::WContainerWidget>());
auto bottomBox = mainLayout->addWidget<Wt::WContainerWidget>(std::make_unique<Wt::WContainerWidget>());
middleBox->setHeight(Wt::WLength(50, Wt::LengthUnit::Percentage));
bottomBox->setHeight(Wt::WLength(50, Wt::LengthUnit::Percentage));
auto middleLayout = middleBox->setLayout<Wt::WVBoxLayout>(std::make_unique<Wt::WVBoxLayout>());
auto middleContents = middleLayout->addLayout<Wt::WVBoxLayout>(std::make_unique<Wt::WVBoxLayout>(), 1, Wt::AlignmentFlag::Bottom);
//Add some Text to middleContents
bottomBox->setObjectName ("bottomBox");
auto bottomLayout = bottomBox->setLayout<Wt::WVBoxLayout>(std::make_unique<Wt::WVBoxLayout>());
auto bottomContents = bottomLayout->addLayout<Wt::WVBoxLayout>(std::make_unique<Wt::WVBoxLayout>(), 1, Wt::AlignmentFlag::Top);
bottomContents->setObjectName ("bottomContent");
bottomContents->setSpacing (50);
text = bottomContents->addWidget<Wt::WText> (std::make_unique<Wt::WText>(), 1, Wt::AlignmentFlag::Center);
text->setText("bla bla");
text->setAttributeValue ("style",
"font-size: 24px;"
"font-weight: bold;"
"text-shadow: 3px 0px 3px #fff, -3px 0px 3px #fff, 0px 3px 3px #fff, 0px -3px 3px #fff;"
"opacity: 0.75;"
);
bottomContents->addWidget<RegisterBtn>(std::make_unique<RegisterBtn>(), 0, Wt::AlignmentFlag::Center);
}
~HeroSection(){};
private:
static constexpr int widthMax_{1200};
static constexpr int heightMax_{725};
};
I have also used the Introduction to Wt::Auth tutorial and added the authentication feature to the application. I have created the authWidget widget in the main class and used it in different parts of the application:
myApp.cpp:
class myApp : public Wt::WApplication
{
private:
/* data */
Session session_;
Wt::WStackedWidget* body_;
Wt::Auth::AuthWidget *authWidget_;
void internalPathHandler (void)
{
if (internalPath() == "/home") body_->setCurrentIndex (0);
else if (internalPath() == "/login") body_->setCurrentIndex (1);
}
public:
myApp (const Wt::WEnvironment &env): Wt::WApplication(env), session_("testDB")
{
setInternalPath("/home");
setLocale (Wt::WLocale ("fa"), false);
setLayoutDirection (Wt::LayoutDirection::RightToLeft);
//Set theme and add resources
auto authWidget = std::make_unique<Wt::Auth::AuthWidget>(Session::auth(), session_.users(), session_.login());
authWidget_ = authWidget.get();
authWidget_->model()->addPasswordAuth(&Session::passwordAuth());
authWidget_->model()->addOAuth(Session::oAuth());
authWidget_->setRegistrationEnabled(true);
authWidget_->processEnvironment();
root()->addNew<navigationBar>(layoutDirection()); //There two buttons, one to redirect to login page and another to logout.
body_ = root()->addNew<Wt::WStackedWidget>();
root()->addNew<footerSection>(layoutDirection());
body_->addWidget<HomePage>(std::make_unique<HomePage>(layoutDirection())); //HeroSection is a part of HomePage
body_->addNew<Login>(std::move(authWidget), layoutDirection());
session_.login().changed().connect([=](){
if (session_.login().loggedIn())
{
Wt::WApplication::setInternalPath("/home", true);
}
});
internalPathHandler();
internalPathChanged().connect([=](){
internalPathHandler();
});
}
virtual ~myApp(){};
Wt::Auth::AuthWidget* authWidget() { return authWidget_; }
};
Login.cpp
class Login : public Wt::WContainerWidget
{
public:
Login (std::unique_ptr<Wt::Auth::AuthWidget> authWidget, Wt::LayoutDirection direction)
{
resize (Wt::WLength (100, Wt::LengthUnit::Percentage),
Wt::WLength (725, Wt::LengthUnit::Pixel));
auto centerLayout = setLayout (std::make_unique<Wt::WVBoxLayout>());
auto forumBackground = centerLayout->addWidget<Wt::WContainerWidget>(std::make_unique<Wt::WContainerWidget>(), 0, Wt::AlignmentFlag::Middle);
forumBackground->resize (Wt::WLength (575, Wt::LengthUnit::Pixel), Wt::WLength (520, Wt::LengthUnit::Pixel));
forumBackground->setMargin (Wt::WLength::Auto, Wt::Side::Left | Wt::Side::Right);
forumBackground->decorationStyle().setBackgroundColor (Wt::WColor(255, 255, 255, (255 * 0.2)));
auto mainLayout = forumBackground->setLayout<Wt::WVBoxLayout>(std::make_unique<Wt::WVBoxLayout>());
mainLayout->setContentsMargins (0, 22, 0, 22);
mainLayout->addWidget (std::move(authWidget), 0, Wt::AlignmentFlag::Middle);
}
~Login ();
};
As it is clear in the codes, the button is horizontally centered. The problem is as follows:
When we log in, the homepage page is displayed and the button is hidden. If we log out without refreshing the page, the button will appear in the correct place, but if we refresh the page after logging in and then log out, the button will be displayed on the right side of the page. Of course, if we refresh again, the button will be moved to the center.
Thanks
Replies (1)
RE: Button moving after page refresh - Added by Matthias Van Ceulebroeck about 12 hours ago
Hey Ali,
I tried running your example, and had to fill in a couple of items that were missing. The main part being the navigation bar (which may be the cause of the behavior you see).
I filled it in like:
navigationbar.cppnavigationbar.cpp
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
class NavigationBar : public Wt::WContainerWidget
{
private:
Wt::WPushButton* login_;
Wt::WPushButton* logout_;
public:
NavigationBar(Wt::LayoutDirection dir)
{
auto mainLayout = setLayout(std::make_unique<Wt::WVBoxLayout>());
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(13, 0, 13, 0);
login_ = mainLayout->addWidget(std::make_unique<Wt::WPushButton>("Login"));
logout_ = mainLayout->addWidget(std::make_unique<Wt::WPushButton>("Logout"));
login_->setHeight(Wt::WLength(50, Wt::LengthUnit::Pixel));
logout_->setHeight(Wt::WLength(50, Wt::LengthUnit::Pixel));
login_->clicked().connect([this] {
Wt::WApplication::instance()->setInternalPath("/login", true);
});
logout_->clicked().connect([this] {
dynamic_cast<myApp*>(Wt::WApplication::instance())->authWidget()->login().logout();
});
}
I do not see the behavior you describe. So I suspect your logout/redirect mechanism may differ. Can you share this code?
Best,
Matthias