GRAPHICS: MACGUI: Draw title on ninepatch borders

This commit is contained in:
djsrv 2020-08-05 19:17:08 -04:00
parent 74f0434d42
commit c29ccaa0bb
6 changed files with 117 additions and 58 deletions

View file

@ -40,31 +40,28 @@ namespace Graphics {
struct BorderName {
byte type;
const char *name;
int lo;
int ro;
int to;
int bo;
BorderOffsets offsets;
};
static const BorderName borders[] = {
{0x00, "StandardClose", 1, 2, 19, 2},
{0x01, "ThickNoTitle", 5, 5, 5, 5},
{0x02, "ThinNoTitle", 1, 1, 1, 1},
{0x03, "ThinNoTitleShadow", 1, 3, 1, 3},
{0x04, "StandardClose", 1, 2, 19, 2},
{0x05, "Thick", 5, 5, 20, 5},
{0x06, "ThinNoTitle", 1, 1, 1, 1},
{0x07, "ThinNoTitleShadow", 1, 3, 1, 3},
{0x08, "StandardCloseZoom", 1, 2, 19, 2},
{0x09, "ThickZoom", 5, 5, 20, 5},
{0x0A, "ThinNoTitle", 1, 1, 1, 1},
{0x0B, "ThinNoTitleShadow", 1, 3, 1, 3},
{0x0C, "StandardCloseZoom", 1, 2, 19, 2},
{0x0D, "ThickZoom", 5, 5, 20, 5},
{0x0E, "ThinNoTitle", 1, 1, 1, 1},
{0x0F, "ThinNoTitleShadow", 1, 3, 1, 3},
{0x10, "RoundClose", 1, 1, 19, 6},
{0xFF, "No type", -1, -1, -1, -1}
{0x00, "StandardClose", 1, 2, 19, 2, 2, 2, false},
{0x01, "ThickNoTitle", 5, 5, 5, 5, -1, -1, false},
{0x02, "ThinNoTitle", 1, 1, 1, 1, -1, -1, false},
{0x03, "ThinNoTitleShadow", 1, 3, 1, 3, -1, -1, false},
{0x04, "StandardClose", 1, 2, 19, 2, 2, 2, false},
{0x05, "Thick", 5, 5, 20, 5, 2, 3, false},
{0x06, "ThinNoTitle", 1, 1, 1, 1, -1, -1, false},
{0x07, "ThinNoTitleShadow", 1, 3, 1, 3, -1, -1, false},
{0x08, "StandardCloseZoom", 1, 2, 19, 2, 2, 2, false},
{0x09, "ThickZoom", 5, 5, 20, 5, 2, 3, false},
{0x0A, "ThinNoTitle", 1, 1, 1, 1, -1, -1, false},
{0x0B, "ThinNoTitleShadow", 1, 3, 1, 3, -1, -1, false},
{0x0C, "StandardCloseZoom", 1, 2, 19, 2, 2, 2, false},
{0x0D, "ThickZoom", 5, 5, 20, 5, 2, 3, false},
{0x0E, "ThinNoTitle", 1, 1, 1, 1, -1, -1, false},
{0x0F, "ThinNoTitleShadow", 1, 3, 1, 3, -1, -1, false},
{0x10, "RoundClose", 1, 1, 19, 6, 1, 1, true},
{0xFF, "No type", -1, -1, -1, -1, -1, -1, false}
};
Common::String windowTypeName(byte windowType) {
@ -85,20 +82,14 @@ void MacWindowManager::loadDataBundle() {
}
}
Common::Rect MacWindowManager::getBorderOffsets(byte windowType) {
BorderOffsets MacWindowManager::getBorderOffsets(byte windowType) {
int i = 0;
while (borders[i].type != 0xFF) {
if (borders[i].type == windowType) {
Common::Rect offsets;
offsets.left = borders[i].lo;
offsets.right = borders[i].ro;
offsets.top = borders[i].to;
offsets.bottom = borders[i].bo;
return offsets;
}
if (borders[i].type == windowType)
break;
i++;
}
return Common::Rect(-1, -1, -1, -1);
return borders[i].offsets;
}
Common::SeekableReadStream *MacWindowManager::getBorderFile(byte windowType, bool isActive) {

View file

@ -232,11 +232,42 @@ void MacWindow::drawBorder() {
_borderIsDirty = false;
ManagedSurface *g = &_borderSurface;
int width = _borderSurface.w;
int titleColor;
int titleY;
int titleHeight;
int sidesWidth;
if (_macBorder.hasBorder(_active)) {
drawBorderFromSurface(g);
titleColor = _macBorder.getOffset().dark ? _wm->_colorWhite : _wm->_colorBlack;
titleY = _macBorder.getOffset().titleTop;
titleHeight = _macBorder.getOffset().top - titleY - _macBorder.getOffset().titleBottom;
sidesWidth = _macBorder.getOffset().left + _macBorder.getOffset().right;
} else {
drawSimpleBorder(g);
titleColor = _wm->_colorBlack;
titleY = 0;
titleHeight = _borderWidth;
sidesWidth = _borderWidth * 2;
}
if (_titleVisible && !_title.empty()) {
const Graphics::Font *font = getTitleFont();
int yOff = _wm->_fontMan->hasBuiltInFonts() ? 3 : 1;
int w = font->getStringWidth(_title) + 10;
int maxWidth = width - sidesWidth * 2 - 7;
if (w > maxWidth)
w = maxWidth;
if (_macBorder.hasBorder(_active)) {
if (!_macBorder.getOffset().dark)
fillRect(g, (width - w) / 2, titleY, w, titleHeight, _wm->_colorOffWhite);
} else {
drawBox(g, (width - w) / 2, titleY, w, titleHeight);
}
font->drawString(g, _title, (width - w) / 2 + 5, titleY + yOff, w, titleColor);
}
}
@ -260,8 +291,7 @@ void MacWindow::drawBorderFromSurface(ManagedSurface *g) {
}
void MacWindow::drawSimpleBorder(ManagedSurface *g) {
bool active = _active, scrollable = _scrollable, closeable = _active, drawTitle = _titleVisible && !_title.empty();
bool active = _active, scrollable = _scrollable, closeable = _active;
const int size = kBorderWidth;
int x = 0;
int y = 0;
@ -321,18 +351,6 @@ void MacWindow::drawSimpleBorder(ManagedSurface *g) {
}
}
}
if (drawTitle) {
const Graphics::Font *font = getTitleFont();
int yOff = _wm->_fontMan->hasBuiltInFonts() ? 3 : 1;
int w = font->getStringWidth(_title) + 10;
int maxWidth = width - size * 2 - 7;
if (w > maxWidth)
w = maxWidth;
drawBox(g, x + (width - w) / 2, y, w, size);
font->drawString(g, _title, x + (width - w) / 2 + 5, y + yOff, w, _wm->_colorBlack);
}
}
void MacWindow::drawPattern() {
@ -366,6 +384,18 @@ void MacWindow::setScroll(float scrollPos, float scrollSize) {
}
void MacWindow::loadBorder(Common::SeekableReadStream &file, bool active, int lo, int ro, int to, int bo) {
BorderOffsets offsets;
offsets.left = lo;
offsets.right = ro;
offsets.top = to;
offsets.bottom = bo;
offsets.titleTop = -1;
offsets.titleBottom = -1;
offsets.dark = false;
loadBorder(file, active, offsets);
}
void MacWindow::loadBorder(Common::SeekableReadStream &file, bool active, BorderOffsets offsets) {
Image::BitmapDecoder bmpDecoder;
Graphics::Surface *source;
Graphics::TransparentSurface *surface = new Graphics::TransparentSurface();
@ -379,10 +409,22 @@ void MacWindow::loadBorder(Common::SeekableReadStream &file, bool active, int lo
source->free();
delete source;
setBorder(surface, active, lo, ro, to, bo);
setBorder(surface, active, offsets);
}
void MacWindow::setBorder(Graphics::TransparentSurface *surface, bool active, int lo, int ro, int to, int bo) {
BorderOffsets offsets;
offsets.left = lo;
offsets.right = ro;
offsets.top = to;
offsets.bottom = bo;
offsets.titleTop = -1;
offsets.titleBottom = -1;
offsets.dark = false;
setBorder(surface, active, offsets);
}
void MacWindow::setBorder(Graphics::TransparentSurface *surface, bool active, BorderOffsets offsets) {
surface->applyColorKey(255, 0, 255, false);
if (active)
@ -390,8 +432,8 @@ void MacWindow::setBorder(Graphics::TransparentSurface *surface, bool active, in
else
_macBorder.addInactiveBorder(surface);
if (lo + ro + to + bo > -4) { // Checking against default -1
_macBorder.setOffsets(lo, ro, to, bo);
if (offsets.left + offsets.right + offsets.top + offsets.bottom > -4) { // Checking against default -1
_macBorder.setOffsets(offsets);
}
updateOuterDims();
@ -584,17 +626,17 @@ void MacWindow::setBorderType(int borderType) {
if (borderType < 0) {
disableBorder();
} else {
Common::Rect offsets = _wm->getBorderOffsets(borderType);
BorderOffsets offsets = _wm->getBorderOffsets(borderType);
Common::SeekableReadStream *activeFile = _wm->getBorderFile(borderType, true);
if (activeFile) {
loadBorder(*activeFile, true, offsets.left, offsets.right, offsets.top, offsets.bottom);
loadBorder(*activeFile, true, offsets);
delete activeFile;
}
Common::SeekableReadStream *inactiveFile = _wm->getBorderFile(borderType, false);
if (inactiveFile) {
loadBorder(*inactiveFile, false, offsets.left, offsets.right, offsets.top, offsets.bottom);
loadBorder(*inactiveFile, false, offsets);
delete inactiveFile;
}
}

View file

@ -284,7 +284,9 @@ public:
* @param bo Width of the bottom side of the border, in pixels.
*/
void loadBorder(Common::SeekableReadStream &file, bool active, int lo = -1, int ro = -1, int to = -1, int bo = -1);
void loadBorder(Common::SeekableReadStream &file, bool active, BorderOffsets offsets);
void setBorder(TransparentSurface *border, bool active, int lo = -1, int ro = -1, int to = -1, int bo = -1);
void setBorder(TransparentSurface *border, bool active, BorderOffsets offsets);
void disableBorder();
/**

View file

@ -33,7 +33,13 @@ MacWindowBorder::MacWindowBorder() : _activeInitialized(false), _inactiveInitial
_activeBorder = nullptr;
_inactiveBorder = nullptr;
_borderOffsets.right = -1; // make invalid rect
_borderOffsets.left = -1;
_borderOffsets.right = -1;
_borderOffsets.top = -1;
_borderOffsets.bottom = -1;
_borderOffsets.titleTop = -1;
_borderOffsets.titleBottom = -1;
_borderOffsets.dark = false;
}
MacWindowBorder::~MacWindowBorder() {
@ -78,10 +84,17 @@ void MacWindowBorder::setOffsets(int left, int right, int top, int bottom) {
}
void MacWindowBorder::setOffsets(Common::Rect &rect) {
_borderOffsets = rect;
_borderOffsets.left = rect.left;
_borderOffsets.right = rect.right;
_borderOffsets.top = rect.top;
_borderOffsets.bottom = rect.bottom;
}
Common::Rect &MacWindowBorder::getOffset() {
void MacWindowBorder::setOffsets(const BorderOffsets &offsets) {
_borderOffsets = offsets;
}
BorderOffsets &MacWindowBorder::getOffset() {
return _borderOffsets;
}

View file

@ -32,6 +32,16 @@
namespace Graphics {
struct BorderOffsets {
int left;
int right;
int top;
int bottom;
int titleTop;
int titleBottom;
bool dark;
};
/**
* A representation of a custom border, which allows for arbitrary border offsets
* and nine-patch resizable displays for both active and inactive states.
@ -83,6 +93,7 @@ public:
*/
void setOffsets(int left, int right, int top, int bottom);
void setOffsets(Common::Rect &rect);
void setOffsets(const BorderOffsets &offsets);
/**
* Accessor method to retrieve a given border.
@ -91,7 +102,7 @@ public:
* @param offset The identifier of the offset wanted.
* @return The desired offset in pixels.
*/
Common::Rect &getOffset();
BorderOffsets &getOffset();
/**
* Blit the desired border (active or inactive) into a destination surface.
@ -110,7 +121,7 @@ private:
bool _activeInitialized;
bool _inactiveInitialized;
Common::Rect _borderOffsets;
BorderOffsets _borderOffsets;
};

View file

@ -289,7 +289,7 @@ public:
void removeMarked();
void loadDataBundle();
Common::Rect getBorderOffsets(byte windowType);
BorderOffsets getBorderOffsets(byte windowType);
Common::SeekableReadStream *getBorderFile(byte windowType, bool isActive);
public: