ultimatepp/uppdev/plugin/cairo/CairoCtrl.h
cxl b7eba97090 Sdraw...
git-svn-id: svn://ultimatepp.org/upp/trunk@733 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-01-06 22:20:15 +00:00

264 lines
5.2 KiB
C++

#ifndef _plugin_cairo_CairoCtrl_h_
#define _plugin_cairo_CairoCtrl_h_
#include <CtrlLib/CtrlLib.h>
#include "Cairo.h"
#include "CairoDraw.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#include "lib/cairo-win32.h"
class CairoCtrl : public DHCtrl
{
private:
Drawing const *_drawing;
Color const *_backgroundColor;
HDC _hDC;
Cairo _cairo;
bool _doubleBuffering;
void DoPaint()
{
if (!_cairo.HasContext())
return;
CairoDraw draw(_cairo);
if (_drawing == NULL)
{
if (_backgroundColor != NULL)
_cairo.Clear(*_backgroundColor);
CairoPaint(_cairo);
UppPaint(draw);
}
else
{
_cairo.Clear(_backgroundColor == NULL ? White() : *_backgroundColor);
Size drawingSize = _drawing->GetSize();
Size size = GetSize();
Size drawSize = size;
int dx = 0, dy = 0;
if(drawingSize.cy * size.cx < size.cy * drawingSize.cx)
{
drawSize.cy = drawingSize.cy * size.cx / drawingSize.cx;
dy = (size.cy - drawSize.cy) / 2;
}
else
{
drawSize.cx = drawingSize.cx * size.cy / drawingSize.cy;
dx = (size.cx - drawSize.cx) / 2;
}
draw.Clipoff(dx, dy, drawSize.cx, drawSize.cy);
draw.DrawDrawing(drawSize, *_drawing);
draw.End();
}
if (_doubleBuffering)
BitBlt(_hDC, Point(0, 0), cairo_win32_surface_get_dc(_cairo.GetSurface()), GetSize());
}
protected:
// Called on paint events
virtual void CairoPaint(Cairo &cairo) { WhenCairoPaint(cairo); }
virtual void UppPaint(Draw &draw) { WhenPaint(draw); }
public:
Callback1<Cairo &> WhenCairoPaint;
Callback1<Draw &> WhenPaint;
CairoCtrl()
: _drawing(NULL),
_hDC(NULL),
_doubleBuffering(true),
_backgroundColor(NULL)
{}
~CairoCtrl()
{
if (_hDC != NULL)
ReleaseDC(GetHWND(), _hDC);
if (_backgroundColor != NULL)
delete _backgroundColor;
}
void Set(Drawing const * const drawing)
{
_drawing = drawing;
Refresh();
}
void Background(Color const &color)
{
if (_backgroundColor != NULL)
delete _backgroundColor;
_backgroundColor = new Color(color);
}
void SetDoubleBuffering(bool buffer = true)
{
_doubleBuffering = buffer;
State(LAYOUTPOS);
}
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_PAINT)
{
PAINTSTRUCT ps;
BeginPaint(GetHWND(), &ps);
DoPaint();
EndPaint(GetHWND(), &ps);
return 0;
}
else if(message == WM_ERASEBKGND)
return 1;
return DHCtrl::WindowProc(message, wParam, lParam);
}
virtual void State(int reason)
{
DHCtrl::State(reason);
if (reason == OPEN || reason == LAYOUTPOS)
{
HWND hwnd = GetHWND();
if (hwnd != NULL)
_hDC = ::GetDC(hwnd);
if (_hDC != NULL)
{
if (_doubleBuffering)
_cairo.SetSurface(cairo_win32_surface_create_with_ddb(_hDC, CAIRO_FORMAT_RGB24, GetSize().cx, GetSize().cy), GetSize().cx, GetSize().cy);
else
_cairo.SetSurface(cairo_win32_surface_create(_hDC), GetSize().cx, GetSize().cy);
}
}
else if (reason == CLOSE && _hDC != NULL)
{
ReleaseDC(GetHWND(), _hDC);
_hDC = NULL;
}
}
};
#else
class CairoCtrl : public Ctrl
{
private:
Drawing const *_drawing;
Color const *_backgroundColor;
Cairo _cairo;
ImageBuffer _buffer;
void DoPaint()
{
if (!_cairo.HasContext())
return;
CairoDraw draw(_cairo);
if (_drawing == NULL)
{
if (_backgroundColor != NULL)
_cairo.Clear(*_backgroundColor);
CairoPaint(_cairo);
UppPaint(draw);
}
else
{
_cairo.Clear(_backgroundColor == NULL ? White() : *_backgroundColor);
Size drawingSize = _drawing->GetSize();
Size size = GetSize();
Size drawSize = size;
int dx = 0, dy = 0;
if(drawingSize.cy * size.cx < size.cy * drawingSize.cx)
{
drawSize.cy = drawingSize.cy * size.cx / drawingSize.cx;
dy = (size.cy - drawSize.cy) / 2;
}
else
{
drawSize.cx = drawingSize.cx * size.cy / drawingSize.cy;
dx = (size.cx - drawSize.cx) / 2;
}
draw.Clipoff(dx, dy, drawSize.cx, drawSize.cy);
draw.DrawDrawing(drawSize, *_drawing);
draw.End();
}
}
virtual void Paint(Draw& draw)
{
if (GetSize() != _buffer.GetSize())
{
_buffer.Create(GetSize());
_cairo.SetSurface(_buffer);
}
if (_buffer.IsEmpty())
return;
DoPaint();
Image i = _buffer;
draw.DrawImage(0, 0, i);
_buffer = i;
}
protected:
// Called on paint events
virtual void CairoPaint(Cairo &cairo) { WhenCairoPaint(cairo); }
virtual void UppPaint(Draw &draw) { WhenPaint(draw); }
public:
Callback1<Cairo &> WhenCairoPaint;
Callback1<Draw &> WhenPaint;
CairoCtrl()
: _drawing(NULL),
_backgroundColor(NULL)
{}
~CairoCtrl()
{
if (_backgroundColor != NULL)
delete _backgroundColor;
}
void Set(Drawing const * const drawing)
{
_drawing = drawing;
Refresh();
}
void Background(Color const &color)
{
if (_backgroundColor != NULL)
delete _backgroundColor;
_backgroundColor = new Color(color);
}
void SetDoubleBuffering(bool buffer = true) {}
};
#endif
END_UPP_NAMESPACE
#endif