Add overlays (ui::Overlay and ui::OverlayManager classes).

This commit is contained in:
David Capello 2012-08-06 01:17:29 -03:00
parent 89cb9d098c
commit 237bec80f2
12 changed files with 310 additions and 10 deletions

View File

@ -302,14 +302,23 @@ void gui_run()
void gui_feedback()
{
Manager* manager = Manager::getDefault();
OverlayManager* overlays = OverlayManager::instance();
jmouse_draw_cursor();
if (!Manager::getDefault()->getDisplay()->flip()) {
// Draw overlays.
overlays->captureOverlappedAreas();
overlays->drawOverlays();
if (!manager->getDisplay()->flip()) {
// In case that the display was resized.
gui_setup_screen(false);
App::instance()->getMainWindow()->remap_window();
Manager::getDefault()->invalidate();
manager->invalidate();
}
else
overlays->restoreOverlappedAreas();
}
// Sets the ji_screen variable. This routine should be called

View File

@ -10,6 +10,7 @@
namespace she {
class Surface;
class NotDisposableSurface;
// A display or window to show graphics.
class Display {
@ -31,7 +32,8 @@ namespace she {
virtual void setScale(int scale) = 0;
// Returns the main surface to draw into this display.
virtual Surface* getSurface() = 0;
// You must not dispose this surface.
virtual NotDisposableSurface* getSurface() = 0;
// Flips all graphics in the surface to the real display. Returns
// false if the flip couldn't be done because the display was

View File

@ -14,7 +14,8 @@ namespace she {
virtual ~LockedSurface() { }
virtual void unlock() = 0;
virtual void clear() = 0;
virtual void blitTo(LockedSurface* dest, int x, int y) const = 0;
virtual void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const = 0;
virtual void drawAlphaSurface(const LockedSurface* src, int dstx, int dsty) = 0;
};
} // namespace she

View File

@ -100,16 +100,21 @@ public:
clear_to_color(m_bmp, 0);
}
void blitTo(LockedSurface* dest, int x, int y) const {
void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const {
ASSERT(m_bmp);
ASSERT(dest);
ASSERT(static_cast<Alleg4Surface*>(dest)->m_bmp);
blit(m_bmp,
static_cast<Alleg4Surface*>(dest)->m_bmp,
0, 0,
x, y,
m_bmp->w, m_bmp->h);
srcx, srcy,
dstx, dsty,
width, height);
}
void drawAlphaSurface(const LockedSurface* src, int dstx, int dsty) {
set_alpha_blender();
draw_trans_sprite(m_bmp, static_cast<const Alleg4Surface*>(src)->m_bmp, dstx, dsty);
}
private:
@ -193,8 +198,8 @@ public:
m_surface = newSurface;
}
Surface* getSurface() {
return m_surface;
NotDisposableSurface* getSurface() {
return static_cast<NotDisposableSurface*>(m_surface);
}
bool flip() {

View File

@ -21,6 +21,13 @@ namespace she {
virtual void* nativeHandle() = 0;
};
class NotDisposableSurface : public Surface {
public:
virtual ~NotDisposableSurface() { }
private:
virtual void dispose() = 0;
};
} // namespace she
#endif

View File

@ -27,6 +27,8 @@ add_library(ui-lib
menu.cpp
message.cpp
message_loop.cpp
overlay.cpp
overlay_manager.cpp
paint_event.cpp
popup_window.cpp
preferred_size_event.cpp

View File

@ -8,6 +8,7 @@
#include "ui/base.h"
#include "ui/clipboard.h"
#include "ui/overlay_manager.h"
#include "ui/theme.h"
namespace ui {
@ -31,6 +32,8 @@ GuiSystem::GuiSystem()
GuiSystem::~GuiSystem()
{
OverlayManager::destroyInstance();
// finish theme
CurrentTheme::set(NULL);

View File

@ -34,6 +34,8 @@
#include "ui/menu.h"
#include "ui/message.h"
#include "ui/message_loop.h"
#include "ui/overlay.h"
#include "ui/overlay_manager.h"
#include "ui/paint_event.h"
#include "ui/popup_window.h"
#include "ui/preferred_size_event.h"

74
src/ui/overlay.cpp Normal file
View File

@ -0,0 +1,74 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "ui/overlay.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
#include "she/system.h"
#include "ui/manager.h"
namespace ui {
Overlay::Overlay(she::Surface* overlaySurface, const gfx::Point& pos, ZOrder zorder)
: m_surface(overlaySurface)
, m_overlap(NULL)
, m_pos(pos)
, m_zorder(zorder)
{
}
Overlay::~Overlay()
{
Manager* manager = Manager::getDefault();
if (manager)
manager->invalidateRect(gfx::Rect(m_pos.x, m_pos.y,
m_surface->width(),
m_surface->height()));
m_surface->dispose();
if (m_overlap)
m_overlap->dispose();
}
gfx::Rect Overlay::getBounds() const
{
return gfx::Rect(m_pos.x, m_pos.y, m_surface->width(), m_surface->height());
}
void Overlay::drawOverlay(she::LockedSurface* screen)
{
she::ScopedSurfaceLock lockedSurface(m_surface);
screen->drawAlphaSurface(lockedSurface, m_pos.x, m_pos.y);
}
void Overlay::moveOverlay(const gfx::Point& newPos)
{
m_pos = newPos;
}
void Overlay::captureOverlappedArea(she::LockedSurface* screen)
{
if (!m_overlap)
m_overlap = she::Instance()->createSurface(m_surface->width(), m_surface->height());
she::ScopedSurfaceLock lock(m_overlap);
screen->blitTo(lock, m_pos.x, m_pos.y, 0, 0,
m_overlap->width(), m_overlap->height());
}
void Overlay::restoreOverlappedArea(she::LockedSurface* screen)
{
if (!m_overlap)
return;
she::ScopedSurfaceLock lock(m_overlap);
lock->blitTo(screen, 0, 0, m_pos.x, m_pos.y,
m_overlap->width(), m_overlap->height());
}
}

49
src/ui/overlay.h Normal file
View File

@ -0,0 +1,49 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef UI_OVERLAY_H_INCLUDED
#define UI_OVERLAY_H_INCLUDED
#include "gfx/fwd.h"
#include "gfx/point.h"
#include "ui/base.h"
namespace she {
class Surface;
class LockedSurface;
}
namespace ui {
class Overlay {
public:
typedef int ZOrder;
Overlay(she::Surface* overlaySurface, const gfx::Point& pos, ZOrder zorder = 0);
~Overlay();
gfx::Rect getBounds() const;
void captureOverlappedArea(she::LockedSurface* screen);
void restoreOverlappedArea(she::LockedSurface* screen);
void drawOverlay(she::LockedSurface* screen);
void moveOverlay(const gfx::Point& newPos);
bool operator<(const Overlay& other) const {
return m_zorder < other.m_zorder;
}
private:
she::Surface* m_surface;
she::Surface* m_overlap;
gfx::Point m_pos;
ZOrder m_zorder;
};
} // namespace ui
#endif

View File

@ -0,0 +1,96 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "ui/overlay_manager.h"
#include "she/display.h"
#include "she/scoped_surface_lock.h"
#include "ui/manager.h"
#include "ui/overlay.h"
#include <algorithm>
namespace ui {
static bool less_than(Overlay* x, Overlay* y) {
return *x < *y;
}
OverlayManager* OverlayManager::m_singleton = NULL;
OverlayManager* OverlayManager::instance()
{
if (m_singleton == NULL)
m_singleton = new OverlayManager;
return m_singleton;
}
void OverlayManager::destroyInstance()
{
delete m_singleton;
}
OverlayManager::OverlayManager()
{
}
OverlayManager::~OverlayManager()
{
}
void OverlayManager::addOverlay(Overlay* overlay)
{
iterator it = std::lower_bound(begin(), end(), overlay, less_than);
m_overlays.insert(it, overlay);
}
void OverlayManager::removeOverlay(Overlay* overlay)
{
iterator it = std::find(begin(), end(), overlay);
ASSERT(it != end());
if (it != end())
m_overlays.erase(it);
}
void OverlayManager::captureOverlappedAreas()
{
Manager* manager = Manager::getDefault();
if (!manager)
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
for (iterator it = begin(), end = this->end(); it != end; ++it)
(*it)->captureOverlappedArea(lockedDisplaySurface);
}
void OverlayManager::restoreOverlappedAreas()
{
Manager* manager = Manager::getDefault();
if (!manager)
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
for (iterator it = begin(), end = this->end(); it != end; ++it)
(*it)->restoreOverlappedArea(lockedDisplaySurface);
}
void OverlayManager::drawOverlays()
{
Manager* manager = Manager::getDefault();
if (!manager)
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
for (iterator it = begin(), end = this->end(); it != end; ++it)
(*it)->drawOverlay(lockedDisplaySurface);
}
} // namespace ui

50
src/ui/overlay_manager.h Normal file
View File

@ -0,0 +1,50 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef UI_OVERLAY_MANAGER_H_INCLUDED
#define UI_OVERLAY_MANAGER_H_INCLUDED
#include "ui/base.h"
#include <vector>
namespace she { class Surface; }
namespace ui {
class Overlay;
class OverlayManager {
friend class GuiSystem; // So it can call destroyInstance() from ~GuiSystem
static OverlayManager* m_singleton;
OverlayManager();
~OverlayManager();
public:
static OverlayManager* instance();
void addOverlay(Overlay* overlay);
void removeOverlay(Overlay* overlay);
void captureOverlappedAreas();
void restoreOverlappedAreas();
void drawOverlays();
private:
static void destroyInstance();
typedef std::vector<Overlay*> OverlayList;
typedef OverlayList::iterator iterator;
iterator begin() { return m_overlays.begin(); }
iterator end() { return m_overlays.end(); }
OverlayList m_overlays;
};
} // namespace ui
#endif