Browse Source

Fixes for positioning on popups with components

Ivan Savenko 1 năm trước cách đây
mục cha
commit
99cb1df91d

+ 1 - 1
client/lobby/OptionsTab.cpp

@@ -374,7 +374,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genTownWindow()
 		if(!elem.empty())
 			components.push_back(std::make_shared<CComponent>(ComponentType::CREATURE, elem.front(), std::nullopt, CComponent::tiny));
 	}
-	boxAssociatedCreatures = std::make_shared<CComponentBox>(components, Rect(10, 140, pos.w - 20, 140));
+	boxAssociatedCreatures = std::make_shared<CComponentBox>(components, Rect(10, 140, pos.w - 20, 140), 20, 10, 22, 4);
 }
 
 void OptionsTab::CPlayerOptionTooltipBox::genHeroWindow()

+ 1 - 0
client/widgets/CComponent.cpp

@@ -427,6 +427,7 @@ void CComponentBox::placeComponents(bool selectable)
 	for(auto & comp : components)
 	{
 		addChild(comp.get());
+		comp->recActions = defActions; //FIXME: for some reason, received component might have recActions set to 0
 		comp->moveTo(Point(pos.x, pos.y));
 	}
 

+ 1 - 1
client/widgets/CComponent.h

@@ -92,7 +92,7 @@ class CComponentBox : public CIntObject
 	std::shared_ptr<CSelectableComponent> selected;
 	std::function<void(int newID)> onSelect;
 
-	static constexpr int defaultBetweenImagesMin = 20;
+	static constexpr int defaultBetweenImagesMin = 42;
 	static constexpr int defaultBetweenSubtitlesMin = 10;
 	static constexpr int defaultBetweenRows = 22;
 	static constexpr int defaultComponentsInRow = 4;

+ 0 - 3
client/widgets/TextControls.cpp

@@ -374,9 +374,6 @@ void CTextBox::trimToFit()
 	if (slider)
 		return;
 
-	if(label->alignment == ETextAlignment::CENTER)
-		moveBy((pos.dimensions() - label->textSize) / 2);
-
 	pos.w = label->textSize.x;
 	pos.h = label->textSize.y;
 	label->pos.w = label->textSize.x;

+ 53 - 37
client/windows/CMessage.cpp

@@ -27,6 +27,7 @@
 #include "../widgets/TextControls.h"
 #include "../windows/InfoWindows.h"
 
+constexpr int RIGHT_CLICK_POPUP_MIN_SIZE = 100;
 constexpr int BEFORE_COMPONENTS = 30;
 constexpr int SIDE_MARGIN = 11;
 constexpr int TOP_MARGIN = 20;
@@ -220,6 +221,8 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, PlayerColor play
 
 	assert(ret && ret->text);
 
+	// STEP 1: DETERMINE SIZE OF ALL ELEMENTS
+
 	for(const auto & area : textAreaSizes)
 	{
 		ret->text->resize(area);
@@ -227,70 +230,83 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, PlayerColor play
 			break; // suitable size found, use it
 	}
 
+//	int textWidth = ret->text->pos.w;
+	int textHeight = ret->text->pos.h;
+
 	if(ret->text->slider)
 		ret->text->slider->addUsedEvents(CIntObject::WHEEL | CIntObject::KEYBOARD);
 
-	Point winSize(ret->text->pos.w, ret->text->pos.h); //start with text size
-
-	if(ret->components)
-		winSize.y += 10 + ret->components->pos.h; //space to first component
-
 	int buttonsWidth = 0;
-	if(ret->buttons.size())
+	int buttonsHeight = 0;
+	if(!ret->buttons.empty())
 	{
-		int bh = 0;
 		// Compute total width of buttons
 		buttonsWidth = INTERVAL_BETWEEN_BUTTONS * (ret->buttons.size() - 1); // space between all buttons
 		for(auto & elem : ret->buttons) //and add buttons width
 		{
 			buttonsWidth += elem->pos.w;
-			vstd::amax(bh, elem->pos.h);
+			vstd::amax(buttonsHeight, elem->pos.h);
 		}
-		winSize.y += INTERVAL_BETWEEN_TEXT_AND_BUTTONS + bh; //before button + button
 	}
 
-	// Clip window size
-	if(ret->components)
-		vstd::amax(winSize.x, ret->components->pos.w);
-	vstd::amax(winSize.x, buttonsWidth);
+	// STEP 2: COMPUTE WINDOW SIZE
 
-	vstd::amin(winSize.x, GH.screenDimensions().x);
-	vstd::amin(winSize.y, GH.screenDimensions().y);
+	if(ret->buttons.empty() && !ret->components)
+	{
+		// use more compact form for right-click popup with no buttons / components
 
-	ret->pos.h = winSize.y + TOP_MARGIN + BOTTOM_MARGIN;
-	ret->pos.w = winSize.x + 2 * SIDE_MARGIN;
-	ret->center();
+		ret->pos.w = std::max(RIGHT_CLICK_POPUP_MIN_SIZE, ret->text->label->textSize.x + 2 * SIDE_MARGIN);
+		ret->pos.h = std::max(RIGHT_CLICK_POPUP_MIN_SIZE, ret->text->label->textSize.y + TOP_MARGIN + BOTTOM_MARGIN);
+	}
+	else
+	{
+		int windowContentWidth = ret->text->pos.w;
+		int windowContentHeight = ret->text->pos.h;
+		if(ret->components)
+		{
+			vstd::amax(windowContentWidth, ret->components->pos.w);
+			windowContentHeight += INTERVAL_BETWEEN_TEXT_AND_BUTTONS + ret->components->pos.h;
+		}
+		if(!ret->buttons.empty())
+		{
+			vstd::amax(windowContentWidth, buttonsWidth);
+			windowContentHeight += INTERVAL_BETWEEN_TEXT_AND_BUTTONS + buttonsHeight;
+		}
+
+		ret->pos.w = windowContentWidth + 2 * SIDE_MARGIN;
+		ret->pos.h = windowContentHeight + TOP_MARGIN + BOTTOM_MARGIN;
+	}
 
-	Point marginTopLeft(SIDE_MARGIN, TOP_MARGIN);
-	ret->text->moveBy(marginTopLeft);
-	ret->text->trimToFit();
+	// STEP 3: MOVE ALL ELEMENTS IN PLACE
 
 	if(ret->buttons.empty() && !ret->components)
 	{
-		//improvement for text only right-click popups -> center text
-		Point distance = ret->pos.topLeft() - ret->text->pos.topLeft() + marginTopLeft;
-		ret->text->moveBy(distance);
-
-		ret->pos.h = ret->text->pos.h + TOP_MARGIN + BOTTOM_MARGIN;
-		ret->pos.w = ret->text->pos.w + 2 * SIDE_MARGIN;
+		ret->text->trimToFit();
+		ret->text->center(ret->pos.center());
 	}
-
-	if(!ret->buttons.empty())
+	else
 	{
-		int buttonPosX = ret->pos.w / 2 - buttonsWidth / 2;
-		int buttonPosY = ret->pos.h - BOTTOM_MARGIN - ret->buttons[0]->pos.h;
+		if(ret->components)
+			ret->components->moveBy(Point((ret->pos.w - ret->components->pos.w) / 2, TOP_MARGIN + ret->text->pos.h + INTERVAL_BETWEEN_TEXT_AND_BUTTONS));
 
-		for(auto & elem : ret->buttons)
+		ret->text->trimToFit();
+		ret->text->moveBy(Point((ret->pos.w - ret->text->pos.w) / 2, TOP_MARGIN + (textHeight - ret->text->pos.h) / 2 ));
+
+		if(!ret->buttons.empty())
 		{
-			elem->moveBy(Point(buttonPosX, buttonPosY));
-			buttonPosX += elem->pos.w + INTERVAL_BETWEEN_BUTTONS;
+			int buttonPosX = ret->pos.w / 2 - buttonsWidth / 2;
+			int buttonPosY = ret->pos.h - BOTTOM_MARGIN - ret->buttons[0]->pos.h;
+
+			for(auto & elem : ret->buttons)
+			{
+				elem->moveBy(Point(buttonPosX, buttonPosY));
+				buttonPosX += elem->pos.w + INTERVAL_BETWEEN_BUTTONS;
+			}
 		}
 	}
 
-	if(ret->components)
-		ret->components->moveBy(Point(ret->pos.x, ret->pos.y));
-
 	ret->backgroundTexture->pos = ret->pos;
+	ret->center();
 }
 
 void CMessage::drawBorder(PlayerColor playerColor, Canvas & to, int w, int h, int x, int y)

+ 2 - 2
client/windows/InfoWindows.cpp

@@ -69,7 +69,7 @@ CSelWindow::CSelWindow( const std::string & Text, PlayerColor player, int charpe
 	}
 
 	if(!comps.empty())
-		components = std::make_shared<CComponentBox>(comps, Rect(0, 0, 600, 300));
+		components = std::make_shared<CComponentBox>(comps, Rect(0,0,0,0));
 
 	CMessage::drawIWindow(this, Text, player);
 }
@@ -124,7 +124,7 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
 	}
 
 	if(!comps.empty())
-		components = std::make_shared<CComponentBox>(comps, Rect(0, 0, 600, 300));
+		components = std::make_shared<CComponentBox>(comps, Rect(0,0,0,0));
 
 	CMessage::drawIWindow(this, Text, player);
 }