Files
dota_factory/src/ui/MessageDialog.h
Malte Langkabel 9b88deff69 give the escape menu and the name prompts the game's own frame
The last dialogs wearing system chrome were the three QMessageBoxes -- the
escape menu, the game-over and win screens -- and the two QInputDialogs that
name a blueprint. They are the ones the player meets at the sharpest moments
of a run, and they looked like alerts from the operating system.

MessageDialog and NameInputDialog replace them on the layer. The message
dialog names its buttons by the index addButton hands back and reports which
was clicked, with Escape standing for a button the caller nominates rather
than for a dismissal of its own -- Continue in the escape menu, as it was
explicitly set to before, and Quit on the two state screens, which is where
the reject role sent it. Neither dialog takes Q or a click outside: every
button is a decision, and a half-typed name is work in progress
(REQ-UI-DIALOG-DISMISS).

Two things the layer needed for the nested case: it now tracks the scroll
area each modal is shown in, so a modal opened with no anchor centers on the
one it was opened from rather than on the window -- which is where the
Create Blueprint prompt belongs (REQ-UI-PANEL-MODAL) -- and findFor() walks
a widget's parents to the layer, so the blueprint panel buried in the layout
dialog can open a modal without every widget in between carrying a pointer.

The three error boxes stay system dialogs on purpose: config load, config
reload, and blueprint file load all report a failure that may leave nothing
to draw on (REQ-UI-MODAL-CHROME).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
2026-08-18 12:14:31 +02:00

51 lines
1.7 KiB
C++

#pragma once
#include <optional>
#include <vector>
#include <QString>
#include "ModalDialog.h"
class QHBoxLayout;
class QLabel;
// The game's own message box (REQ-UI-MODAL-CHROME): a title, an optional line or two of
// text, and a row of buttons the caller names. It stands in for QMessageBox at the three
// places the player is asked to decide something -- the escape menu (REQ-UI-GAME-MENU)
// and the game-over and win screens (REQ-HQ-GAME-OVER, REQ-WIN-SCREEN) -- so that those
// read as part of the game rather than as system alerts.
//
// The caller identifies buttons by the index addButton() hands back, and asks
// getClickedButtonIndex() afterwards; the QDialog result code says only whether a button
// was clicked at all. Q and a click outside do not dismiss it: every button here is a
// decision, and there is no "no change" among them to fall back on.
class MessageDialog : public ModalDialog
{
Q_OBJECT
public:
// text may be empty, for a dialog that is a question its buttons already state.
MessageDialog(const QString& title, const QString& text, QWidget* parent = nullptr);
// Appends a button and returns its index, left to right.
int addButton(const QString& caption);
// Which button Escape stands for. Without one, Escape does nothing -- a dialog whose
// buttons all commit to something has no dismissal to offer.
void setEscapeButtonIndex(int index);
std::optional<int> getClickedButtonIndex() const;
public slots:
void reject() override;
private:
void onButtonClicked(int index);
QHBoxLayout* m_buttonLayout;
int m_buttonCount;
std::optional<int> m_escapeButtonIndex;
std::optional<int> m_clickedButtonIndex;
};