aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphics/macgui/macwindow.cpp120
-rw-r--r--graphics/macgui/macwindow.h15
-rw-r--r--graphics/macgui/macwindowborder.cpp22
-rw-r--r--graphics/macgui/macwindowborder.h4
-rw-r--r--graphics/macgui/macwindowmanager.cpp49
-rw-r--r--graphics/macgui/macwindowmanager.h13
-rw-r--r--graphics/nine_patch.cpp89
-rw-r--r--graphics/nine_patch.h14
8 files changed, 285 insertions, 41 deletions
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index 350878446b..e754f3c593 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -50,6 +50,7 @@
#include "common/events.h"
#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/macwindow.h"
+#include "image/bmp.h"
namespace Graphics {
@@ -99,6 +100,8 @@ void MacWindow::setActive(bool active) {
_borderIsDirty = true;
}
+bool MacWindow::isActive() { return _active; }
+
void MacWindow::resize(int w, int h) {
if (_surface.w == w && _surface.h == h)
return;
@@ -177,13 +180,14 @@ static void drawPixelInverted(int x, int y, int color, void *data) {
}
void MacWindow::updateInnerDims() {
- _innerDims = _dims;
if (_macBorder.hasBorder(_active) && _macBorder.hasOffsets()) {
- int maxW = _innerDims.width() - _macBorder.getBorderOffset(kBorderOffsetLeft) - _macBorder.getBorderOffset(kBorderOffsetRight);
- int maxH = _innerDims.width() - _macBorder.getBorderOffset(kBorderOffsetTop) - _macBorder.getBorderOffset(kBorderOffsetBottom);
- _innerDims.clip(maxW, maxH);
- _innerDims.translate(_macBorder.getBorderOffset(kBorderOffsetLeft), _macBorder.getBorderOffset(kBorderOffsetTop));
+ _innerDims = Common::Rect(
+ _dims.left + _macBorder.getOffset(kBorderOffsetLeft),
+ _dims.top + _macBorder.getOffset(kBorderOffsetTop),
+ _dims.right - _macBorder.getOffset(kBorderOffsetRight),
+ _dims.bottom - _macBorder.getOffset(kBorderOffsetBottom));
} else {
+ _innerDims = _dims;
_innerDims.grow(-kBorderWidth);
}
}
@@ -192,12 +196,11 @@ void MacWindow::drawBorder() {
_borderIsDirty = false;
ManagedSurface *g = &_borderSurface;
- prepareBorderSurface(g);
-
- if (_macBorder.hasBorder(_active))
+ if (_macBorder.hasBorder(_active)) {
drawBorderFromSurface(g);
- else
+ } else {
drawSimpleBorder(g);
+ }
}
void MacWindow::prepareBorderSurface(ManagedSurface *g) {
@@ -211,6 +214,11 @@ void MacWindow::prepareBorderSurface(ManagedSurface *g) {
}
void MacWindow::drawBorderFromSurface(ManagedSurface *g) {
+ g->clear(kColorGreen2);
+ Common::Rect inside = _innerDims;
+ inside.moveTo(_macBorder.getOffset(kBorderOffsetLeft), _macBorder.getOffset(kBorderOffsetTop));
+ g->fillRect(inside, kColorGreen);
+
_macBorder.blitBorderInto(_borderSurface, _active);
}
@@ -223,6 +231,8 @@ void MacWindow::drawSimpleBorder(ManagedSurface *g) {
int width = _borderSurface.w;
int height = _borderSurface.h;
+ prepareBorderSurface(g);
+
drawBox(g, x, y, size, size);
drawBox(g, x + width - size - 1, y, size, size);
drawBox(g, x + width - size - 1, y + height - size - 1, size, size);
@@ -304,14 +314,33 @@ void MacWindow::setHighlight(WindowClick highlightedPart) {
_borderIsDirty = true;
}
- void MacWindow::setBorder(TransparentSurface &border, bool active, int lo, int ro, int to, int bo) {
+ void MacWindow::loadBorder(Common::SeekableReadStream &file, bool active, int lo, int ro, int to, int bo) {
+
+ Image::BitmapDecoder bmpDecoder;
+ Graphics::Surface source;
+ Graphics::TransparentSurface *surface = new Graphics::TransparentSurface();
+
+ bmpDecoder.loadStream(file);
+ source = *(bmpDecoder.getSurface());
+
+ source.convertToInPlace(surface->getSupportedPixelFormat(), bmpDecoder.getPalette());
+ surface->create(source.w, source.h, source.format);
+ surface->copyFrom(source);
+ surface->applyColorKey(255, 0, 255, false);
+
if (active)
- _macBorder.addActiveBorder(border);
+ _macBorder.addActiveBorder(*surface);
else
- _macBorder.addInactiveBorder(border);
+ _macBorder.addInactiveBorder(*surface);
if (!_macBorder.hasOffsets())
- _macBorder.setBorderOffsets(lo, ro, to, bo);
+ _macBorder.setOffsets(lo, ro, to, bo);
+
+ updateInnerDims();
+ }
+
+ void MacWindow::setCloseable(bool closeable) {
+ _closeable = closeable;
}
void MacWindow::drawBox(ManagedSurface *g, int x, int y, int w, int h) {
@@ -331,18 +360,56 @@ WindowClick MacWindow::isInBorder(int x, int y) {
if (_innerDims.contains(x, y))
return kBorderInner;
- if (x >= _innerDims.left - _borderWidth && x < _innerDims.left && y >= _innerDims.top - _borderWidth && y < _innerDims.top)
+ if (isInCloseButton(x, y))
return kBorderCloseButton;
if (_resizable)
- if (x >= _innerDims.right && x < _innerDims.right + _borderWidth && y >= _innerDims.bottom && y < _innerDims.bottom + _borderWidth)
+ if (isInResizeButton(x, y))
return kBorderResizeButton;
- if (_scrollable && x >= _innerDims.right && x < _innerDims.right + _borderWidth) {
- if (y < _innerDims.top - _borderWidth)
+ if (_scrollable)
+ return isInScroll(x, y);
+
+ return kBorderBorder;
+}
+
+bool MacWindow::isInCloseButton(int x, int y) {
+ int bLeft = kBorderWidth;
+ int bTop = kBorderWidth;
+ if (_macBorder.hasOffsets()) {
+ bLeft = _macBorder.getOffset(kBorderOffsetLeft);
+ bTop = _macBorder.getOffset(kBorderOffsetTop);
+ }
+ return (x >= _innerDims.left - bLeft && x < _innerDims.left && y >= _innerDims.top - bTop && y < _innerDims.top);
+}
+
+bool MacWindow::isInResizeButton(int x, int y) {
+ int bRight = kBorderWidth;
+ int bBottom = kBorderWidth;
+ if (_macBorder.hasOffsets()) {
+ bRight = _macBorder.getOffset(kBorderOffsetRight);
+ bBottom = _macBorder.getOffset(kBorderOffsetBottom);
+ }
+ return (x >= _innerDims.right && x < _innerDims.right + bRight && y >= _innerDims.bottom && y < _innerDims.bottom + bBottom);
+}
+
+WindowClick MacWindow::isInScroll(int x, int y) {
+ int bLeft = kBorderWidth;
+ int bTop = kBorderWidth;
+ int bRight = kBorderWidth;
+ int bBottom = kBorderWidth;
+ if (_macBorder.hasOffsets()) {
+ bLeft = _macBorder.getOffset(kBorderOffsetLeft);
+ bTop = _macBorder.getOffset(kBorderOffsetTop);
+ bRight = _macBorder.getOffset(kBorderOffsetRight);
+ bBottom = _macBorder.getOffset(kBorderOffsetBottom);
+ }
+
+ if (x >= _innerDims.right && x < _innerDims.right + bRight) {
+ if (y < _innerDims.top - bTop)
return kBorderBorder;
- if (y >= _innerDims.bottom + _borderWidth)
+ if (y >= _innerDims.bottom + bBottom)
return kBorderBorder;
if (y >= _innerDims.top + _innerDims.height() / 2)
@@ -351,6 +418,19 @@ WindowClick MacWindow::isInBorder(int x, int y) {
return kBorderScrollUp;
}
+ if (y >= _innerDims.bottom && y < _innerDims.bottom + bBottom) {
+ if (x < _innerDims.left - bTop)
+ return kBorderBorder;
+
+ if (x >= _innerDims.right + bRight)
+ return kBorderBorder;
+
+ if (x >= _innerDims.left + _innerDims.width() / 2)
+ return kBorderScrollRight;
+
+ return kBorderScrollLeft;
+ }
+
return kBorderBorder;
}
@@ -397,6 +477,10 @@ bool MacWindow::processEvent(Common::Event &event) {
_draggedY = event.mouse.y;
}
+ if (click == kBorderCloseButton && _closeable) {
+ _wm->removeWindow(this);
+ }
+
break;
case Common::EVENT_LBUTTONUP:
_beingDragged = false;
diff --git a/graphics/macgui/macwindow.h b/graphics/macgui/macwindow.h
index ce5cd1a813..763e215c46 100644
--- a/graphics/macgui/macwindow.h
+++ b/graphics/macgui/macwindow.h
@@ -75,6 +75,8 @@ namespace MacWindowConstants {
kBorderNone = 0,
kBorderScrollUp,
kBorderScrollDown,
+ kBorderScrollLeft,
+ kBorderScrollRight,
kBorderCloseButton,
kBorderInner,
kBorderBorder,
@@ -132,13 +134,18 @@ public:
bool draw(ManagedSurface *g, bool forceRedraw = false);
void setActive(bool active);
+ bool isActive();
+
void setTitle(Common::String &title) { _title = title; }
void setHighlight(WindowClick highlightedPart);
void setScroll(float scrollPos, float scrollSize);
bool processEvent(Common::Event &event);
bool hasAllFocus() { return _beingDragged || _beingResized; }
- void setBorder(TransparentSurface &border, bool active, int lo, int ro, int to, int bo);
+ void loadBorder(Common::SeekableReadStream &file, bool active, int lo, int ro, int to, int bo);
+ //void setBorder(TransparentSurface &border, bool active);
+
+ void setCloseable(bool closeable);
private:
void drawBorder();
@@ -151,6 +158,10 @@ private:
void updateInnerDims();
WindowClick isInBorder(int x, int y);
+ bool isInCloseButton(int x, int y);
+ bool isInResizeButton(int x, int y);
+ WindowClick isInScroll(int x, int y);
+
private:
ManagedSurface _borderSurface;
ManagedSurface _composeSurface;
@@ -177,6 +188,8 @@ private:
Common::String _title;
};
+
+
} // End of namespace Graphics
#endif
diff --git a/graphics/macgui/macwindowborder.cpp b/graphics/macgui/macwindowborder.cpp
index b5fdcc33bf..f5458cb976 100644
--- a/graphics/macgui/macwindowborder.cpp
+++ b/graphics/macgui/macwindowborder.cpp
@@ -1,14 +1,20 @@
#include "macwindowborder.h"
+#include "common/system.h"
+
+#include "graphics/macgui/macwindowmanager.h"
+
+
namespace Graphics {
+using namespace Graphics::MacGUIConstants;
+
MacWindowBorder::MacWindowBorder() : _activeInitialized(false), _inactiveInitialized(false) {
_activeBorder = nullptr;
_inactiveBorder = nullptr;
_hasOffsets = false;
}
-
MacWindowBorder::~MacWindowBorder() {
if (_activeBorder)
delete _activeBorder;
@@ -36,7 +42,7 @@ bool MacWindowBorder::hasOffsets() {
return _hasOffsets;
}
-void MacWindowBorder::setBorderOffsets(int left, int right, int top, int bottom) {
+void MacWindowBorder::setOffsets(int left, int right, int top, int bottom) {
_borderOffsets[0] = left;
_borderOffsets[1] = right;
_borderOffsets[2] = top;
@@ -44,7 +50,7 @@ void MacWindowBorder::setBorderOffsets(int left, int right, int top, int bottom)
_hasOffsets = true;
}
-int MacWindowBorder::getBorderOffset(MacBorderOffset offset) {
+int MacWindowBorder::getOffset(MacBorderOffset offset) {
return _borderOffsets[offset];
}
@@ -53,10 +59,14 @@ void MacWindowBorder::blitBorderInto(ManagedSurface &destination, bool active) {
TransparentSurface srf;
NinePatchBitmap *src = active ? _activeBorder : _inactiveBorder;
- srf.create(destination.w, destination.h, src->getSource()->format);
+ srf.create(destination.w, destination.h, destination.format);
+ srf.fillRect(Common::Rect(0, 0, srf.w, srf.h), kColorGreen2);
+
+ byte palette[kColorCount];
+ g_system->getPaletteManager()->grabPalette(palette, 0, kColorCount);
- src->blit(srf, 0, 0, srf.w, srf.h);
- destination.transBlitFrom(srf, destination.format.ARGBToColor(0, 255, 255, 255));
+ src->blit(srf, 0, 0, srf.w, srf.h, palette, kColorCount);
+ destination.transBlitFrom(srf, kColorGreen2);
}
} // End of namespace Graphics
diff --git a/graphics/macgui/macwindowborder.h b/graphics/macgui/macwindowborder.h
index f1d0d2c81a..3c41ef2819 100644
--- a/graphics/macgui/macwindowborder.h
+++ b/graphics/macgui/macwindowborder.h
@@ -74,8 +74,8 @@ public:
void addInactiveBorder(TransparentSurface &source);
bool hasOffsets();
- void setBorderOffsets(int left, int right, int top, int bottom);
- int getBorderOffset(MacBorderOffset offset);
+ void setOffsets(int left, int right, int top, int bottom);
+ int getOffset(MacBorderOffset offset);
void blitBorderInto(ManagedSurface &destination, bool active);
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index da573e6025..de94acf33a 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -184,6 +184,11 @@ void MacWindowManager::setActive(int id) {
_fullRefresh = true;
}
+void MacWindowManager::removeWindow(MacWindow *target) {
+ _windowsToRemove.push_back(target);
+ _needsRemoval = true;
+}
+
struct PlotData {
Graphics::ManagedSurface *surface;
MacPatterns *patterns;
@@ -242,6 +247,8 @@ void MacWindowManager::drawDesktop() {
void MacWindowManager::draw() {
assert(_screen);
+ removeMarked();
+
if (_fullRefresh)
drawDesktop();
@@ -269,9 +276,9 @@ bool MacWindowManager::processEvent(Common::Event &event) {
if (_menu && _menu->processEvent(event))
return true;
- if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN &&
- event.type != Common::EVENT_LBUTTONUP)
- return false;
+ if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN &&
+ event.type != Common::EVENT_LBUTTONUP)
+ return false;
if (_windows[_activeWindow]->isEditable() && _windows[_activeWindow]->getType() == kWindowWindow &&
((MacWindow *)_windows[_activeWindow])->getInnerDimensions().contains(event.mouse.x, event.mouse.y)) {
@@ -302,6 +309,42 @@ bool MacWindowManager::processEvent(Common::Event &event) {
return false;
}
+void MacWindowManager::removeMarked() {
+ if (!_needsRemoval) return;
+
+ Common::List<BaseMacWindow *>::const_iterator it;
+ for (it = _windowsToRemove.begin(); it != _windowsToRemove.end(); it++) {
+ removeFromStack(*it);
+ removeFromWindowList(*it);
+ delete *it;
+ _activeWindow = 0;
+ _fullRefresh = true;
+ }
+ _windowsToRemove.clear();
+ _needsRemoval = false;
+}
+
+void MacWindowManager::removeFromStack(BaseMacWindow *target) {
+ Common::List<BaseMacWindow *>::iterator stackIt;
+ for (stackIt = _windowStack.begin(); stackIt != _windowStack.end(); stackIt++) {
+ if (*stackIt == target) {
+ stackIt = _windowStack.erase(stackIt);
+ stackIt--;
+ }
+ }
+}
+
+void MacWindowManager::removeFromWindowList(BaseMacWindow *target) {
+ int size = _windows.size();
+ int ndx = 0;
+ for (int i = 0; i < size; i++) {
+ if (_windows[i] == target) {
+ ndx = i;
+ }
+ }
+ _windows.remove_at(ndx);
+}
+
//////////////////////
// Font stuff
//////////////////////
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index 21bc3815db..c208089c24 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -56,7 +56,7 @@
#include "graphics/fontman.h"
#include "graphics/macgui/macwindow.h"
-namespace Graphics {
+namespace Graphics {
namespace MacGUIConstants {
enum {
@@ -68,7 +68,8 @@ namespace MacGUIConstants {
kColorGray = 1,
kColorWhite = 2,
kColorGreen = 3,
- kColorGreen2 = 4
+ kColorGreen2 = 4,
+ kColorCount
};
enum {
@@ -98,6 +99,7 @@ public:
MacWindow *addWindow(bool scrollable, bool resizable, bool editable);
Menu *addMenu();
void setActive(int id);
+ void removeWindow(MacWindow *target);
void setFullRefresh(bool redraw) { _fullRefresh = true; }
@@ -117,12 +119,19 @@ private:
void drawDesktop();
void loadFonts();
+ void removeMarked();
+ void removeFromStack(BaseMacWindow *target);
+ void removeFromWindowList(BaseMacWindow *target);
+
private:
ManagedSurface *_screen;
Common::List<BaseMacWindow *> _windowStack;
Common::Array<BaseMacWindow *> _windows;
+ Common::List<BaseMacWindow *> _windowsToRemove;
+ bool _needsRemoval;
+
int _lastId;
int _activeWindow;
diff --git a/graphics/nine_patch.cpp b/graphics/nine_patch.cpp
index 8ac6977eed..89c534f1ac 100644
--- a/graphics/nine_patch.cpp
+++ b/graphics/nine_patch.cpp
@@ -48,6 +48,8 @@
#include "graphics/transparent_surface.h"
#include "graphics/nine_patch.h"
+#include "graphics/managed_surface.h"
+
namespace Graphics {
NinePatchSide::~NinePatchSide() {
@@ -201,7 +203,7 @@ bad_bitmap:
}
}
-void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh) {
+void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette, byte numColors) {
/* don't draw bitmaps that are smaller than the fixed area */
if (dw < _h._fix || dh < _v._fix)
return;
@@ -223,15 +225,50 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in
_cached_dh = dh;
}
+ /* Handle CLUT8 */
+ if (target.format.bytesPerPixel == 1) {
+ if (!palette)
+ warning("Trying to blit into a surface with 1bpp, you need the palette.");
+
+ Surface srf;
+ srf.create(target.w, target.h, _bmp->format);
+
+ drawRegions(srf, dx, dy, dw, dh);
+
+ byte black = getColorIndex(TS_RGB(0, 0, 0), palette);
+ byte white = getColorIndex(TS_RGB(255, 255, 255), palette);
+
+ for (uint i = 0; i < srf.w; ++i) {
+ for (uint j = 0; j < srf.h; ++j) {
+ uint32 color = *(uint32*)srf.getBasePtr(i, j);
+ if (color > 0) {
+ *((byte *)target.getBasePtr(i, j)) = closestGrayscale(color, palette, numColors);
+ }
+ }
+ }
+
+ return;
+ }
+
+ /* Else, draw regions normally */
+ drawRegions(target, dx, dy, dw, dh);
+}
+
+NinePatchBitmap::~NinePatchBitmap() {
+ if (_destroy_bmp)
+ delete _bmp;
+}
+
+void NinePatchBitmap::drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh) {
/* draw each region */
for (uint i = 0; i < _v._m.size(); ++i) {
for (uint j = 0; j < _h._m.size(); ++j) {
Common::Rect r(_h._m[j]->offset, _v._m[i]->offset,
- _h._m[j]->offset + _h._m[j]->length, _v._m[i]->offset + _v._m[i]->length);
+ _h._m[j]->offset + _h._m[j]->length, _v._m[i]->offset + _v._m[i]->length);
_bmp->blit(target, dx + _h._m[j]->dest_offset, dy + _v._m[i]->dest_offset,
- Graphics::FLIP_NONE, &r, TS_ARGB(255, 255, 255, 255),
- _h._m[j]->dest_length, _v._m[i]->dest_length);
+ Graphics::FLIP_NONE, &r, TS_ARGB(255, 255, 255, 255),
+ _h._m[j]->dest_length, _v._m[i]->dest_length);
}
}
}
@@ -271,9 +308,47 @@ void NinePatchBitmap::blitClip(Graphics::Surface &target, Common::Rect clip, int
}
}
-NinePatchBitmap::~NinePatchBitmap() {
- if (_destroy_bmp)
- delete _bmp;
+byte NinePatchBitmap::getColorIndex(uint32 target, byte* palette) {
+ byte *pal = palette;
+ uint i = 0;
+ uint32 color = TS_RGB(pal[0], pal[1], pal[2]);
+ while (color != target) {
+ i += 3;
+ color = TS_RGB(pal[i], pal[i + 1], pal[i + 2]);
+ }
+ return (i / 3);
+}
+
+uint32 NinePatchBitmap::grayscale(uint32 color) {
+ byte r, g, b;
+ _bmp->format.colorToRGB(color, r, g, b);
+ return grayscale(r, g, b);
+}
+
+uint32 NinePatchBitmap::grayscale(byte r, byte g, byte b) {
+ return (0.29 * r + 0.58 * g + 0.11 * b) / 3;
+}
+
+static inline uint32 dist(uint32 a, uint32 b) {
+ if (a > b)
+ return (a - b);
+
+ return b - a;
+}
+
+byte NinePatchBitmap::closestGrayscale(uint32 color, byte* palette, byte paletteLength) {
+ byte target = grayscale(color);
+ byte bestNdx = 0;
+ byte bestColor = grayscale(palette[0], palette[1], palette[2]);
+ for (byte i = 1; i < paletteLength; ++i) {
+ byte current = grayscale(palette[i * 3], palette[(i * 3) + 1], palette[(i * 3) + 2]);
+ if (dist(target, bestColor) >= dist(target, current)) {
+ bestColor = current;
+ bestNdx = i;
+ }
+ }
+
+ return bestNdx;
}
} // end of namespace Graphics
diff --git a/graphics/nine_patch.h b/graphics/nine_patch.h
index eaebac3e7b..d0fc1af05a 100644
--- a/graphics/nine_patch.h
+++ b/graphics/nine_patch.h
@@ -86,15 +86,25 @@ public:
NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap);
~NinePatchBitmap();
- void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh);
+ void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette = NULL, byte numColours = 0);
void blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh);
-
+
int getWidth() { return _width; }
int getHeight() { return _height; }
int getMinWidth() { return _h._fix; }
int getMinHeight() { return _v._fix; }
Graphics::TransparentSurface *getSource() { return _bmp; }
Common::Rect &getPadding() { return _padding; }
+
+private:
+
+ void drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh);
+
+ // Assumes color is in the palette
+ byte getColorIndex(uint32 target, byte *palette);
+ uint32 grayscale(uint32 color);
+ uint32 grayscale(byte r, byte g, byte b);
+ byte closestGrayscale(uint32 color, byte* palette, byte paletteLength);
};
} // end of namespace Graphics