mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 14:16:10 -06:00
264 lines
5.2 KiB
C++
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
|