Fix various dialog box issues

- Better vertical positioning (account for word wrapping)
- Better horizontal positioning (consider both right and left gaps for
calculating available width).
- Prevent vertical text overflow.
This commit is contained in:
Alexander Batalov 2022-12-29 13:02:59 +03:00
parent 248d6dfb92
commit 5922d15b1c
1 changed files with 51 additions and 25 deletions

View File

@ -415,81 +415,107 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
fontSetCurrent(101); fontSetCurrent(101);
int v23 = _ytable[dialogType]; int nextY = _ytable[dialogType];
int maxY = _ytable[dialogType] + _dblines[dialogType] * fontGetLineHeight();
if ((flags & DIALOG_BOX_NO_VERTICAL_CENTERING) == 0) { if ((flags & DIALOG_BOX_NO_VERTICAL_CENTERING) == 0) {
int v41 = _dblines[dialogType] * fontGetLineHeight() / 2 + v23; int numberOfLines = 0;
v23 = v41 - ((bodyLength + 1) * fontGetLineHeight() / 2);
if (hasTitle) {
numberOfLines++;
}
for (int index = 0; index < bodyLength; index++) {
short beginnings[WORD_WRAP_MAX_COUNT];
short subLineCount;
int maxWidth = backgroundFrmImage.getWidth() - _xtable[dialogType] * 2;
if (wordWrap(body[index], maxWidth, beginnings, &subLineCount) == 0) {
numberOfLines += subLineCount - 1;
}
}
if (numberOfLines > _dblines[dialogType]) {
numberOfLines = _dblines[dialogType];
}
nextY += (_dblines[dialogType] - numberOfLines) * fontGetLineHeight() / 2;
} }
if (hasTitle) { if (hasTitle) {
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) { if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType], fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + _xtable[dialogType],
title, title,
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
titleColor); titleColor);
} else { } else {
int length = fontGetStringWidth(title); int length = fontGetStringWidth(title);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2, fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + (backgroundFrmImage.getWidth() - length) / 2,
title, title,
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
titleColor); titleColor);
} }
v23 += fontGetLineHeight(); nextY += fontGetLineHeight();
} }
for (int v94 = 0; v94 < bodyLength; v94++) { for (int index = 0; index < bodyLength && nextY < maxY; index++) {
int len = fontGetStringWidth(body[v94]); int width = fontGetStringWidth(body[index]);
if (len <= backgroundFrmImage.getWidth() - 26) { int maxWidth = backgroundFrmImage.getWidth() - _xtable[dialogType] * 2;
if (width <= maxWidth) {
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) { if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType], fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + _xtable[dialogType],
body[v94], body[index],
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
bodyColor); bodyColor);
} else { } else {
int length = fontGetStringWidth(body[v94]); int length = fontGetStringWidth(body[index]);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2, fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + (backgroundFrmImage.getWidth() - length) / 2,
body[v94], body[index],
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
bodyColor); bodyColor);
} }
v23 += fontGetLineHeight(); nextY += fontGetLineHeight();
} else { } else {
short beginnings[WORD_WRAP_MAX_COUNT]; short beginnings[WORD_WRAP_MAX_COUNT];
short count; short count;
if (wordWrap(body[v94], backgroundFrmImage.getWidth() - 26, beginnings, &count) != 0) { if (wordWrap(body[index], maxWidth, beginnings, &count) != 0) {
debugPrint("\nError: dialog_out"); debugPrint("\nError: dialog_out");
} }
for (int v48 = 1; v48 < count; v48++) { for (int beginningIndex = 1; beginningIndex < count && nextY < maxY; beginningIndex++) {
int v51 = beginnings[v48] - beginnings[v48 - 1]; int subLineLength = beginnings[beginningIndex] - beginnings[beginningIndex - 1];
if (v51 >= 260) { if (subLineLength >= 260) {
v51 = 259; subLineLength = 259;
} }
char string[260]; char string[260];
strncpy(string, body[v94] + beginnings[v48 - 1], v51); strncpy(string, body[index] + beginnings[beginningIndex - 1], subLineLength);
string[v51] = '\0'; string[subLineLength] = '\0';
// Remove trailing space as it affects width calculation.
if (subLineLength > 0 && string[subLineLength - 1] == ' ') {
string[subLineLength - 1] = '\0';
subLineLength -= 1;
}
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) { if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType], fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + _xtable[dialogType],
string, string,
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
bodyColor); bodyColor);
} else { } else {
int length = fontGetStringWidth(string); int length = fontGetStringWidth(string);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2, fontDrawText(windowBuf + backgroundFrmImage.getWidth() * nextY + (backgroundFrmImage.getWidth() - length) / 2,
string, string,
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(),
bodyColor); bodyColor);
} }
v23 += fontGetLineHeight(); nextY += fontGetLineHeight();
} }
} }
} }