mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
reorganizing repo
git-svn-id: svn://ultimatepp.org/upp/trunk@9214 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
e5d5257d47
commit
f0e42f8693
265 changed files with 69272 additions and 0 deletions
42
rainbow/CoreGl/AlphaMag.frag
Normal file
42
rainbow/CoreGl/AlphaMag.frag
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
uniform sampler2D Texture;
|
||||
uniform vec4 GlyphColor;
|
||||
uniform vec4 GlowColor;
|
||||
uniform vec4 OutlineColor;
|
||||
|
||||
uniform bool Outline;
|
||||
uniform bool Glow;
|
||||
uniform bool Shadow;
|
||||
|
||||
const float AlphaCenter = 0.5;
|
||||
const float DistanceScale = 25.0;
|
||||
|
||||
uniform float OutlineCenter;
|
||||
uniform float GlowCenter;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(Texture, gl_TexCoord[0].xy);
|
||||
float alpha = color.a;
|
||||
float width = min(length(fwidth(gl_TexCoord[0])), 1.0) * DistanceScale;
|
||||
|
||||
vec4 finalColor = GlyphColor;
|
||||
|
||||
float ma = smoothstep(AlphaCenter - width, AlphaCenter + width, alpha);
|
||||
finalColor.a = ma;
|
||||
|
||||
if(Outline)
|
||||
{
|
||||
float mo = smoothstep(OutlineCenter - width, OutlineCenter + width, alpha);
|
||||
finalColor = mix(OutlineColor, finalColor, ma);
|
||||
finalColor.a = mo;
|
||||
}
|
||||
|
||||
if(Glow && alpha >= finalColor.a - 0.5)
|
||||
{
|
||||
float mg = smoothstep(AlphaCenter, GlowCenter, sqrt(alpha));
|
||||
finalColor = mix(GlowColor, finalColor, ma);
|
||||
finalColor.a = mg;
|
||||
}
|
||||
|
||||
gl_FragColor = finalColor * GlyphColor.a;
|
||||
}
|
||||
5
rainbow/CoreGl/AlphaMag.vert
Normal file
5
rainbow/CoreGl/AlphaMag.vert
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
51
rainbow/CoreGl/Blur.frag
Normal file
51
rainbow/CoreGl/Blur.frag
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
uniform float sigma; // The sigma value for the gaussian function: higher value means more blur
|
||||
// A good value for 9x9 is around 3 to 5
|
||||
// A good value for 7x7 is around 2.5 to 4
|
||||
// A good value for 5x5 is around 2 to 3.5
|
||||
// ... play around with this based on what you need :)
|
||||
|
||||
uniform float blurSize; // This should usually be equal to
|
||||
// 1.0f / texture_pixel_width for a horizontal blur, and
|
||||
// 1.0f / texture_pixel_height for a vertical blur.
|
||||
|
||||
uniform sampler2D blurSampler; // Texture that will be blurred by this shader
|
||||
|
||||
const float numBlurPixelsPerSide = 3.0f;
|
||||
// 9x9 - 4
|
||||
// 7x7 - 3
|
||||
// 5x5 - 2
|
||||
uniform vec2 blurMultiplyVec;
|
||||
// 1, 0 - vertical
|
||||
// 0, 1 - horizontal
|
||||
uniform vec3 gaussian;
|
||||
uniform float grayStrength;
|
||||
uniform float blurStrength;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 v = texture2D(blurSampler, gl_TexCoord[0].xy);
|
||||
if(blurStrength > 0.0f)
|
||||
{
|
||||
vec4 avgValue = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
float coefficientSum = 0.0f;
|
||||
|
||||
vec3 incGaussian = gaussian;
|
||||
avgValue += v * incGaussian.x;
|
||||
coefficientSum += incGaussian.x;
|
||||
incGaussian.xy *= incGaussian.yz;
|
||||
|
||||
for (float i = 1.0f; i <= numBlurPixelsPerSide; i++) {
|
||||
vec2 pos = i * blurSize * blurMultiplyVec;
|
||||
avgValue += texture2D(blurSampler, gl_TexCoord[0].xy - pos) * incGaussian.x;
|
||||
avgValue += texture2D(blurSampler, gl_TexCoord[0].xy + pos) * incGaussian.x;
|
||||
coefficientSum += 2.0f * incGaussian.x;
|
||||
incGaussian.xy *= incGaussian.yz;
|
||||
}
|
||||
|
||||
v = avgValue / coefficientSum;
|
||||
}
|
||||
float gray = dot(v.rgb, vec3(0.299, 0.587, 0.114));
|
||||
vec4 grayColor = vec4(gray, gray, gray, v.a);
|
||||
|
||||
gl_FragColor = mix(v, grayColor, grayStrength);
|
||||
}
|
||||
5
rainbow/CoreGl/Blur.vert
Normal file
5
rainbow/CoreGl/Blur.vert
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
21
rainbow/CoreGl/ChSysInit.cpp
Normal file
21
rainbow/CoreGl/ChSysInit.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void ChSysInit()
|
||||
{
|
||||
CtrlImg::Reset();
|
||||
CtrlsImg::Reset();
|
||||
ChReset();
|
||||
}
|
||||
|
||||
void ChHostSkin()
|
||||
{
|
||||
ChSysInit();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
238
rainbow/CoreGl/Clip.cpp
Normal file
238
rainbow/CoreGl/Clip.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
static VectorMap<String, ClipData> fbClipboard;
|
||||
|
||||
void ClearClipboard()
|
||||
{
|
||||
GuiLock __;
|
||||
fbClipboard.Clear();
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&))
|
||||
{
|
||||
GuiLock __;
|
||||
ClipData& cd = fbClipboard.GetAdd(format);
|
||||
cd.data = data;
|
||||
cd.render = render;
|
||||
}
|
||||
|
||||
static String sRawRender(const Value& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const String& data)
|
||||
{
|
||||
GuiLock __;
|
||||
AppendClipboard(format, data, sRawRender);
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const byte *data, int length)
|
||||
{
|
||||
GuiLock __;
|
||||
AppendClipboard(format, String(data, length));
|
||||
}
|
||||
|
||||
String ReadClipboard(const char *format)
|
||||
{
|
||||
GuiLock __;
|
||||
int q = fbClipboard.Find(format);
|
||||
return q >= 0 ? (*fbClipboard[q].render)(fbClipboard[q].data) : String();
|
||||
}
|
||||
|
||||
void AppendClipboardText(const String& s)
|
||||
{
|
||||
AppendClipboard("text", ToSystemCharset(s));
|
||||
}
|
||||
|
||||
void AppendClipboardUnicodeText(const WString& s)
|
||||
{
|
||||
AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength());
|
||||
}
|
||||
|
||||
const char *ClipFmtsText()
|
||||
{
|
||||
return "wtext;text";
|
||||
}
|
||||
|
||||
String GetString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.Accept("wtext")) {
|
||||
String s = ~clip;
|
||||
return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString();
|
||||
}
|
||||
if(clip.IsAvailable("text"))
|
||||
return ~clip;
|
||||
return Null;
|
||||
}
|
||||
|
||||
WString GetWString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.Accept("wtext")) {
|
||||
String s = ~clip;
|
||||
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
|
||||
}
|
||||
if(clip.IsAvailable("text"))
|
||||
return (~clip).ToWString();
|
||||
return Null;
|
||||
}
|
||||
|
||||
|
||||
bool AcceptText(PasteClip& clip)
|
||||
{
|
||||
return clip.Accept(ClipFmtsText());
|
||||
}
|
||||
|
||||
static String sText(const Value& data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static String sWText(const Value& data)
|
||||
{
|
||||
return Unicode__(WString(data));
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const String& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(text, sText));
|
||||
data.GetAdd("wtext", ClipData(text, sWText));
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const WString& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(text, sText));
|
||||
data.GetAdd("wtext", ClipData(text, sWText));
|
||||
}
|
||||
|
||||
String GetTextClip(const WString& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return text.ToString();
|
||||
if(fmt == "wtext")
|
||||
return Unicode__(text);
|
||||
return Null;
|
||||
}
|
||||
|
||||
String GetTextClip(const String& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return text;
|
||||
if(fmt == "wtext")
|
||||
return Unicode__(text.ToWString());
|
||||
return Null;
|
||||
}
|
||||
|
||||
String ReadClipboardText()
|
||||
{
|
||||
String w = ReadClipboard("text");
|
||||
return w.GetCount() ? w : ReadClipboardUnicodeText().ToString();
|
||||
}
|
||||
|
||||
WString ReadClipboardUnicodeText()
|
||||
{
|
||||
String w = ReadClipboard("wtext");
|
||||
if(w.GetCount())
|
||||
return WString((const wchar *)~w, w.GetLength() / 2);
|
||||
return ReadClipboard("text").ToWString();
|
||||
}
|
||||
|
||||
bool IsClipboardAvailable(const char *id)
|
||||
{
|
||||
return fbClipboard.Find(id) >= 0;
|
||||
}
|
||||
|
||||
bool IsClipboardAvailableText()
|
||||
{
|
||||
return IsClipboardAvailable("text") || IsClipboardAvailable("wtext");
|
||||
}
|
||||
|
||||
const char *ClipFmtsImage()
|
||||
{
|
||||
static const char *q;
|
||||
ONCELOCK {
|
||||
static String s = "dib;" + ClipFmt<Image>();
|
||||
q = s;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
bool AcceptImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
return clip.Accept(ClipFmtsImage());
|
||||
}
|
||||
|
||||
Image GetImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Image m;
|
||||
if(Accept<Image>(clip)) {
|
||||
LoadFromString(m, ~clip);
|
||||
if(!m.IsEmpty())
|
||||
return m;
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
Image ReadClipboardImage()
|
||||
{
|
||||
GuiLock __;
|
||||
PasteClip d = Ctrl::Clipboard();
|
||||
return GetImage(d);
|
||||
}
|
||||
|
||||
String sImage(const Value& image)
|
||||
{
|
||||
Image img = image;
|
||||
return StoreAsString(const_cast<Image&>(img));
|
||||
}
|
||||
|
||||
String GetImageClip(const Image& img, const String& fmt)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.IsEmpty()) return Null;
|
||||
if(fmt == ClipFmt<Image>())
|
||||
return sImage(img);
|
||||
return Null;
|
||||
}
|
||||
|
||||
void AppendClipboardImage(const Image& img)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.IsEmpty()) return;
|
||||
AppendClipboard(ClipFmt<Image>(), img, sImage);
|
||||
}
|
||||
|
||||
bool AcceptFiles(PasteClip& clip)
|
||||
{
|
||||
if(clip.Accept("files")) {
|
||||
clip.SetAction(DND_COPY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAvailableFiles(PasteClip& clip)
|
||||
{
|
||||
return clip.IsAvailable("files");
|
||||
}
|
||||
|
||||
Vector<String> GetFiles(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Vector<String> f;
|
||||
return f;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
199
rainbow/CoreGl/Console.cpp
Normal file
199
rainbow/CoreGl/Console.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "Console.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Console::Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
|
||||
#ifndef COLOR_ALPHA
|
||||
SystemDraw& sw = (SystemDraw&) w;
|
||||
sw.alpha = 100.f;
|
||||
Color frame = Yellow;
|
||||
Color body = Black;
|
||||
#else
|
||||
Color frame = Yellow().Alpha(100);
|
||||
Color body = Black().Alpha(100);
|
||||
#endif
|
||||
|
||||
w.DrawRect(sz, body);
|
||||
w.DrawRect(0, 0, sz.cx, 1, frame);
|
||||
w.DrawRect(sz.cx - 1, 1, 1, sz.cy - 1, frame);
|
||||
w.DrawRect(0, 1, 1, sz.cy, frame);
|
||||
w.DrawRect(1, sz.cy - 1, sz.cx - 2, 1, frame);
|
||||
//DrawFrame(w, sz, Yellow);
|
||||
//w.DrawImage(sz.cx - 18, sz.cy - 21, LinuxGlImg::ResizeMarker());
|
||||
w.DrawRect(1, sz.cy - 22, sz.cx - 2, 1, frame);
|
||||
w.Clip(5, 5, sz.cx - 10, sz.cy - 5 - 21);
|
||||
#ifndef COLOR_ALPHA
|
||||
sw.alpha = 255.f;
|
||||
#endif
|
||||
int y = 5;
|
||||
//int ty = Draw::GetStdFontCy() + 2;
|
||||
int ty = 12 + 2;
|
||||
for(int i = 0; i < fixedText.GetCount(); i++)
|
||||
{
|
||||
w.DrawText(5, y, fixedText[i].text, StdFont(), fixedText[i].ink);
|
||||
y += ty;
|
||||
}
|
||||
|
||||
if(fixedText.GetCount() > 0 && floatText.GetCount() > 0)
|
||||
{
|
||||
#ifndef COLOR_ALPHA
|
||||
sw.alpha = 150.f;
|
||||
#endif
|
||||
w.DrawRect(5, y, sz.cx - 10, 1, frame);
|
||||
#ifndef COLOR_ALPHA
|
||||
sw.alpha = 255.f;
|
||||
#endif
|
||||
y += 2;
|
||||
}
|
||||
|
||||
int lines = (sz.cy - y - 22) / ty;
|
||||
int n = fceil(sb.GetPos() / double(ty));
|
||||
int maxn = min(n + lines, currLine);
|
||||
|
||||
while(n < maxn)
|
||||
{
|
||||
LineInfo& lf = floatText[n];
|
||||
w.DrawText(5, y, lf.text, StdFont(), lf.ink);
|
||||
y += ty;
|
||||
++n;
|
||||
}
|
||||
|
||||
w.End();
|
||||
}
|
||||
|
||||
void Console::Log(int line, const char* text, Color ink)
|
||||
{
|
||||
LineInfo& lf = fixedText.GetAdd(line);
|
||||
lf.ink = ink;
|
||||
lf.text = text;
|
||||
}
|
||||
|
||||
void Console::Log(const char* text, Color ink)
|
||||
{
|
||||
bool isend = sb.IsEnd();
|
||||
|
||||
if(++currLine >= maxLine)
|
||||
{
|
||||
currLine = maxLine;
|
||||
for(int i = 0; i < maxLine - 1; i++)
|
||||
floatText[i] = floatText[i + 1];
|
||||
}
|
||||
|
||||
int ty = Draw::GetStdFontCy() + 2;
|
||||
int total = currLine * ty;
|
||||
int fcnt = fixedText.GetCount();
|
||||
sb.SetTotal(total + 5 + 22);
|
||||
|
||||
if(isend)
|
||||
sb.GoEnd();
|
||||
|
||||
LineInfo& lf = floatText[currLine - 1];
|
||||
lf.ink = ink;
|
||||
lf.text = text;
|
||||
}
|
||||
|
||||
void Console::LeftDown(Point p, dword keys)
|
||||
{
|
||||
SetCapture();
|
||||
pos = p;
|
||||
rs = GetSize();
|
||||
tl = GetScreenRect().TopLeft();
|
||||
Size sz = GetSize();
|
||||
resize = p.x > sz.cx - 18 && p.y > sz.cy - 18;
|
||||
}
|
||||
|
||||
void Console::LeftUp(Point p, dword keys)
|
||||
{
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
||||
void Console::MouseMove(Point p, dword keys)
|
||||
{
|
||||
if(HasCapture())
|
||||
{
|
||||
Rect r = GetRect();
|
||||
bool isend = sb.IsEnd();
|
||||
if(resize)
|
||||
{
|
||||
tl = Point(p.x - pos.x, p.y - pos.y);
|
||||
SetConsoleRect(r.left, r.top, max(2, rs.cx + tl.x), max(2, rs.cy + tl.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
tl += Point(p.x - pos.x, p.y - pos.y);
|
||||
SetConsoleRect(tl.x, tl.y, r.Width(), r.Height());
|
||||
}
|
||||
if(isend)
|
||||
sb.GoEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Console::Layout()
|
||||
{
|
||||
}
|
||||
|
||||
void Console::SetConsoleRect(int x, int y, int cx, int cy)
|
||||
{
|
||||
int width = cx < 0 ? 300 : cx;
|
||||
int height = cy < 0 ? 5 + 5 + (Draw::GetStdFontCy() + 2) * 30 + 3 : cy;
|
||||
SetRect(x, y, width, height);
|
||||
}
|
||||
|
||||
void Console::SetLines(int lines)
|
||||
{
|
||||
maxLine = lines;
|
||||
floatText.SetCount(lines);
|
||||
}
|
||||
|
||||
void Console::Init(Ctrl& parent)
|
||||
{
|
||||
if(!init)
|
||||
return;
|
||||
init = false;
|
||||
this->parent = &parent;
|
||||
SetConsoleRect(parent.GetSize().cx - 5 - 300, 5);
|
||||
sb.SetFrameSize(5, false).SetAlign(AlignedFrame::RIGHT);
|
||||
Show();
|
||||
}
|
||||
|
||||
void Console::Show(bool b)
|
||||
{
|
||||
if(IsOpen())
|
||||
{
|
||||
if(!b)
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(b)
|
||||
PopUp(parent, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::Clear()
|
||||
{
|
||||
currLine = 0;
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
Console::Console() : init(true), resize(false)
|
||||
{
|
||||
Add(sb.RightPos(2, 7).VSizePos(2, 22));
|
||||
Add(clear.LeftPos(2, 50).BottomPos(2, 18));
|
||||
clear.SetLabel("Clear");
|
||||
//clear.bg = Yellow;
|
||||
//clear.alpha = 150.f;
|
||||
clear <<= THISBACK(Clear);
|
||||
SetLines(3000);
|
||||
currLine = 0;
|
||||
scrollLine = 0;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
51
rainbow/CoreGl/Console.h
Normal file
51
rainbow/CoreGl/Console.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _CoreGl_Console_h_
|
||||
#define _CoreGl_Console_h_
|
||||
|
||||
#include "ControlPanel.h"
|
||||
#include "Scrollbar.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct Console : Ctrl
|
||||
{
|
||||
Ctrl* parent;
|
||||
SlimScrollBar sb;
|
||||
SlimButton clear;
|
||||
|
||||
struct LineInfo : Moveable<LineInfo> {
|
||||
Color ink;
|
||||
String text;
|
||||
};
|
||||
|
||||
bool init;
|
||||
bool resize;
|
||||
Point pos;
|
||||
Point tl;
|
||||
Size rs;
|
||||
int currLine;
|
||||
int scrollLine;
|
||||
int maxLine;
|
||||
VectorMap<int, LineInfo> fixedText;
|
||||
Vector<LineInfo> floatText;
|
||||
void Init(Ctrl& parent);
|
||||
void SetConsoleRect(int x, int y, int cx = -1, int cy = -1);
|
||||
virtual void Paint(Draw& w);
|
||||
virtual void LeftDown(Point p, dword keys);
|
||||
virtual void LeftUp(Point p, dword keys);
|
||||
virtual void MouseMove(Point p, dword keys);
|
||||
virtual void Layout();
|
||||
|
||||
void Log(int line, const char* text, Color ink = White);
|
||||
void Log(const char* text, Color ink = White);
|
||||
|
||||
void SetLines(int lines);
|
||||
void Show(bool b = true);
|
||||
void Clear();
|
||||
|
||||
typedef Console CLASSNAME;
|
||||
Console();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
211
rainbow/CoreGl/ControlPanel.cpp
Normal file
211
rainbow/CoreGl/ControlPanel.cpp
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "ControlPanel.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
ValueSlider::ValueSlider()
|
||||
{
|
||||
pos = 0;
|
||||
shaded = true;
|
||||
immediate = false;
|
||||
src = Color(255, 255, 0);
|
||||
dst = Color(255, 153, 51);
|
||||
}
|
||||
|
||||
void ValueSlider::Paint(Draw &w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
|
||||
/*w.DrawRect(0, 0, sz.cx, 1, Black);
|
||||
w.DrawRect(0, sz.cy - 1, sz.cx, 1, Black);
|
||||
w.DrawRect(0, 0, 1, sz.cy, Black);
|
||||
w.DrawRect(sz.cx - 1, 0, 1, sz.cy, Black);*/
|
||||
|
||||
int t = (int) (((pos - minValue) * sz.cx) / (maxValue - minValue));
|
||||
if(t < 1) t = 1;
|
||||
if(t > sz.cx - 1) t = sz.cx - 1;
|
||||
|
||||
if(shaded)
|
||||
{
|
||||
for(int i = 1; i < t; i++)
|
||||
w.DrawRect(i, 1, 1, sz.cy - 2, Blend(src, dst, 256 * i / (sz.cx - 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
w.DrawRect(Rect(1, 1, t, sz.cy - 1), dst);
|
||||
}
|
||||
|
||||
if(t < sz.cx - 1)
|
||||
w.DrawRect(Rect(t, 1, sz.cx - 1, sz.cy - 1), Color(245, 245, 255));
|
||||
|
||||
String s = Format("%s : %.2f", text, pos);
|
||||
Size tsz = GetTextSize(s, StdFont());
|
||||
w.DrawText((sz.cx - tsz.cx) / 2, (sz.cy - tsz.cy) / 2, s);
|
||||
}
|
||||
|
||||
void ValueSlider::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
pos = minValue + (p.x * (maxValue - minValue)) / (float) GetSize().cx;
|
||||
Refresh();
|
||||
SetCapture();
|
||||
if(immediate)
|
||||
WhenAction();
|
||||
}
|
||||
|
||||
void ValueSlider::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
ReleaseCapture();
|
||||
if(!immediate)
|
||||
WhenAction();
|
||||
}
|
||||
|
||||
void ValueSlider::MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
if(HasCapture())
|
||||
{
|
||||
pos = minValue + (p.x * (maxValue - minValue)) / (float) GetSize().cx;
|
||||
if(pos > maxValue) pos = maxValue;
|
||||
if(pos < minValue) pos = minValue;
|
||||
Refresh();
|
||||
if(immediate)
|
||||
WhenAction();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueSlider::SetPos(float p, float minv, float maxv)
|
||||
{
|
||||
pos = p;
|
||||
minValue = minv;
|
||||
maxValue = maxv;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
float ValueSlider::GetPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
void SlimButton::Paint(Draw &w)
|
||||
{
|
||||
SystemDraw& sw = (SystemDraw&) w;
|
||||
float a = sw.alpha;
|
||||
sw.alpha = alpha;
|
||||
Size sz = GetSize();
|
||||
if(HasMouseIn(sz))
|
||||
w.DrawRect(sz, bg);
|
||||
sw.alpha = a;
|
||||
|
||||
Size tsz = GetTextSize(label, StdFont());
|
||||
w.DrawText((sz.cx - tsz.cx) / 2, (sz.cy - tsz.cy) / 2, label, StdFont(), fg);
|
||||
}
|
||||
|
||||
void SlimButton::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
SetCapture();
|
||||
}
|
||||
|
||||
void SlimButton::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
ReleaseCapture();
|
||||
Action();
|
||||
}
|
||||
|
||||
void SlimButton::MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
}
|
||||
|
||||
void SlimButton::SetLabel(const char* s)
|
||||
{
|
||||
label = s;
|
||||
}
|
||||
|
||||
SlimButton::SlimButton()
|
||||
{
|
||||
fg = White;
|
||||
bg = Black;
|
||||
alpha = 255.f;
|
||||
}
|
||||
|
||||
InfoPanel::InfoPanel() : init(true), parent(NULL)
|
||||
{
|
||||
Add(alphaSlider.RightPos(199, 100).VSizePos(1, 0));
|
||||
Add(angleSlider.RightPos(100, 100).VSizePos(1, 0));
|
||||
Add(scaleSlider.RightPos(1, 100).VSizePos(1, 0));
|
||||
|
||||
alphaSlider.text = "Alpha";
|
||||
angleSlider.text = "Angle";
|
||||
scaleSlider.text = "Scale";
|
||||
|
||||
alphaSlider.shaded = true;
|
||||
angleSlider.shaded = true;
|
||||
scaleSlider.shaded = true;
|
||||
alphaSlider.immediate = true;
|
||||
angleSlider.immediate = true;
|
||||
scaleSlider.immediate = true;
|
||||
|
||||
alphaSlider.SetPos(255.f, 0.f, 255.f);
|
||||
angleSlider.SetPos(0.f, 0.f, 360.f);
|
||||
scaleSlider.SetPos(1.f, 1.f, 5.f);
|
||||
}
|
||||
|
||||
void InfoPanel::Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Size wsz = screenRect.GetSize();
|
||||
Color frameColor = Color(183, 183, 183);
|
||||
Color bgColor = Color(102, 102, 102);
|
||||
w.DrawRect(sz, bgColor);
|
||||
w.DrawRect(0, 0, 1, sz.cy, frameColor);
|
||||
w.DrawRect(0, 0, sz.cx, 1, frameColor);
|
||||
w.DrawRect(sz.cx - 1, 0, 1, sz.cy, frameColor);
|
||||
String info = Format("FPS: %.2f, Textures: %d (%d), Size: %d, %d", GetFps(), resources.textures.GetCount(), resources.bindedTextures, wsz.cx, wsz.cy);
|
||||
w.DrawText(5, sz.cy - 18, info, StdFont(), White);
|
||||
}
|
||||
|
||||
void InfoPanel::Init(Ctrl& parent, float angle, float scale, float alpha)
|
||||
{
|
||||
const int width = 585;
|
||||
SetRect((screenRect.Width() - width) / 2, screenRect.Height() - 22, width, 22);
|
||||
if(!init)
|
||||
return;
|
||||
init = false;
|
||||
this->parent = &parent;
|
||||
Show();
|
||||
alphaSlider.SetPos(alpha, 0.f, 255.f);
|
||||
angleSlider.SetPos(angle, 0.f, 360.f);
|
||||
scaleSlider.SetPos(scale, 1.f, 5.f);
|
||||
}
|
||||
|
||||
void InfoPanel::Show(bool b)
|
||||
{
|
||||
if(IsOpen())
|
||||
{
|
||||
if(!b)
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(b)
|
||||
PopUp(parent, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
float InfoPanel::GetAlpha()
|
||||
{
|
||||
return alphaSlider.GetPos();
|
||||
}
|
||||
|
||||
float InfoPanel::GetAngle()
|
||||
{
|
||||
return angleSlider.GetPos();
|
||||
}
|
||||
|
||||
float InfoPanel::GetScale()
|
||||
{
|
||||
return scaleSlider.GetPos();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
71
rainbow/CoreGl/ControlPanel.h
Normal file
71
rainbow/CoreGl/ControlPanel.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef _rainbow_CoreGl_ControlPanel_h_
|
||||
#define _rainbow_CoreGl_ControlPanel_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct ValueSlider : Ctrl
|
||||
{
|
||||
bool shaded;
|
||||
bool immediate;
|
||||
Color src;
|
||||
Color dst;
|
||||
|
||||
float pos;
|
||||
float minValue;
|
||||
float maxValue;
|
||||
String text;
|
||||
|
||||
typedef ValueSlider CLASSNAME;
|
||||
|
||||
ValueSlider();
|
||||
|
||||
virtual void Paint(Draw &w);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual void MouseMove(Point p, dword keyflags);
|
||||
|
||||
void SetPos(float p, float minValue, float maxValue);
|
||||
float GetPos();
|
||||
|
||||
Callback WhenLeftUp;
|
||||
};
|
||||
|
||||
struct SlimButton : Ctrl
|
||||
{
|
||||
Color fg;
|
||||
Color bg;
|
||||
float alpha;
|
||||
String label;
|
||||
virtual void Paint(Draw &w);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual void MouseMove(Point p, dword keyflags);
|
||||
void SetLabel(const char* s);
|
||||
SlimButton();
|
||||
};
|
||||
|
||||
struct InfoPanel : Ctrl
|
||||
{
|
||||
bool init;
|
||||
Ctrl* parent;
|
||||
|
||||
ValueSlider alphaSlider;
|
||||
ValueSlider angleSlider;
|
||||
ValueSlider scaleSlider;
|
||||
|
||||
float GetAlpha();
|
||||
float GetAngle();
|
||||
float GetScale();
|
||||
|
||||
void Init(Ctrl& parent, float angle = 0.f, float scale = 1.f, float alpha = 255.f);
|
||||
void Show(bool b = true);
|
||||
virtual void Paint(Draw& w);
|
||||
typedef InfoPanel CLASSNAME;
|
||||
InfoPanel();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
305
rainbow/CoreGl/CoreGl.h
Normal file
305
rainbow/CoreGl/CoreGl.h
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
#ifndef _CoreGl_CoreGl_h_
|
||||
#define _CoreGl_CoreGl_h_
|
||||
|
||||
#ifndef GLEW_STATIC
|
||||
#define GLEW_STATIC
|
||||
#endif
|
||||
|
||||
#define DRAW_ON_TIMER 0
|
||||
#define DRAW_ON_IDLE 1
|
||||
#define DRAW_ON_EVENT 2
|
||||
|
||||
#define CLIP_MODE 2
|
||||
/*
|
||||
0 - Scissor clip
|
||||
1 - Plane clip
|
||||
2 - Stencil clip
|
||||
3 - Manual clip
|
||||
*/
|
||||
#include "Gl.h"
|
||||
#include <Painter/Painter.h>
|
||||
|
||||
#include "Shaders.h"
|
||||
#include "Fbo.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct FrameInfo {
|
||||
int64 curr_tick_count;
|
||||
float fps;
|
||||
float frame_factor;
|
||||
float frame_skip;
|
||||
int64 frame_time;
|
||||
FrameInfo() : fps(0.f), frame_factor(1.f), frame_skip(60.f), frame_time(0), curr_tick_count(0)
|
||||
{}
|
||||
};
|
||||
|
||||
extern FrameInfo frameInfo;
|
||||
float GetFps();
|
||||
|
||||
#define IMAGECLASS CoreGlImg
|
||||
#define IMAGEFILE <CoreGl/CoreGl.iml>
|
||||
#include <Draw/iml_header.h>
|
||||
|
||||
#include "Resources.brc"
|
||||
|
||||
typedef Rect_<float> RectF;
|
||||
typedef Point_<float> PointF;
|
||||
|
||||
#include "FontGl.h"
|
||||
#include "ResGl.h"
|
||||
|
||||
enum TransformState {
|
||||
TS_BEFORE_CTRL_PAINT,
|
||||
TS_AFTER_CTRL_PAINT,
|
||||
TS_BEFORE_PAINT,
|
||||
TS_AFTER_PAINT,
|
||||
TS_BEFORE_SCREEN,
|
||||
TS_AFTER_SCREEN
|
||||
};
|
||||
|
||||
#define TEXEL_OFFSET 0.325f
|
||||
|
||||
class SystemDraw : public Draw {
|
||||
public:
|
||||
virtual dword GetInfo() const;
|
||||
virtual Size GetPageSize() const;
|
||||
bool CanSetSurface() { return false; }
|
||||
|
||||
void PlaneEquation(double eq[4], float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3);
|
||||
void SetClipRect(const Rect& r);
|
||||
void ScissorClip(const Rect& r);
|
||||
void PlaneClip(const Rect& r);
|
||||
void StencilClip(const Rect& r, int mode = 0, bool exlude = false);
|
||||
void SetClip(const Rect& r, int mode = 0, bool exclude = false);
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool ExcludeClipOp(const Rect& r);
|
||||
virtual bool IntersectClipOp(const Rect& r);
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
virtual Rect GetPaintRect() const;
|
||||
|
||||
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
|
||||
virtual void DrawImageOp(float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, const Image& img, const Rect& src, Color color);
|
||||
virtual void DrawTextureOp(const RectF& r, int textureId, int width, int height, const RectF& src);
|
||||
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
|
||||
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor);
|
||||
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor);
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
|
||||
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx);
|
||||
|
||||
virtual Size GetNativeDpi() const;
|
||||
virtual void BeginNative();
|
||||
virtual void EndNative();
|
||||
|
||||
virtual int GetCloffLevel() const;
|
||||
|
||||
void Text(int x, int y, int angle, const wchar *text, Font font, Color ink,
|
||||
int outlineStrength, Color outlineColor,
|
||||
int glowStrength, Color glowColor,
|
||||
int n, const int *dx);
|
||||
|
||||
void ImageColoring(bool b = true) { image_coloring = b; }
|
||||
|
||||
RectF UnProject(const RectF& r, float& depth);
|
||||
void UnProject(float* vtx, float sx, float sy, float dx, float dy);
|
||||
void UnProject(float& x, float& y, float &z);
|
||||
void SetVtx(float* vtx, float sx, float sy, float dx, float dy);
|
||||
void SetProjectionMode(int mode);
|
||||
bool IsPerspectiveProjection() { return projection_mode == 1; }
|
||||
bool IsOrthogonalProjection() { return projection_mode == 0; }
|
||||
|
||||
private:
|
||||
static SystemDraw* systemDraw;
|
||||
friend class FontInfo;
|
||||
friend class Font;
|
||||
|
||||
OpenGLFont fi;
|
||||
|
||||
struct Cloff : Moveable<Cloff> {
|
||||
bool clipping;
|
||||
bool exclude;
|
||||
Point org;
|
||||
Rect drawing_clip;
|
||||
};
|
||||
|
||||
struct MatrixStack : Moveable<MatrixStack>
|
||||
{
|
||||
double projection_matrix[16];
|
||||
double modelview_matrix[16];
|
||||
int projection_mode;
|
||||
};
|
||||
|
||||
float current_color[4];
|
||||
float vtx[8];
|
||||
float crd[8];
|
||||
double projection_matrix[16];
|
||||
void SetVec(float* v, float sx, float sy, float dx, float dy);
|
||||
void SetVec(float* v, int sx, int sy, int dx, int dy);
|
||||
|
||||
void SaveCurrentColor();
|
||||
void RestoreLastColor();
|
||||
|
||||
public:
|
||||
Rect drawing_clip;
|
||||
Size drawing_size;
|
||||
Point drawing_offset;
|
||||
Rect clip;
|
||||
float r, g, b, a;
|
||||
float alpha;
|
||||
float angle;
|
||||
float scale;
|
||||
static float blurStrength;
|
||||
static float grayStrength;
|
||||
|
||||
private:
|
||||
Array<Cloff> cloff;
|
||||
Array<MatrixStack> mstack;
|
||||
int ci;
|
||||
int cn;
|
||||
int cd;
|
||||
int mi;
|
||||
bool image_coloring;
|
||||
int projection_mode;
|
||||
|
||||
void Reset();
|
||||
|
||||
protected:
|
||||
|
||||
SystemDraw();
|
||||
void InitClip(const Rect& clip);
|
||||
void Init();
|
||||
|
||||
public:
|
||||
static SystemDraw& Get() { return *systemDraw; }
|
||||
static void Flush() { /*glFlush();*/ }
|
||||
Point GetOffset() const { return drawing_offset; }
|
||||
SystemDraw(Size sz);
|
||||
virtual ~SystemDraw();
|
||||
void ViewPort(int width = -1, int height = -1);
|
||||
void OrthogonalView(bool clear_modelview = true);
|
||||
void PerspectiveView(bool clear_modelview = true);
|
||||
void ApplyTransforms();
|
||||
void Clear(bool ontransforms = false);
|
||||
void PushContext();
|
||||
void PopContext();
|
||||
float GetAspect() { return drawing_size.cx / (float) drawing_size.cy; };
|
||||
};
|
||||
|
||||
struct BackDraw__ : public SystemDraw {
|
||||
BackDraw__() {}
|
||||
};
|
||||
|
||||
class BackDraw : public BackDraw__ { // Dummy only, as we are running in GlobalBackBuffer mode
|
||||
Size size;
|
||||
Draw *painting;
|
||||
Point painting_offset;
|
||||
ImageBuffer ib;
|
||||
|
||||
public:
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
public:
|
||||
void Put(SystemDraw& w, int x, int y) {}
|
||||
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
|
||||
|
||||
void Create(SystemDraw& w, int cx, int cy) {}
|
||||
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
|
||||
void Destroy() {}
|
||||
|
||||
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
|
||||
|
||||
BackDraw();
|
||||
~BackDraw();
|
||||
};
|
||||
|
||||
struct ImageDraw__ {
|
||||
ImageBuffer image;
|
||||
ImageBuffer alpha;
|
||||
|
||||
ImageDraw__(int cx, int cy) : image(cx, cy), alpha(cx, cy) {}
|
||||
};
|
||||
|
||||
class ImageDraw : private ImageDraw__, public BufferPainter {
|
||||
BufferPainter alpha_painter;
|
||||
bool has_alpha;
|
||||
|
||||
Image Get(bool pm) const;
|
||||
|
||||
public:
|
||||
Draw& Alpha();
|
||||
|
||||
operator Image() const { return Get(true); }
|
||||
|
||||
Image GetStraight() const { return Get(false); }
|
||||
|
||||
ImageDraw(Size sz);
|
||||
ImageDraw(int cx, int cy);
|
||||
};
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation);
|
||||
|
||||
class PrinterJob { // Dummy only...
|
||||
NilDraw nil;
|
||||
Vector<int> pages;
|
||||
|
||||
public:
|
||||
Draw& GetDraw() { return nil; }
|
||||
operator Draw&() { return GetDraw(); }
|
||||
const Vector<int>& GetPages() const { return pages; }
|
||||
int operator[](int i) const { return 0; }
|
||||
int GetPageCount() const { return 0; }
|
||||
|
||||
bool Execute() { return false; }
|
||||
|
||||
PrinterJob& Landscape(bool b = true) { return *this; }
|
||||
PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; }
|
||||
PrinterJob& PageCount(int n) { return *this; }
|
||||
PrinterJob& CurrentPage(int currentpage) { return *this; }
|
||||
PrinterJob& Name(const char *_name) { return *this; }
|
||||
|
||||
PrinterJob(const char *name = NULL) {}
|
||||
~PrinterJob() {}
|
||||
};
|
||||
|
||||
class TopWindowFrame;
|
||||
struct InfoPanel;
|
||||
struct Console;
|
||||
void GlLog(int line, const char* text, Color ink = White);
|
||||
void GlLog(const char* text, Color ink = White);
|
||||
void GlLogF(Color ink, const char* fmt, ...);
|
||||
void GlLogF(const char* fmt, ...);
|
||||
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window;
|
||||
#define GUIPLATFORM_CTRL_DECLS_INCLUDE <CoreGl/Ctrl.h>
|
||||
#define GUIPLATFORM_PASTECLIP_DECLS \
|
||||
bool dnd; \
|
||||
friend struct DnDLoop;
|
||||
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <CoreGl/Top.h>
|
||||
|
||||
#ifdef flagLINUXGL
|
||||
#define GUIPLATFORM_INCLUDE_AFTER <LinuxGl/After.h>
|
||||
#endif
|
||||
|
||||
#ifdef flagWINGL
|
||||
#define GUIPLATFORM_INCLUDE_AFTER <WinGl/After.h>
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
60
rainbow/CoreGl/CoreGl.iml
Normal file
60
rainbow/CoreGl/CoreGl.iml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
PREMULTIPLIED
|
||||
IMAGE_ID(arrow)
|
||||
IMAGE_ID(ibeam)
|
||||
IMAGE_ID(wait)
|
||||
IMAGE_ID(no)
|
||||
IMAGE_ID(sizeall)
|
||||
IMAGE_ID(sizehorz)
|
||||
IMAGE_ID(sizeright)
|
||||
IMAGE_ID(sizeleft)
|
||||
IMAGE_ID(sizevert)
|
||||
IMAGE_ID(sizetopleft)
|
||||
IMAGE_ID(sizetop)
|
||||
IMAGE_ID(sizetopright)
|
||||
IMAGE_ID(sizebottomleft)
|
||||
IMAGE_ID(sizebottom)
|
||||
IMAGE_ID(sizebottomright)
|
||||
IMAGE_ID(overlap)
|
||||
IMAGE_ID(maximize)
|
||||
IMAGE_ID(close)
|
||||
IMAGE_ID(bgtitle)
|
||||
IMAGE_ID(title)
|
||||
IMAGE_ID(border)
|
||||
IMAGE_ID(hand)
|
||||
IMAGE_ID(ResizeMarker)
|
||||
|
||||
IMAGE_BEGIN_DATA
|
||||
IMAGE_DATA(120,156,237,90,205,75,85,65,20,159,50,211,66,9,137,118,46,218,180,233,79,136,160,109,203,192,130,32,218,228,34,90)
|
||||
IMAGE_DATA(180,171,69,148,249,130,136,32,66,131,44,9,75,203,2,53,107,241,54,34,42,234,194,15,4,63,240,3,30,162,8,34)
|
||||
IMAGE_DATA(136,136,160,43,221,157,230,61,223,199,120,238,220,51,231,204,187,207,10,238,25,14,58,119,126,191,51,103,126,231,220,123)
|
||||
IMAGE_DATA(159,31,170,74,93,80,105,59,173,78,164,191,128,146,25,8,57,0,32,226,192,193,193,69,216,223,191,196,229,192,222,222)
|
||||
IMAGE_DATA(21,216,221,189,6,59,59,215,57,28,216,222,190,1,91,91,55,97,115,243,14,172,175,215,187,56,176,177,81,175,113,247)
|
||||
IMAGE_DATA(97,109,237,33,172,174,62,130,84,234,41,197,129,149,149,199,176,188,252,68,227,26,97,113,241,21,204,207,191,133,217,217)
|
||||
IMAGE_DATA(230,48,14,44,45,189,132,133,133,215,48,55,215,4,51,51,173,48,53,213,9,147,147,223,97,98,162,221,198,209,152,102)
|
||||
IMAGE_DATA(152,158,126,175,113,109,48,62,222,13,35,35,35,89,255,5,195,195,157,152,163,99,181,106,92,27,140,141,117,194,232,232)
|
||||
IMAGE_DATA(239,60,94,21,106,105,114,52,230,179,246,14,24,26,250,1,131,131,63,161,191,63,73,158,119,96,160,29,250,250,190,230)
|
||||
IMAGE_DATA(227,36,147,221,36,62,153,252,18,200,177,171,235,91,168,62,54,13,58,58,62,81,120,235,190,45,45,239,68,125,216,212)
|
||||
IMAGE_DATA(244,70,220,235,137,196,115,209,30,13,13,207,196,123,8,176,65,43,87,231,212,73,85,145,113,133,10,175,50,55,235,161)
|
||||
IMAGE_DATA(161,239,243,155,163,249,127,127,45,228,188,1,93,84,149,22,174,92,139,86,126,84,56,174,103,56,181,61,31,72,55,176)
|
||||
IMAGE_DATA(199,129,39,57,22,108,40,135,192,6,56,12,108,158,35,193,250,228,226,115,86,31,45,255,66,125,101,253,89,163,71,101)
|
||||
IMAGE_DATA(118,80,194,89,156,107,220,155,132,195,47,102,93,146,103,177,252,64,1,25,49,236,79,31,127,126,88,94,82,62,55,134)
|
||||
IMAGE_DATA(100,221,181,7,39,71,234,156,148,185,52,150,240,109,57,73,122,197,118,205,151,207,141,227,115,223,249,220,183,174,88,118)
|
||||
IMAGE_DATA(99,62,144,14,163,6,95,239,34,51,95,255,197,240,115,46,141,131,249,62,113,192,48,52,117,198,192,56,155,30,84,172)
|
||||
IMAGE_DATA(48,60,231,154,121,29,231,109,59,11,198,98,190,143,219,226,248,228,17,149,30,81,213,197,22,203,118,22,23,23,239,143)
|
||||
IMAGE_DATA(93,18,195,22,71,202,199,113,124,249,40,14,109,53,250,99,127,165,42,203,56,38,187,2,80,24,238,33,194,112,84,211)
|
||||
IMAGE_DATA(218,76,169,227,191,121,56,121,68,165,135,185,238,85,151,184,208,113,161,253,2,50,19,118,225,138,21,216,188,230,227,182)
|
||||
IMAGE_DATA(56,62,121,68,165,135,185,238,85,151,10,93,234,178,108,169,45,27,178,19,193,194,186,4,183,9,132,230,206,131,255,235)
|
||||
IMAGE_DATA(107,212,249,40,93,40,61,57,185,24,235,5,171,214,227,116,118,4,50,65,162,19,1,201,164,92,28,23,190,88,14,22)
|
||||
IMAGE_DATA(219,197,193,197,226,238,23,182,119,177,60,73,29,36,103,53,121,170,132,181,240,237,17,107,47,198,79,166,210,173,81,231)
|
||||
IMAGE_DATA(163,116,161,244,228,228,98,172,23,204,124,50,81,22,200,18,21,132,216,236,88,159,66,92,14,22,223,197,161,10,201,197)
|
||||
IMAGE_DATA(227,117,28,75,146,3,7,111,114,212,49,235,207,205,77,218,83,113,195,198,13,91,18,14,55,55,113,195,198,175,210,210)
|
||||
IMAGE_DATA(173,81,231,163,116,161,244,228,228,98,172,23,44,254,144,31,228,224,98,113,247,11,219,187,88,158,164,14,146,179,154,60)
|
||||
IMAGE_DATA(85,194,90,248,246,136,181,23,171,244,136,200,172,119,154,225,54,60,21,203,23,207,201,3,227,93,123,70,133,231,232,83)
|
||||
IMAGE_DATA(42,93,204,107,146,58,241,45,130,102,114,37,39,17,203,134,137,241,209,227,37,245,226,91,20,79,166,171,213,213,161,155)
|
||||
IMAGE_DATA(227,181,244,60,231,54,172,109,205,118,157,138,131,215,93,216,48,14,133,149,226,37,249,72,206,235,171,39,149,39,117,14)
|
||||
IMAGE_DATA(210,78,233,145,179,186,186,86,184,253,160,23,238,190,232,133,123,31,123,65,58,207,7,43,203,252,109,38,1,103,46,247)
|
||||
IMAGE_DATA(192,249,91,75,80,219,152,126,9,11,231,233,54,47,215,35,251,179,44,247,126,58,242,230,119,153,249,255,212,185,57,229)
|
||||
IMAGE_DATA(137,68,34,198,151,8,159,155,187,220,167,23,50,205,228,248,197,8,245,233,5,227,32,149,74,29,249,26,134,197,56,3)
|
||||
IMAGE_DATA(111,253,4,18,134,71,251,228,99,112,241,46,156,13,159,115,41,62,204,209,153,165,120,39,135,210,148,137,229,225,207,234)
|
||||
IMAGE_DATA(225,99,250,161,6,148,199,56,26,199,177,63,147,104,81,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
IMAGE_END_DATA(1056, 23)
|
||||
57
rainbow/CoreGl/CoreGl.upp
Normal file
57
rainbow/CoreGl/CoreGl.upp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
uses
|
||||
Painter;
|
||||
|
||||
options(WIN32) "-D_WIN32 -DGLEW_STATIC";
|
||||
|
||||
file
|
||||
Gl.h,
|
||||
CoreGl.h,
|
||||
FontGl.h,
|
||||
ResGl.h,
|
||||
ControlPanel.h,
|
||||
ControlPanel.cpp,
|
||||
Scrollbar.h,
|
||||
Scrollbar.cpp,
|
||||
Console.h,
|
||||
Console.cpp,
|
||||
Draw.cpp,
|
||||
DrawOp.cpp,
|
||||
DrawText.cpp,
|
||||
Clip.cpp,
|
||||
Ctrl.h,
|
||||
Ctrl.cpp,
|
||||
Dnd.cpp,
|
||||
Event.cpp,
|
||||
Wnd.cpp,
|
||||
Image.cpp,
|
||||
Top.h,
|
||||
Top.cpp,
|
||||
TopFrame.h,
|
||||
TopFrame.cpp,
|
||||
ChSysInit.cpp,
|
||||
Util.cpp,
|
||||
Glew readonly separator,
|
||||
glew.h,
|
||||
glxew.h,
|
||||
wglew.h,
|
||||
glew.c,
|
||||
SceneGraph readonly separator,
|
||||
SceneGraph.h,
|
||||
SceneGraph.cpp,
|
||||
Resources readonly separator,
|
||||
Resources.cpp,
|
||||
Resources.brc,
|
||||
Fbo.h,
|
||||
Fbo.cpp,
|
||||
Shaders.h,
|
||||
Shaders.cpp,
|
||||
AlphaMag.vert,
|
||||
AlphaMag.frag,
|
||||
Blur.vert,
|
||||
Blur.frag,
|
||||
Fonts/TahomaB.fnt,
|
||||
Fonts/TahomaB_0.png,
|
||||
Fonts/TahomaN.fnt,
|
||||
Fonts/TahomaN_0.png,
|
||||
CoreGl.iml;
|
||||
|
||||
97
rainbow/CoreGl/Ctrl.cpp
Normal file
97
rainbow/CoreGl/Ctrl.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
int Ctrl::Xbuttons;
|
||||
int Ctrl::Xbuttontime;
|
||||
Point Ctrl::Xbuttonpos;
|
||||
|
||||
void Ctrl::GuiPlatformConstruct()
|
||||
{
|
||||
cliptobounds = true;
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformRemove()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformGetTopRect(Rect& r) const
|
||||
{
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformSetFullRefreshSpecial()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
}
|
||||
|
||||
String GuiPlatformGetKeyDesc(dword key)
|
||||
{
|
||||
return Null;
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformSelection(PasteClip&)
|
||||
{
|
||||
}
|
||||
|
||||
void GuiPlatformAdjustDragImage(ImageBuffer&)
|
||||
{
|
||||
}
|
||||
|
||||
bool GuiPlatformHasSizeGrip()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiPlatformGripResize(TopWindow *q)
|
||||
{
|
||||
q->GripResize();
|
||||
}
|
||||
|
||||
Color GuiPlatformGetScreenPixel(int x, int y)
|
||||
{
|
||||
return Black;
|
||||
}
|
||||
|
||||
void GuiPlatformAfterMenuPopUp()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::InstallPanicBox()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::ApplyLayout()
|
||||
{
|
||||
GuiLock __;
|
||||
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
|
||||
q->ApplyLayout();
|
||||
}
|
||||
|
||||
String Ctrl::Name() const {
|
||||
GuiLock __;
|
||||
#ifdef CPU_64
|
||||
String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this);
|
||||
#else
|
||||
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
|
||||
#endif
|
||||
if(IsChild())
|
||||
s << "(parent " << String(typeid(*parent).name()) << ")";
|
||||
return s;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
83
rainbow/CoreGl/Ctrl.h
Normal file
83
rainbow/CoreGl/Ctrl.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//$ class Ctrl {
|
||||
static Ptr<Ctrl> desktop;
|
||||
static Vector<Ctrl *> topctrl;
|
||||
static InfoPanel infoPanel;
|
||||
|
||||
static float angle;
|
||||
static float scale;
|
||||
static float alpha;
|
||||
|
||||
static Point glCursorPos;
|
||||
static Image glCursorImage;
|
||||
static Rect glCaretRect;
|
||||
static int glCaretTm;
|
||||
|
||||
static int64 glEventLoop;
|
||||
static int64 glEndSessionLoop;
|
||||
|
||||
bool cliptobounds:1;
|
||||
|
||||
int FindTopCtrl() const;
|
||||
static void SyncTopWindows();
|
||||
void DestroyWnd();
|
||||
void NewTop() { top = new Top; top->owner_window = NULL; }
|
||||
void PutForeground();
|
||||
static void MouseEventGl(Ptr<Ctrl> t, int event, Point p, int zdelta);
|
||||
|
||||
static void DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz,
|
||||
const byte *pattern, int animation);
|
||||
static void DragRectDraw0(const Vector<Rect>& clip, const Rect& rect, int n,
|
||||
const byte *pattern, int animation);
|
||||
|
||||
|
||||
friend class TopWindowFrame;
|
||||
friend class SystemDraw;
|
||||
friend struct DnDLoop;
|
||||
|
||||
void SetOpen(bool b) { isopen = b; }
|
||||
|
||||
protected:
|
||||
static int PaintLock;
|
||||
|
||||
public:
|
||||
static int Xbuttons;
|
||||
static int Xbuttontime;
|
||||
static Point Xbuttonpos;
|
||||
|
||||
static Console console;
|
||||
static Rect screenRect;
|
||||
static bool screenReady;
|
||||
|
||||
static void InitGl();
|
||||
static void ExitGl();
|
||||
static void EndSession();
|
||||
static bool DoMouseGl(Ctrl* q, int event, Point p, int zdelta);
|
||||
static void DoMouseGl(int event, Point p, int zdelta = 0);
|
||||
static bool DoKeyGl(dword key, int cnt);
|
||||
static void CursorSync(Draw& w);
|
||||
static void MouseSync(Draw& w);
|
||||
|
||||
static void SetDesktop(Ctrl& q);
|
||||
static Ctrl *GetDesktop() { return desktop; }
|
||||
static void SetWindowSize(Size sz);
|
||||
static Size GetScreenSize() { return screenRect.GetSize(); }
|
||||
static dword GetCaretTm() { return glCaretTm; }
|
||||
static void ResetCaretTm() { glCaretTm = GetTickCount(); }
|
||||
|
||||
static void DrawScreen();
|
||||
|
||||
Ctrl& ClipToBounds(bool b = true) { cliptobounds = b; return *this; }
|
||||
bool IsClipToBounds() const { return cliptobounds; }
|
||||
|
||||
|
||||
virtual void ApplyTransform(TransformState state) {}
|
||||
virtual void PostPaint(Draw& w) {}
|
||||
virtual void ApplyLayout();
|
||||
void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
|
||||
static Ctrl *FindMouseTopCtrl();
|
||||
|
||||
enum { DRAWDRAGRECT_SCREEN = 0x8000 };
|
||||
|
||||
//$ };
|
||||
150
rainbow/CoreGl/Dnd.cpp
Normal file
150
rainbow/CoreGl/Dnd.cpp
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
Ptr<Ctrl> sDnDSource;
|
||||
|
||||
Ctrl * Ctrl::GetDragAndDropSource()
|
||||
{
|
||||
return sDnDSource;
|
||||
}
|
||||
|
||||
struct DnDLoop : LocalLoop {
|
||||
const VectorMap<String, ClipData> *data;
|
||||
Vector<String> fmts;
|
||||
|
||||
Image move, copy, reject;
|
||||
Ptr<Ctrl> target;
|
||||
int action;
|
||||
byte actions;
|
||||
|
||||
void Sync();
|
||||
String GetData(const String& f);
|
||||
void DnD(bool paste);
|
||||
|
||||
virtual void LeftUp(Point, dword);
|
||||
virtual bool Key(dword, int);
|
||||
virtual void MouseMove(Point p, dword);
|
||||
virtual Image CursorImage(Point, dword);
|
||||
};
|
||||
|
||||
Ptr<DnDLoop> dndloop;
|
||||
|
||||
bool PasteClip::IsAvailable(const char *fmt) const
|
||||
{
|
||||
GuiLock __;
|
||||
return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0
|
||||
: IsClipboardAvailable(fmt);
|
||||
}
|
||||
|
||||
String DnDLoop::GetData(const String& f)
|
||||
{
|
||||
GuiLock __;
|
||||
int i = data->Find(f);
|
||||
String d;
|
||||
if(i >= 0)
|
||||
d = (*data)[i].Render();
|
||||
else
|
||||
if(sDnDSource)
|
||||
d = sDnDSource->GetDropData(f);
|
||||
return d;
|
||||
}
|
||||
|
||||
String PasteClip::Get(const char *fmt) const
|
||||
{
|
||||
return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt);
|
||||
}
|
||||
|
||||
void PasteClip::GuiPlatformConstruct()
|
||||
{
|
||||
dnd = false;
|
||||
}
|
||||
|
||||
void DnDLoop::DnD(bool paste)
|
||||
{
|
||||
PasteClip d;
|
||||
d.paste = paste;
|
||||
d.accepted = false;
|
||||
d.allowed = (byte)actions;
|
||||
d.action = GetCtrl() ? DND_COPY : DND_MOVE;
|
||||
d.dnd = true;
|
||||
if(target)
|
||||
target->DnD(GetMousePos(), d);
|
||||
action = d.IsAccepted() ? d.GetAction() : DND_NONE;
|
||||
}
|
||||
|
||||
void DnDLoop::Sync()
|
||||
{
|
||||
GuiLock __;
|
||||
Ptr<Ctrl> t = FindMouseTopCtrl();
|
||||
if(t != target)
|
||||
if(target)
|
||||
target->DnDLeave();
|
||||
target = t;
|
||||
DnD(false);
|
||||
}
|
||||
|
||||
void DnDLoop::LeftUp(Point, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::LeftUp");
|
||||
DnD(true);
|
||||
EndLoop();
|
||||
}
|
||||
|
||||
void DnDLoop::MouseMove(Point p, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::MouseMove");
|
||||
Sync();
|
||||
}
|
||||
|
||||
bool DnDLoop::Key(dword, int)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::Key");
|
||||
Sync();
|
||||
return false;
|
||||
}
|
||||
|
||||
Image DnDLoop::CursorImage(Point, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
return action == DND_MOVE ? move : action == DND_COPY ? copy : reject;
|
||||
}
|
||||
|
||||
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
|
||||
const VectorMap<String, ClipData>& data)
|
||||
{
|
||||
GuiLock __;
|
||||
DnDLoop d;
|
||||
d.actions = (byte)actions;
|
||||
d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample);
|
||||
if(actions & DND_COPY)
|
||||
d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample);
|
||||
if(actions & DND_MOVE)
|
||||
d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample);
|
||||
d.SetMaster(*this);
|
||||
d.data = &data;
|
||||
d.action = DND_NONE;
|
||||
d.fmts = Split(fmts, ';');
|
||||
dndloop = &d;
|
||||
sDnDSource = this;
|
||||
d.Run();
|
||||
sDnDSource = NULL;
|
||||
SyncCaret();
|
||||
LLOG("DoDragAndDrop finished");
|
||||
return d.action;
|
||||
}
|
||||
|
||||
void Ctrl::SetSelectionSource(const char *fmts) {}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
189
rainbow/CoreGl/Draw.cpp
Normal file
189
rainbow/CoreGl/Draw.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
FrameInfo frameInfo;
|
||||
SystemDraw* SystemDraw::systemDraw = NULL;
|
||||
float SystemDraw::blurStrength = 0;
|
||||
float SystemDraw::grayStrength = 0;
|
||||
|
||||
dword SystemDraw::GetInfo() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size SystemDraw::GetPageSize() const
|
||||
{
|
||||
return Size(0, 0);
|
||||
}
|
||||
|
||||
Size SystemDraw::GetNativeDpi() const
|
||||
{
|
||||
return Size(96, 96);
|
||||
}
|
||||
|
||||
void SystemDraw::BeginNative()
|
||||
{
|
||||
}
|
||||
|
||||
void SystemDraw::EndNative()
|
||||
{
|
||||
}
|
||||
|
||||
int SystemDraw::GetCloffLevel() const
|
||||
{
|
||||
return ci;
|
||||
}
|
||||
|
||||
void SystemDraw::InitClip(const Rect& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
drawing_clip = clip;
|
||||
}
|
||||
|
||||
void SystemDraw::Reset() {
|
||||
systemDraw = this;
|
||||
cloff.SetCount(32);
|
||||
mstack.SetCount(32);
|
||||
ci = 0;
|
||||
cn = 0;
|
||||
cd = 0;
|
||||
mi = 0;
|
||||
drawing_offset = Point(0, 0);
|
||||
alpha = 255;
|
||||
r = g = b = a = 255;
|
||||
angle = 0;
|
||||
scale = 1;
|
||||
image_coloring = true;
|
||||
projection_mode = 0;
|
||||
}
|
||||
|
||||
SystemDraw::SystemDraw() {
|
||||
GuiLock __;
|
||||
Reset();
|
||||
}
|
||||
|
||||
SystemDraw::SystemDraw(Size sz) {
|
||||
GuiLock __;
|
||||
Reset();
|
||||
drawing_clip = sz;
|
||||
drawing_size = sz;
|
||||
clip = sz;
|
||||
Init();
|
||||
}
|
||||
|
||||
void SystemDraw::Init()
|
||||
{
|
||||
//glVertexPointer(2, GL_FLOAT, 0, vtx);
|
||||
//glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
#if CLIP_MODE == 0
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#elif CLIP_MODE == 1
|
||||
glEnable(GL_CLIP_PLANE0);
|
||||
glEnable(GL_CLIP_PLANE1);
|
||||
glEnable(GL_CLIP_PLANE2);
|
||||
glEnable(GL_CLIP_PLANE3);
|
||||
#elif CLIP_MODE == 2
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glClearStencil(0);
|
||||
#endif
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glClearDepth(1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
|
||||
void SystemDraw::Clear(bool ontransforms)
|
||||
{
|
||||
GuiLock __;
|
||||
if(ontransforms && (angle == 0 && scale == 1))
|
||||
return;
|
||||
#if CLIP_MODE == 0
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#endif
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
#if CLIP_MODE == 0
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemDraw::ViewPort(int width, int height)
|
||||
{
|
||||
GuiLock __;
|
||||
glViewport(0, 0, (GLsizei) width < 0 ? drawing_size.cx : width, (GLsizei) height < 0 ? drawing_size.cy : height);
|
||||
}
|
||||
|
||||
void SystemDraw::OrthogonalView(bool clear_modelview)
|
||||
{
|
||||
GuiLock __;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, drawing_size.cx, drawing_size.cy, 0, -100, 100);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if(clear_modelview)
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void SystemDraw::PerspectiveView(bool clear_modelview)
|
||||
{
|
||||
GuiLock __;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(45.0f, GetAspect(), 1.f, 100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if(clear_modelview)
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void SystemDraw::ApplyTransforms()
|
||||
{
|
||||
GuiLock __;
|
||||
float dx = (float) drawing_size.cx / 2;
|
||||
float dy = (float) drawing_size.cy / 2;
|
||||
glTranslatef(dx, dy, 0.f);
|
||||
glRotatef(angle, 0, 0, 1);
|
||||
glScalef(scale, scale, 1);
|
||||
glTranslatef(-dx, -dy, 0.f);
|
||||
}
|
||||
|
||||
void SystemDraw::PushContext()
|
||||
{
|
||||
GuiLock __;
|
||||
MatrixStack& m = mstack[mi++];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, m.projection_matrix);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, m.modelview_matrix);
|
||||
m.projection_mode = projection_mode;
|
||||
}
|
||||
|
||||
void SystemDraw::PopContext()
|
||||
{
|
||||
GuiLock __;
|
||||
MatrixStack& m = mstack[--mi];
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixd(m.projection_matrix);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixd(m.modelview_matrix);
|
||||
projection_mode = m.projection_mode;
|
||||
}
|
||||
|
||||
SystemDraw::~SystemDraw() {
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
657
rainbow/CoreGl/DrawOp.cpp
Normal file
657
rainbow/CoreGl/DrawOp.cpp
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
void SystemDraw::PlaneEquation(double eq[4], float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
|
||||
{
|
||||
eq[0] = y1 * (z2 - z3) +
|
||||
y2 * (z3 - z1) +
|
||||
y3 * (z1 - z2);
|
||||
|
||||
eq[1] = z1 * (x2 - x3) +
|
||||
z2 * (x3 - x1) +
|
||||
z3 * (x1 - x2);
|
||||
|
||||
eq[2] = x1 * (y2 - y3) +
|
||||
x2 * (y3 - y1) +
|
||||
x3 * (y1 - y2);
|
||||
|
||||
eq[3] = -(x1 * (y2 * z3 - y3 * z2) +
|
||||
x2 * (y3 * z1 - y1 * z3) +
|
||||
x3 * (y1 * z2 - y2 * z1));
|
||||
}
|
||||
|
||||
void SystemDraw::SetClipRect(const Rect& r)
|
||||
{
|
||||
clip = r;
|
||||
#if CLIP_MODE != 2
|
||||
for(int i = 0; i < ci; i++)
|
||||
if(!cloff[i].exclude)
|
||||
clip &= cloff[i].drawing_clip;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemDraw::ScissorClip(const Rect& r)
|
||||
{
|
||||
glScissor(r.left, drawing_size.cy - r.top - r.Height(), r.Width(), r.Height());
|
||||
}
|
||||
|
||||
void SystemDraw::PlaneClip(const Rect& r)
|
||||
{
|
||||
float cl = (float) r.left;
|
||||
float ct = (float) r.top;
|
||||
float cr = (float) r.right;
|
||||
float cb = (float) r.bottom;
|
||||
|
||||
double eq[4];
|
||||
|
||||
PlaneEquation(eq, cl, ct, 0, cl, cb, 0, cl, cb, +1.0f);
|
||||
glClipPlane(GL_CLIP_PLANE0, eq);
|
||||
|
||||
PlaneEquation(eq, cr, ct, 0, cr, cb, 0, cr, cb, -1.0f);
|
||||
glClipPlane(GL_CLIP_PLANE1, eq);
|
||||
|
||||
PlaneEquation(eq, cl, ct, 0, cr, ct, 0, cr, ct, -1.0f);
|
||||
glClipPlane(GL_CLIP_PLANE2, eq);
|
||||
|
||||
PlaneEquation(eq, cl, cb, 0, cr, cb, 0, cr, cb, +1.0f);
|
||||
glClipPlane(GL_CLIP_PLANE3, eq);
|
||||
}
|
||||
|
||||
void SystemDraw::SetVec(float* v, float sx, float sy, float dx, float dy)
|
||||
{
|
||||
v[0] = sx; v[1] = dy;
|
||||
v[2] = sx; v[3] = sy;
|
||||
v[4] = dx; v[5] = dy;
|
||||
v[6] = dx; v[7] = sy;
|
||||
}
|
||||
|
||||
void SystemDraw::SetVec(float* v, int sx, int sy, int dx, int dy)
|
||||
{
|
||||
v[0] = (float) sx; v[1] = (float) dy;
|
||||
v[2] = (float) sx; v[3] = (float) sy;
|
||||
v[4] = (float) dx; v[5] = (float) dy;
|
||||
v[6] = (float) dx; v[7] = (float) sy;
|
||||
}
|
||||
|
||||
void SystemDraw::StencilClip(const Rect& r, int mode, bool exclude)
|
||||
{
|
||||
float vtx[12];
|
||||
SetVtx(vtx, (float) r.left, (float) r.top, (float) r.right, (float) r.bottom);
|
||||
|
||||
glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx);
|
||||
|
||||
int prev_cn = cn;
|
||||
|
||||
glColorMask(0, 0, 0, 0);
|
||||
|
||||
if(mode == 0)
|
||||
{
|
||||
if(exclude)
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 255, ~0);
|
||||
}
|
||||
else
|
||||
{
|
||||
++cn;
|
||||
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
|
||||
glStencilFunc(GL_GEQUAL, cn, ~0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(exclude)
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, cn, ~0);
|
||||
}
|
||||
else
|
||||
{
|
||||
--cn;
|
||||
glStencilOp(GL_KEEP, GL_DECR, GL_DECR);
|
||||
glStencilFunc(GL_ALWAYS, cn, ~0);
|
||||
}
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
if(exclude)
|
||||
glStencilFunc(GL_GREATER, 255, ~0);
|
||||
else
|
||||
glStencilFunc(GL_EQUAL, cn, ~0);
|
||||
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
void SystemDraw::SetClip(const Rect& r, int mode, bool exclude)
|
||||
{
|
||||
SetClipRect(r);
|
||||
#if CLIP_MODE == 0
|
||||
ScissorClip(clip);
|
||||
#elif CLIP_MODE == 1
|
||||
PlaneClip(clip);
|
||||
#elif CLIP_MODE == 2
|
||||
StencilClip(clip, mode, exclude);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemDraw::BeginOp()
|
||||
{
|
||||
Cloff& w = cloff[ci++];
|
||||
w.clipping = false;
|
||||
w.exclude = false;
|
||||
w.org = drawing_offset;
|
||||
w.drawing_clip = drawing_clip;
|
||||
}
|
||||
|
||||
void SystemDraw::EndOp()
|
||||
{
|
||||
ASSERT(ci);
|
||||
#if CLIP_MODE == 2
|
||||
if(cloff[ci - 1].clipping)
|
||||
SetClip(drawing_clip, 1, cloff[ci - 1].exclude);
|
||||
#endif
|
||||
Cloff& w = cloff[--ci];
|
||||
drawing_offset = w.org;
|
||||
drawing_clip = w.drawing_clip;
|
||||
#if CLIP_MODE != 2
|
||||
if(cloff[ci].clipping)
|
||||
SetClip(drawing_clip);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemDraw::OffsetOp(Point p)
|
||||
{
|
||||
GuiLock __;
|
||||
BeginOp();
|
||||
drawing_offset += p;
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipOp(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
BeginOp();
|
||||
cloff[ci - 1].clipping = true;
|
||||
drawing_clip = r + drawing_offset;
|
||||
SetClip(drawing_clip);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
BeginOp();
|
||||
cloff[ci - 1].clipping = true;
|
||||
drawing_clip = r + drawing_offset;
|
||||
drawing_offset += r.TopLeft();
|
||||
SetClip(drawing_clip);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(ci > 0);
|
||||
cloff[ci - 1].clipping = true;
|
||||
cloff[ci - 1].exclude = true;
|
||||
drawing_clip = r + drawing_offset;
|
||||
SetClip(drawing_clip, 0, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
Cloff& w = cloff[ci];
|
||||
drawing_clip = r + drawing_offset;
|
||||
SetClip(drawing_clip);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect SystemDraw::GetPaintRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
return drawing_clip;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
if(IsNull(color))
|
||||
return;
|
||||
|
||||
if(cx <= 0 || cy <= 0) return;
|
||||
|
||||
float sx = (float) x + drawing_offset.x;
|
||||
float sy = (float) y + drawing_offset.y;
|
||||
float dx = sx + cx;
|
||||
float dy = sy + cy;
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
float cl = (float) clip.left;
|
||||
float ct = (float) clip.top;
|
||||
float cr = (float) clip.right;
|
||||
float cb = (float) clip.bottom;
|
||||
|
||||
if(sx > cr || sy > cb)
|
||||
return;
|
||||
|
||||
if(dx < cl || dy < ct)
|
||||
return;
|
||||
|
||||
if(sx < cl)
|
||||
sx = cl;
|
||||
if(sy < ct)
|
||||
sy = ct;
|
||||
if(dx > cr)
|
||||
dx = cr;
|
||||
if(dy > cb)
|
||||
dy = cb;
|
||||
#endif
|
||||
|
||||
#ifdef COLOR_ALPHA
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), color.GetA() >= 255 ? (int) alpha : color.GetA());
|
||||
#else
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha);
|
||||
#endif
|
||||
|
||||
float vtx[12];
|
||||
SetVtx(vtx, sx, sy, dx, dy);
|
||||
|
||||
glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
#ifdef COLOR_ALPHA
|
||||
glColor4ub(255, 255, 255, 255);
|
||||
#else
|
||||
glColor4ub(255, 255, 255, (int) alpha);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
if(cx <= 0 || cy <= 0) return;
|
||||
|
||||
float sx = (float) x + drawing_offset.x;
|
||||
float sy = (float) y + drawing_offset.y;
|
||||
float dx = sx + cx;
|
||||
float dy = sy + cy;
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
if(sx > clip.right || sy > clip.bottom)
|
||||
return;
|
||||
|
||||
if(dx < clip.left || dy < clip.top)
|
||||
return;
|
||||
#endif
|
||||
|
||||
float tl = (float) src.left;
|
||||
float tr = (float) src.right;
|
||||
float tt = (float) src.top;
|
||||
float tb = (float) src.bottom;
|
||||
|
||||
float sw = (float) src.GetWidth();
|
||||
float sh = (float) src.GetHeight();
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
float cl = (float) clip.left;
|
||||
float ct = (float) clip.top;
|
||||
float cr = (float) clip.right;
|
||||
float cb = (float) clip.bottom;
|
||||
|
||||
if(sx < cl)
|
||||
{
|
||||
float dl = cl - sx;
|
||||
tl += dl * sw / (float) cx;
|
||||
sx = cl;
|
||||
}
|
||||
|
||||
if(sy < ct)
|
||||
{
|
||||
float dt = ct - sy;
|
||||
tt += dt * sh / (float) cy;
|
||||
sy = ct;
|
||||
}
|
||||
|
||||
if(dx > cr)
|
||||
{
|
||||
float dr = dx - cr;
|
||||
tr -= dr * sw / (float) cx;
|
||||
dx = cr;
|
||||
}
|
||||
|
||||
if(dy > cb)
|
||||
{
|
||||
float db = dy - cb;
|
||||
tb -= db * sh / (float) cy;
|
||||
dy = cb;
|
||||
}
|
||||
#endif
|
||||
|
||||
const TextureResource& t = resources.Bind(img, Resources::AUTO_ATLAS | Resources::NEAREST_FILTERING);
|
||||
|
||||
float tw = 1.f / (float) t.realWidth;
|
||||
float th = 1.f / (float) t.realHeight;
|
||||
|
||||
tl = (tl + t.x + TEXEL_OFFSET) * tw;
|
||||
tr = (tr + t.x - TEXEL_OFFSET) * tw;
|
||||
tt = (tt + t.y + TEXEL_OFFSET) * th;
|
||||
tb = (tb + t.y - TEXEL_OFFSET) * th;
|
||||
|
||||
if(image_coloring)
|
||||
{
|
||||
if(IsNull(color))
|
||||
glColor4ub(255, 255, 255, (int) alpha);
|
||||
else
|
||||
{
|
||||
#ifdef COLOR_ALPHA
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), color.GetA() >= 255 ? (int) alpha : color.GetA());
|
||||
#else
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
glColor4ub(255, 255, 255, 255);
|
||||
|
||||
float vtx[12];
|
||||
SetVtx(vtx, sx, sy, dx, dy);
|
||||
|
||||
float crd[] = {
|
||||
tl, tb,
|
||||
tl, tt,
|
||||
tr, tb,
|
||||
tr, tt
|
||||
};
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
||||
glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawTextureOp(const RectF& r, int textureId, int width, int height, const RectF& src)
|
||||
{
|
||||
GuiLock __;
|
||||
float sx = r.left + drawing_offset.x;
|
||||
float sy = r.top + drawing_offset.y;
|
||||
float dx = sx + r.GetWidth();
|
||||
float dy = sy + r.GetHeight();
|
||||
|
||||
float tl = src.left;
|
||||
float tr = src.right;
|
||||
float tt = src.top;
|
||||
float tb = src.bottom;
|
||||
|
||||
resources.Bind(textureId, Resources::NEAREST_FILTERING);
|
||||
|
||||
float tw = 1.f / (float) (width);
|
||||
float th = 1.f / (float) (height);
|
||||
|
||||
tl = (tl + TEXEL_OFFSET) * tw;
|
||||
tr = (tr - TEXEL_OFFSET) * tw;
|
||||
tt = (tt + TEXEL_OFFSET) * th;
|
||||
tb = (tb - TEXEL_OFFSET) * th;
|
||||
|
||||
float vtx[12];
|
||||
|
||||
SetVtx(vtx, sx, sy, dx, dy);
|
||||
|
||||
float crd[] = {
|
||||
tl, tt,
|
||||
tl, tb,
|
||||
tr, tt,
|
||||
tr, tb
|
||||
};
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
||||
glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawImageOp(float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
float tl = (float) src.left;
|
||||
float tr = (float) src.right;
|
||||
float tt = (float) src.top;
|
||||
float tb = (float) src.bottom;
|
||||
|
||||
float sw = (float) src.GetWidth();
|
||||
float sh = (float) src.GetHeight();
|
||||
|
||||
const TextureResource& t = resources.Bind(img, Resources::AUTO_ATLAS | Resources::NEAREST_FILTERING);
|
||||
|
||||
float tw = 1.f / (float) t.realWidth;
|
||||
float th = 1.f / (float) t.realHeight;
|
||||
|
||||
tl = (tl + t.x + TEXEL_OFFSET) * tw;
|
||||
tr = (tr + t.x - TEXEL_OFFSET) * tw;
|
||||
tt = (tt + t.y + TEXEL_OFFSET) * th;
|
||||
tb = (tb + t.y - TEXEL_OFFSET) * th;
|
||||
|
||||
if(image_coloring)
|
||||
{
|
||||
if(IsNull(color))
|
||||
glColor4ub(255, 255, 255, (int) alpha);
|
||||
else
|
||||
{
|
||||
#ifdef COLOR_ALPHA
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), color.GetA());
|
||||
#else
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
float vtx[] = {
|
||||
x3, y3, z3,
|
||||
x0, y0, z0,
|
||||
x2, y2, z2,
|
||||
x1, y1, z1
|
||||
};
|
||||
|
||||
float crd[] = {
|
||||
tl, tb,
|
||||
tl, tt,
|
||||
tr, tb,
|
||||
tr, tt
|
||||
};
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
||||
glVertexPointer(3, GL_FLOAT, 0, vtx);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
#ifdef COLOR_ALPHA
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), color.GetA());
|
||||
#else
|
||||
glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha);
|
||||
#endif
|
||||
glLineWidth((GLfloat) width);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(x1 + drawing_offset.x, y1 + drawing_offset.y);
|
||||
glVertex2i(x2 + drawing_offset.x, y2 + drawing_offset.y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void SystemDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void SystemDraw::SaveCurrentColor()
|
||||
{
|
||||
GuiLock __;
|
||||
glGetFloatv(GL_CURRENT_COLOR, current_color);
|
||||
}
|
||||
|
||||
void SystemDraw::RestoreLastColor()
|
||||
{
|
||||
GuiLock __;
|
||||
glColor4f(current_color[0], current_color[1], current_color[2], current_color[3]);
|
||||
}
|
||||
|
||||
RectF SystemDraw::UnProject(const RectF& r, float& depth)
|
||||
{
|
||||
GuiLock __;
|
||||
double projMat[16];
|
||||
double modelMat[16];
|
||||
int viewPort[4];
|
||||
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, projMat);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, modelMat);
|
||||
glGetIntegerv(GL_VIEWPORT, viewPort);
|
||||
|
||||
RectF fr;
|
||||
double x, y, z;
|
||||
gluUnProject(r.left, r.top, 0.99f, modelMat, projMat, viewPort, &x, &y, &z);
|
||||
depth = (float) z;
|
||||
fr.left = (float) x;
|
||||
fr.top = (float) y;
|
||||
gluUnProject(r.right, r.bottom, 0.99f, modelMat, projMat, viewPort, &x, &y, &z);
|
||||
fr.right = (float) x;
|
||||
fr.bottom = (float) y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
void SystemDraw::UnProject(float* vtx, float sx, float sy, float dx, float dy)
|
||||
{
|
||||
GuiLock __;
|
||||
double projMat[16];
|
||||
double modelMat[16] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
int viewPort[4];
|
||||
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, projMat);
|
||||
//glGetDoublev(GL_MODELVIEW_MATRIX, modelMat);
|
||||
glGetIntegerv(GL_VIEWPORT, viewPort);
|
||||
|
||||
double xs, ys, xd, yd, z;
|
||||
|
||||
gluUnProject(sx, drawing_size.cy - sy, 0.99, modelMat, projMat, viewPort, &xs, &ys, &z);
|
||||
gluUnProject(dx, drawing_size.cy - dy, 0.99, modelMat, projMat, viewPort, &xd, &yd, &z);
|
||||
|
||||
vtx[0] = (float) xs;
|
||||
vtx[1] = (float) yd;
|
||||
vtx[2] = (float) z;
|
||||
vtx[3] = (float) xs;
|
||||
vtx[4] = (float) ys;
|
||||
vtx[5] = (float) z;
|
||||
vtx[6] = (float) xd;
|
||||
vtx[7] = (float) yd;
|
||||
vtx[8] = (float) z;
|
||||
vtx[9] = (float) xd;
|
||||
vtx[10] = (float) ys;
|
||||
vtx[11] = (float) z;
|
||||
}
|
||||
|
||||
void SystemDraw::UnProject(float& x, float& y, float &z)
|
||||
{
|
||||
GuiLock __;
|
||||
double projMat[16];
|
||||
double modelMat[16] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
int viewPort[4];
|
||||
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, projMat);
|
||||
glGetIntegerv(GL_VIEWPORT, viewPort);
|
||||
|
||||
double xd, yd, zd;
|
||||
|
||||
gluUnProject(x, drawing_size.cy - y, 0.99, modelMat, projMat, viewPort, &xd, &yd, &zd);
|
||||
x = (float) xd;
|
||||
y = (float) yd;
|
||||
z = (float) zd;
|
||||
}
|
||||
|
||||
void SystemDraw::SetVtx(float* vtx, float sx, float sy, float dx, float dy)
|
||||
{
|
||||
if(projection_mode == 1)
|
||||
{
|
||||
UnProject(vtx, sx, sy, dx, dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtx[0] = sx;
|
||||
vtx[1] = dy;
|
||||
vtx[2] = sx;
|
||||
vtx[3] = sy;
|
||||
vtx[4] = dx;
|
||||
vtx[5] = dy;
|
||||
vtx[6] = dx;
|
||||
vtx[7] = sy;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemDraw::SetProjectionMode(int mode)
|
||||
{
|
||||
if(mode != projection_mode)
|
||||
{
|
||||
projection_mode = mode;
|
||||
if(projection_mode)
|
||||
PerspectiveView(false);
|
||||
else
|
||||
OrthogonalView(false);
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
321
rainbow/CoreGl/DrawText.cpp
Normal file
321
rainbow/CoreGl/DrawText.cpp
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void OpenGLFont::LoadBrc(const byte* xml, const byte** imagesData, const int* imagesSize, int imagesCount)
|
||||
{
|
||||
Parse((const char*) xml, false);
|
||||
for(int i = 0; i < imagesCount; i++)
|
||||
{
|
||||
MemStream ms((void*) imagesData[i], imagesSize[i]);
|
||||
Image img = StreamRaster::LoadAny(ms);
|
||||
images.Add(img);
|
||||
if(preload)
|
||||
resources.Add(img, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFont::Load(const String& fileName, bool preload)
|
||||
{
|
||||
String filePath = GetDataFile(fileName);
|
||||
String xml = LoadFile(filePath);
|
||||
Parse(xml, true);
|
||||
}
|
||||
|
||||
void OpenGLFont::Parse(const char* xml, bool parsePages)
|
||||
{
|
||||
chars.SetCount(512);
|
||||
|
||||
XmlParser p(xml);
|
||||
|
||||
while(!p.IsTag())
|
||||
p.Skip();
|
||||
|
||||
p.PassTag("font");
|
||||
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.TagE("common"))
|
||||
{
|
||||
scaleW = (float) p.Double("scaleW");
|
||||
scaleH = (float) p.Double("scaleH");
|
||||
lineHeight = (float) p.Double("lineHeight");
|
||||
base = (float) p.Double("base");
|
||||
}
|
||||
else if(p.Tag("pages"))
|
||||
{
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.TagE("page"))
|
||||
{
|
||||
if(parsePages)
|
||||
{
|
||||
String fileName = p["file"];
|
||||
Image img = StreamRaster::LoadFileAny(GetDataFile(fileName));
|
||||
images.Add(img);
|
||||
if(preload)
|
||||
resources.Add(img, true);
|
||||
}
|
||||
pages.Add(StrInt(p["id"]));
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
|
||||
}
|
||||
else if(p.Tag("chars"))
|
||||
{
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.TagE("char"))
|
||||
{
|
||||
int id = p.Int("id");
|
||||
CharInfo& ci = chars[id];
|
||||
|
||||
ci.id = id;
|
||||
ci.x = (float) p.Double("x");
|
||||
ci.y = (float) p.Double("y");
|
||||
ci.width = (float) p.Double("width");
|
||||
ci.height = (float) p.Double("height");
|
||||
ci.xoffset = (float) p.Double("xoffset");
|
||||
ci.yoffset = (float) p.Double("yoffset");
|
||||
ci.xadvance = (float) p.Double("xadvance");
|
||||
ci.page = p.Int("page");
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else if(p.Tag("kernings"))
|
||||
{
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.TagE("kerning"))
|
||||
{
|
||||
int first = p.Int("first");
|
||||
int second = p.Int("second");
|
||||
float amount = (float) p.Double("amount");
|
||||
|
||||
VectorMap<int, float>& vm = kerns.GetAdd(first);
|
||||
vm.Add(second, amount);
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFont::UpdateTextures()
|
||||
{
|
||||
if(texturesUpdated)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < images.GetCount(); i++)
|
||||
{
|
||||
const TextureResource& t = resources.Bind(images[i], Resources::LINEAR_FILTERING);
|
||||
pages[i] = t.serialId;
|
||||
}
|
||||
|
||||
texturesUpdated = true;
|
||||
}
|
||||
|
||||
float ConvStrength(float min, float max, float p)
|
||||
{
|
||||
return min + (max - min) * p / 100.f;
|
||||
}
|
||||
|
||||
void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Color ink, int outlineStrength, Color outlineColor, int glowStrength, Color glowColor, int n, const int *dx)
|
||||
{
|
||||
if(!text)
|
||||
return;
|
||||
|
||||
const wchar* s = text;
|
||||
OpenGLFont& fi = resources.GetFont(font);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
float cl = (float) clip.left;
|
||||
float ct = (float) clip.top;
|
||||
float cr = (float) clip.right;
|
||||
float cb = (float) clip.bottom;
|
||||
#endif
|
||||
fi.UpdateTextures();
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
alphaMagProg.Start();
|
||||
|
||||
const float ic = 1.f / 255.f;
|
||||
|
||||
float outlineCenter = ConvStrength(0.1f, 0.45f, (float) 100 - min(outlineStrength, 100));
|
||||
float glowCenter = ConvStrength(0.55f, 0.95f, (float) 100 - min(glowStrength, 100));
|
||||
|
||||
#ifdef COLOR_ALPHA
|
||||
float ac = alpha / 255.f;
|
||||
int inkA = ink.GetA();
|
||||
int outlineA = outlineColor.GetA();
|
||||
int glowA = glowColor.GetA();
|
||||
#else
|
||||
float ac = alpha;
|
||||
int inkA = 1;
|
||||
int outlineA = 1;
|
||||
int glowA = 1;
|
||||
#endif
|
||||
|
||||
alphaMagProg.SetUniform("GlyphColor", ink.GetR() * ic, ink.GetG() * ic, ink.GetB() * ic, inkA * ic * ac);
|
||||
alphaMagProg.SetUniform("OutlineColor", outlineColor.GetR() * ic, outlineColor.GetG() * ic, outlineColor.GetB() * ic, outlineA * ic * ac);
|
||||
alphaMagProg.SetUniform("GlowColor", glowColor.GetR() * ic, glowColor.GetG() * ic, glowColor.GetB() * ic, glowA * ic * ac);
|
||||
alphaMagProg.SetUniform("Outline", outlineStrength > 0); //0.1 - 0.45
|
||||
alphaMagProg.SetUniform("Glow", glowStrength > 0); //0.55 - 0.095
|
||||
alphaMagProg.SetUniform("Shadow", false);
|
||||
alphaMagProg.SetUniform("OutlineCenter", outlineCenter);
|
||||
alphaMagProg.SetUniform("GlowCenter", glowCenter);
|
||||
|
||||
float xp = (float) x;
|
||||
float yp = (float) y;
|
||||
|
||||
int page = -1;
|
||||
|
||||
float sw = (float) fi.scaleW;
|
||||
float sh = (float) fi.scaleH;
|
||||
|
||||
float tw = 1.f / sw;
|
||||
float th = 1.f / sh;
|
||||
|
||||
while(*s && n > 0)
|
||||
{
|
||||
int cn = *s;
|
||||
|
||||
if(cn >= 0 && cn < fi.chars.GetCount())
|
||||
{
|
||||
const OpenGLFont::CharInfo& ci = fi.chars[cn];
|
||||
|
||||
cn <<= 3;
|
||||
|
||||
if(ci.page != page)
|
||||
{
|
||||
resources.Bind(fi.pages[ci.page], Resources::LINEAR_FILTERING);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
alphaMagProg.SetUniform("Texture", 0);
|
||||
page = ci.page;
|
||||
}
|
||||
|
||||
float sx = (float) ci.xoffset * fi.scale + xp + drawing_offset.x;
|
||||
float sy = (float) ci.yoffset * fi.scale + yp + drawing_offset.y;
|
||||
float dx = sx + ci.width * fi.scale;
|
||||
float dy = sy + ci.height * fi.scale;
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
if(sx <= clip.right && sy <= clip.bottom && dx >= clip.left && dy >= clip.top)
|
||||
#endif
|
||||
{
|
||||
float tl = (float) ci.x;
|
||||
float tt = (float) ci.y;
|
||||
float tr = (float) ci.x + ci.width;
|
||||
float tb = (float) ci.y + ci.height;
|
||||
|
||||
#if CLIP_MODE == 3
|
||||
if(sx < cl)
|
||||
{
|
||||
tl += (cl - sx);
|
||||
sx = cl;
|
||||
}
|
||||
|
||||
if(sy < ct)
|
||||
{
|
||||
tt += (ct - sy);
|
||||
sy = ct;
|
||||
}
|
||||
|
||||
if(dx > cr)
|
||||
{
|
||||
tr -= dx - cr;
|
||||
dx = cr;
|
||||
}
|
||||
|
||||
if(dy > cb)
|
||||
{
|
||||
tb -= dy - cb;
|
||||
dy = cb;
|
||||
}
|
||||
#endif
|
||||
|
||||
tl = (tl + TEXEL_OFFSET) * tw;
|
||||
tr = (tr - TEXEL_OFFSET) * tw;
|
||||
tt = (tt + TEXEL_OFFSET) * th;
|
||||
tb = (tb - TEXEL_OFFSET) * th;
|
||||
/*
|
||||
float vtx[] = {
|
||||
sx, dy,
|
||||
sx, sy,
|
||||
dx, dy,
|
||||
dx, sy
|
||||
};*/
|
||||
float vtx[12];
|
||||
SetVtx(vtx, sx, sy, dx, dy);
|
||||
|
||||
float crd[] = {
|
||||
tl, tb,
|
||||
tl, tt,
|
||||
tr, tb,
|
||||
tr, tt
|
||||
};
|
||||
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
||||
glVertexPointer(projection_mode ? 3: 2, GL_FLOAT, 0, vtx);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
xp += int(ci.xadvance * fi.scale + 0.5f);
|
||||
|
||||
int k = fi.kerns.Find(*s);
|
||||
if(k >= 0)
|
||||
xp += int(fi.kerns[k].Get(*(s + 1), 0) * fi.scale);
|
||||
}
|
||||
|
||||
++s;
|
||||
--n;
|
||||
}
|
||||
|
||||
alphaMagProg.Stop();
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
||||
{
|
||||
GuiLock __;
|
||||
Text(x, y, angle, text, font, ink, 0, White, 0, White, n, dx);
|
||||
}
|
||||
|
||||
Size GetTextSize(const wchar *text, const OpenGLFont& fi, int n)
|
||||
{
|
||||
if(n < 0)
|
||||
n = wstrlen(text);
|
||||
Size sz;
|
||||
sz.cx = 0;
|
||||
const wchar *wtext = (const wchar *)text;
|
||||
while(n > 0) {
|
||||
int cn = *wtext++;
|
||||
if(cn >= 0 && cn < fi.chars.GetCount())
|
||||
{
|
||||
const OpenGLFont::CharInfo& ci = fi.chars[cn];
|
||||
sz.cx += int(ci.xadvance * fi.scale + 0.5f);
|
||||
int k = fi.kerns.Find(cn);
|
||||
if(k >= 0)
|
||||
sz.cx += int(fi.kerns[k].Get(*wtext, 0) * fi.scale);
|
||||
}
|
||||
n--;
|
||||
}
|
||||
sz.cy = int(fi.lineHeight * fi.scale + 0.5f);
|
||||
return sz;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
174
rainbow/CoreGl/Event.cpp
Normal file
174
rainbow/CoreGl/Event.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) //LOG(x)
|
||||
|
||||
static Point glmousepos;
|
||||
|
||||
Point GetMousePos() {
|
||||
return glmousepos;
|
||||
}
|
||||
|
||||
void Ctrl::SysEndLoop()
|
||||
{
|
||||
}
|
||||
|
||||
void WakeUpGuiThread()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::MouseEventGl(Ptr<Ctrl> t, int event, Point p, int zdelta)
|
||||
{
|
||||
if(!t->IsEnabled() && (t != (Ctrl*) &infoPanel && t != (Ctrl*) &console))
|
||||
return;
|
||||
Rect rr = t->GetRect();
|
||||
if((event & Ctrl::ACTION) == DOWN) {
|
||||
Ptr<Ctrl> q = t;
|
||||
TopWindowFrame *wf = dynamic_cast<TopWindowFrame *>(~t);
|
||||
if(wf)
|
||||
q = wf->window;
|
||||
if(q) q->ClickActivateWnd();
|
||||
if(q) q->SetForeground();
|
||||
if(ignoreclick)
|
||||
return;
|
||||
}
|
||||
if(t)
|
||||
t->DispatchMouse(event, p - rr.TopLeft(), zdelta);
|
||||
if(t)
|
||||
t->PostInput();
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::FindMouseTopCtrl()
|
||||
{
|
||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||
Ctrl *t = topctrl[i];
|
||||
if(t->GetRect().Contains(glmousepos))
|
||||
return t->IsEnabled() ? t : NULL;
|
||||
}
|
||||
return desktop->IsEnabled() ? desktop : NULL;
|
||||
}
|
||||
|
||||
bool Ctrl::DoMouseGl(Ctrl* q, int event, Point p, int zdelta)
|
||||
{
|
||||
Rect rr = q->GetRect();
|
||||
if(rr.Contains(p)) {
|
||||
MouseEventGl(q, event, p, zdelta);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::DoMouseGl(int event, Point p, int zdelta)
|
||||
{
|
||||
glmousepos = p;
|
||||
int a = event & Ctrl::ACTION;
|
||||
if(a == Ctrl::UP && Ctrl::ignoreclick) {
|
||||
EndIgnore();
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(a == Ctrl::DOWN && ignoreclick)
|
||||
return;
|
||||
LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl));
|
||||
if(captureCtrl)
|
||||
MouseEventGl(captureCtrl->GetTopCtrl(), event, p, zdelta);
|
||||
else
|
||||
{
|
||||
bool processed = consoleActive && DoMouseGl((Ctrl*) &console, event, p, zdelta);
|
||||
|
||||
if(!processed && controlPanelActive)
|
||||
processed = DoMouseGl((Ctrl*) &infoPanel, event, p, zdelta);
|
||||
|
||||
if(!processed)
|
||||
{
|
||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||
Ptr<Ctrl> t = topctrl[i];
|
||||
if(t != (Ctrl*) &infoPanel && t != (Ctrl*) &console && t->GetRect().Contains(p) &&
|
||||
DoMouseGl(t, event, p, zdelta))
|
||||
return;
|
||||
}
|
||||
Ctrl *desktop = GetDesktop();
|
||||
if(desktop) {
|
||||
desktop->DispatchMouse(event, p, zdelta);
|
||||
desktop->PostInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::DoKeyGl(dword key, int cnt)
|
||||
{
|
||||
if(key == K_CTRL_GRAVE)
|
||||
{
|
||||
controlPanelActive = !controlPanelActive;
|
||||
consoleActive = !consoleActive;
|
||||
return true;
|
||||
}
|
||||
else if(key == K_CTRL_F12)
|
||||
{
|
||||
consoleActive = !consoleActive;
|
||||
return true;
|
||||
}
|
||||
else if(key == K_CTRL_F11)
|
||||
{
|
||||
controlPanelActive = !controlPanelActive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool b = DispatchKey(key, cnt);
|
||||
SyncCaret();
|
||||
Ctrl *desktop = GetDesktop();
|
||||
if(desktop)
|
||||
desktop->PostInput();
|
||||
return b;
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
glCaretTm = GetTickCount();
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::CursorSync(Draw& w)
|
||||
{
|
||||
Rect cr = Null;
|
||||
if(focusCtrl && (((GetTickCount() - glCaretTm) / 500) & 1) == 0)
|
||||
cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy)
|
||||
+ focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView();
|
||||
|
||||
glCaretRect = cr;
|
||||
if(!cr.IsEmpty())
|
||||
w.DrawRect(cr, Black);
|
||||
}
|
||||
|
||||
void Ctrl::MouseSync(Draw& w)
|
||||
{
|
||||
glCursorPos = GetMousePos() - glCursorImage.GetHotSpot();
|
||||
Size sz = glCursorImage.GetSize();
|
||||
w.DrawImage(glCursorPos.x, glCursorPos.y, sz.cx, sz.cy, glCursorImage);
|
||||
}
|
||||
|
||||
void Ctrl::SetMouseCursor(const Image& image)
|
||||
{
|
||||
GuiLock __;
|
||||
if(image.GetSerialId() != glCursorImage.GetSerialId()) {
|
||||
glCursorImage = image;
|
||||
glCursorPos = Null;
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
103
rainbow/CoreGl/Fbo.cpp
Normal file
103
rainbow/CoreGl/Fbo.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include "Fbo.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
bool Fbo::Create(int width, int height, bool resize)
|
||||
{
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
||||
if(!resize)
|
||||
{
|
||||
glGenFramebuffers(1, &fbId);
|
||||
glGenRenderbuffers(1, &rbId);
|
||||
glGenTextures(1, &texId);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rbId);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbId, 0);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbId);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbId);
|
||||
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
ready = true;
|
||||
|
||||
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
void Fbo::Resize(int width, int height)
|
||||
{
|
||||
if(ready)
|
||||
Create(width, height, true);
|
||||
}
|
||||
|
||||
void Fbo::Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId);
|
||||
}
|
||||
|
||||
void Fbo::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Fbo::Clear()
|
||||
{
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Fbo::BlitToScreen()
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
void Fbo::BlitTo(const Fbo& fbo)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo.fbId);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, fbo.width, fbo.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
void Fbo::Remove()
|
||||
{
|
||||
glDeleteTextures(1, &texId);
|
||||
glDeleteRenderbuffers(1, &rbId);
|
||||
glDeleteFramebuffers(1, &fbId);
|
||||
}
|
||||
|
||||
String Fbo::GetError()
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
return "Framebuffer complete";
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
return "Framebuffer incomplete attachment";
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
return "Framebuffer incomplete missing attachment";
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||||
return "Framebuffer incomplete draw buffer";
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
|
||||
return "Framebuffer incomplete read buffer";
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
return "Framebuffer unsupported";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
36
rainbow/CoreGl/Fbo.h
Normal file
36
rainbow/CoreGl/Fbo.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _CoreGl_Fbo_h_
|
||||
#define _CoreGl_Fbo_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
#include <Draw/Draw.h>
|
||||
#include "Gl.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct Fbo : Moveable<Fbo>
|
||||
{
|
||||
GLuint texId;
|
||||
GLuint fbId;
|
||||
GLuint rbId;
|
||||
GLenum status;
|
||||
int width;
|
||||
int height;
|
||||
bool ready;
|
||||
|
||||
bool Create(int width, int height, bool resize = false);
|
||||
void Resize(int width, int height);
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void Clear();
|
||||
void BlitToScreen();
|
||||
void BlitTo(const Fbo& fbo);
|
||||
void Remove();
|
||||
String GetError();
|
||||
|
||||
Fbo() : width(0), height(0), ready(false)
|
||||
{}
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
57
rainbow/CoreGl/FontGl.h
Normal file
57
rainbow/CoreGl/FontGl.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef _CoreGl_FontGl_h_
|
||||
#define _CoreGl_FontGl_h_
|
||||
|
||||
struct OpenGLFont : Moveable<OpenGLFont>
|
||||
{
|
||||
float scaleW;
|
||||
float scaleH;
|
||||
float lineHeight;
|
||||
float base;
|
||||
float scale;
|
||||
|
||||
bool texturesUpdated;
|
||||
|
||||
float vtx[1024 * 4 * 2];
|
||||
float crd[1024 * 4 * 2];
|
||||
|
||||
struct CharInfo : Moveable<CharInfo>
|
||||
{
|
||||
int id;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
float xoffset;
|
||||
float yoffset;
|
||||
float xadvance;
|
||||
int page;
|
||||
};
|
||||
|
||||
struct BrcImage : Moveable<BrcImage>
|
||||
{
|
||||
const byte* data;
|
||||
int length;
|
||||
};
|
||||
|
||||
Vector<CharInfo> chars;
|
||||
VectorMap<int, VectorMap<int, float> > kerns;
|
||||
Vector<Image> images;
|
||||
Vector<int64> pages;
|
||||
bool preload;
|
||||
|
||||
OpenGLFont() : texturesUpdated(false), preload(false), scale(1.0f)
|
||||
{}
|
||||
|
||||
~OpenGLFont()
|
||||
{}
|
||||
|
||||
void LoadBrc(const byte* xml, const byte** imagesData, const int* imagesSize, int imagesCount);
|
||||
void Load(const String& fileName, bool preload = false);
|
||||
void Parse(const char* xml, bool parsePages);
|
||||
void UpdateTextures();
|
||||
void BuildVertices();
|
||||
};
|
||||
|
||||
Size GetTextSize(const wchar *text, const OpenGLFont& fi, int n);
|
||||
|
||||
#endif
|
||||
4
rainbow/CoreGl/Fonts.brc
Normal file
4
rainbow/CoreGl/Fonts.brc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
BINARY(resTahoma14Fnt, "tahoma14.fnt")
|
||||
BINARY(resTahoma14BoldFnt, "tahoma14b.fnt")
|
||||
BINARY(resTahoma14Img, "tahoma14.png")
|
||||
BINARY(resTahoma14BoldImg, "tahoma14b.png")
|
||||
329
rainbow/CoreGl/Fonts/TahomaB.fnt
Normal file
329
rainbow/CoreGl/Fonts/TahomaB.fnt
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
<?xml version="1.0"?>
|
||||
<font>
|
||||
<info face="Tahoma" size="64" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="0" aa="1" padding="64,64,64,64" spacing="1,1" outline="0" />
|
||||
<common lineHeight="64" base="53" scaleW="1024" scaleH="1024" pages="1" packed="0" alphaChnl="0" redChnl="0" greenChnl="0" blueChnl="0" />
|
||||
<pages>
|
||||
<page id="0" file="TahomaB_0.png" />
|
||||
</pages>
|
||||
<chars count="319">
|
||||
<char id="32" x="1006" y="16,25" width="16,125" height="16,125" xoffset="-8" yoffset="45" xadvance="15,5" page="0" chnl="15" />
|
||||
<char id="33" x="793" y="681,375" width="26,25" height="54,5" xoffset="-4" yoffset="6,5" xadvance="18,125" page="0" chnl="15" />
|
||||
<char id="34" x="654,875" y="783,75" width="35,375" height="31,25" xoffset="-4,75" yoffset="4,75" xadvance="25,875" page="0" chnl="15" />
|
||||
<char id="35" x="608,75" y="628,375" width="52,875" height="54,5" xoffset="-4,75" yoffset="6,5" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="36" x="862,5" y="206,25" width="45,25" height="66,125" xoffset="-5,5" yoffset="4,25" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="37" x="878,125" y="514,625" width="73,875" height="56,125" xoffset="-5,25" yoffset="5,75" xadvance="63,5" page="0" chnl="15" />
|
||||
<char id="38" x="952,125" y="513,625" width="56,625" height="56,125" xoffset="-5,75" yoffset="5,75" xadvance="41,375" page="0" chnl="15" />
|
||||
<char id="39" x="690,375" y="783,75" width="24,5" height="31,25" xoffset="-4,875" yoffset="4,75" xadvance="14,625" page="0" chnl="15" />
|
||||
<char id="40" x="291,75" y="208,125" width="35,125" height="66,875" xoffset="-5,125" yoffset="4,75" xadvance="24,125" page="0" chnl="15" />
|
||||
<char id="41" x="327" y="208" width="35,125" height="66,875" xoffset="-6" yoffset="4,75" xadvance="24,125" page="0" chnl="15" />
|
||||
<char id="42" x="160" y="795,25" width="41,875" height="41,375" xoffset="-4,625" yoffset="4,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="43" x="148,25" y="746" width="49,375" height="49,125" xoffset="-3" yoffset="11,375" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="44" x="523,625" y="787,375" width="30,625" height="35,75" xoffset="-8,125" yoffset="34,875" xadvance="16,625" page="0" chnl="15" />
|
||||
<char id="45" x="891,625" y="780,75" width="33,125" height="23,125" xoffset="-5,125" yoffset="24,375" xadvance="22,875" page="0" chnl="15" />
|
||||
<char id="46" x="830,5" y="781,25" width="25,125" height="26,125" xoffset="-4,25" yoffset="34,875" xadvance="16,625" page="0" chnl="15" />
|
||||
<char id="47" x="942" y="272,375" width="38,75" height="64,625" xoffset="-5" yoffset="4,75" xadvance="30,625" page="0" chnl="15" />
|
||||
<char id="48" x="152" y="578,375" width="45,75" height="56,125" xoffset="-6" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="49" x="688,25" y="682,875" width="41,5" height="54,5" xoffset="-3" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="50" x="755" y="571,375" width="44,25" height="55,25" xoffset="-4,125" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="51" x="289,125" y="577,25" width="44,625" height="56,125" xoffset="-5,375" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="52" x="138" y="636,625" width="47,625" height="54,625" xoffset="-6,875" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="53" x="598,375" y="572,875" width="44,25" height="55,375" xoffset="-4,875" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="54" x="197,875" y="577,875" width="45,5" height="56,125" xoffset="-5,5" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="55" x="475,875" y="685,875" width="44,375" height="54,5" xoffset="-5" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="56" x="486,375" y="518,375" width="46,5" height="56,25" xoffset="-6,375" yoffset="5,625" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="57" x="243,5" y="577,375" width="45,5" height="56,125" xoffset="-6,25" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="58" x="989,75" y="680,75" width="25,125" height="45,125" xoffset="-3" yoffset="15,875" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="59" x="983,875" y="569,875" width="30,625" height="54,75" xoffset="-6,875" yoffset="15,875" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="60" x="49,5" y="747,875" width="49,25" height="49,25" xoffset="-3,375" yoffset="11,375" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="61" x="554,375" y="787,25" width="47,75" height="35,5" xoffset="-2,25" yoffset="18,25" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="62" x="98,875" y="747" width="49,25" height="49,25" xoffset="-2,5" yoffset="11,375" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="63" x="843,625" y="571,125" width="41,125" height="55,25" xoffset="-5,125" yoffset="5,75" xadvance="30" page="0" chnl="15" />
|
||||
<char id="64" x="173,375" y="341,75" width="58,25" height="61,125" xoffset="-5" yoffset="5,75" xadvance="48,75" page="0" chnl="15" />
|
||||
<char id="65" x="767,25" y="626,75" width="52,5" height="54,5" xoffset="-8,125" yoffset="6,5" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="66" x="244,375" y="689,25" width="46,875" height="54,5" xoffset="-4" yoffset="6,5" xadvance="36,375" page="0" chnl="15" />
|
||||
<char id="67" x="104" y="580,375" width="47,875" height="56,125" xoffset="-6,25" yoffset="5,75" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="68" x="924,125" y="626,125" width="50,375" height="54,5" xoffset="-4" yoffset="6,5" xadvance="40,125" page="0" chnl="15" />
|
||||
<char id="69" x="520,375" y="685,75" width="42,125" height="54,5" xoffset="-4" yoffset="6,5" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="70" x="562,625" y="683" width="41,75" height="54,5" xoffset="-4" yoffset="6,5" xadvance="30,75" page="0" chnl="15" />
|
||||
<char id="71" x="53,375" y="581,25" width="50,5" height="56,125" xoffset="-6,25" yoffset="5,75" xadvance="39,5" page="0" chnl="15" />
|
||||
<char id="72" x="98,75" y="692,375" width="48,5" height="54,5" xoffset="-4" yoffset="6,5" xadvance="40,5" page="0" chnl="15" />
|
||||
<char id="73" x="729,875" y="682,75" width="36,625" height="54,5" xoffset="-5,5" yoffset="6,5" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="74" x="944,875" y="570,875" width="38,875" height="55,125" xoffset="-7,875" yoffset="6,5" xadvance="26,5" page="0" chnl="15" />
|
||||
<char id="75" x="0" y="693,25" width="49,75" height="54,5" xoffset="-4" yoffset="6,5" xadvance="36,875" page="0" chnl="15" />
|
||||
<char id="76" x="646,375" y="683" width="41,75" height="54,5" xoffset="-4" yoffset="6,5" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="77" x="443,5" y="631,25" width="55,375" height="54,5" xoffset="-4" yoffset="6,5" xadvance="47,375" page="0" chnl="15" />
|
||||
<char id="78" x="974,625" y="626,125" width="48,875" height="54,5" xoffset="-4" yoffset="6,5" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="79" x="0" y="582,125" width="53,25" height="56,125" xoffset="-6,25" yoffset="5,75" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="80" x="430,125" y="686,125" width="45,625" height="54,5" xoffset="-4" yoffset="6,5" xadvance="34,875" page="0" chnl="15" />
|
||||
<char id="81" x="663,625" y="206,5" width="53,25" height="66,125" xoffset="-6,25" yoffset="5,75" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="82" x="872,375" y="626,5" width="51,625" height="54,5" xoffset="-4" yoffset="6,5" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="83" x="333,875" y="576,5" width="46,75" height="56" xoffset="-6,125" yoffset="5,75" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="84" x="147,375" y="691,375" width="48,375" height="54,5" xoffset="-8" yoffset="6,5" xadvance="32,5" page="0" chnl="15" />
|
||||
<char id="85" x="550,125" y="572,875" width="48,125" height="55,375" xoffset="-4,5" yoffset="6,5" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="86" x="714,625" y="628,125" width="52,5" height="54,5" xoffset="-8,375" yoffset="6,5" xadvance="35,75" page="0" chnl="15" />
|
||||
<char id="87" x="185,75" y="634,625" width="69" height="54,5" xoffset="-7,25" yoffset="6,5" xadvance="54,5" page="0" chnl="15" />
|
||||
<char id="88" x="661,75" y="628,25" width="52,75" height="54,5" xoffset="-8,25" yoffset="6,5" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="89" x="819,875" y="626,75" width="52,375" height="54,5" xoffset="-8,5" yoffset="6,5" xadvance="35,5" page="0" chnl="15" />
|
||||
<char id="90" x="291,375" y="688,25" width="46,5" height="54,5" xoffset="-6,625" yoffset="6,5" xadvance="33" page="0" chnl="15" />
|
||||
<char id="91" x="584,5" y="207,25" width="32,25" height="66,375" xoffset="-3,75" yoffset="4,75" xadvance="24,125" page="0" chnl="15" />
|
||||
<char id="92" x="903,125" y="272,5" width="38,75" height="64,625" xoffset="-3" yoffset="4,75" xadvance="30,625" page="0" chnl="15" />
|
||||
<char id="93" x="552,125" y="207,25" width="32,25" height="66,375" xoffset="-4,5" yoffset="4,75" xadvance="24,125" page="0" chnl="15" />
|
||||
<char id="94" x="386,75" y="789,75" width="50,375" height="37,125" xoffset="-3,5" yoffset="6,5" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="95" x="958,125" y="779,5" width="50,5" height="21,25" xoffset="-8,375" yoffset="48,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="96" x="745,25" y="782,625" width="29,875" height="26,125" xoffset="-1" yoffset="1,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="97" x="420" y="742,75" width="43,125" height="46,875" xoffset="-6,625" yoffset="15" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="98" x="845,25" y="457,625" width="44,5" height="56,875" xoffset="-4,5" yoffset="4,75" xadvance="33,5" page="0" chnl="15" />
|
||||
<char id="99" x="508,125" y="740,5" width="41,75" height="46,75" xoffset="-6,625" yoffset="15" xadvance="28" page="0" chnl="15" />
|
||||
<char id="100" x="532,125" y="459,25" width="44,5" height="57,125" xoffset="-6,625" yoffset="4,75" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="101" x="463,25" y="740,75" width="44,75" height="46,75" xoffset="-6,625" yoffset="15" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="102" x="260,25" y="520,625" width="37,5" height="56,5" xoffset="-7,5" yoffset="4,5" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="103" x="889,875" y="457" width="44,5" height="56,875" xoffset="-6,625" yoffset="15" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="104" x="624,75" y="516,375" width="43,125" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="105" x="407,375" y="518,875" width="25,625" height="56,375" xoffset="-4,75" yoffset="4,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="106" x="818,625" y="139,125" width="33,875" height="67,25" xoffset="-10,125" yoffset="4,625" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="107" x="579,625" y="516,5" width="45" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="108" x="853" y="514,625" width="25" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="16" page="0" chnl="15" />
|
||||
<char id="109" x="591" y="737,625" width="59,75" height="46" xoffset="-4,625" yoffset="15" xadvance="50,5" page="0" chnl="15" />
|
||||
<char id="110" x="694,125" y="737,5" width="43,125" height="46" xoffset="-4,5" yoffset="15" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="111" x="373,875" y="742,75" width="46" height="46,875" xoffset="-6,625" yoffset="15" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="112" x="172,375" y="521,125" width="44,5" height="56,625" xoffset="-4,5" yoffset="15" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="113" x="127,75" y="521,625" width="44,5" height="56,625" xoffset="-6,625" yoffset="15" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="114" x="981,625" y="733,5" width="35,5" height="45,125" xoffset="-4,5" yoffset="15,875" xadvance="23" page="0" chnl="15" />
|
||||
<char id="115" x="550" y="740,375" width="40,875" height="46,75" xoffset="-6,5" yoffset="15" xadvance="27,25" page="0" chnl="15" />
|
||||
<char id="116" x="819,375" y="681,375" width="37,25" height="54" xoffset="-7,5" yoffset="7,625" xadvance="22" page="0" chnl="15" />
|
||||
<char id="117" x="650,875" y="737,625" width="43,125" height="46" xoffset="-4,75" yoffset="15,875" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="118" x="848,25" y="735,5" width="46,625" height="45,125" xoffset="-8" yoffset="15,875" xadvance="30,625" page="0" chnl="15" />
|
||||
<char id="119" x="737,375" y="737,375" width="62,375" height="45,125" xoffset="-7,625" yoffset="15,875" xadvance="47,125" page="0" chnl="15" />
|
||||
<char id="120" x="799,875" y="736" width="48,25" height="45,125" xoffset="-8,125" yoffset="15,875" xadvance="32" page="0" chnl="15" />
|
||||
<char id="121" x="416,375" y="575,375" width="46,75" height="55,75" xoffset="-8,125" yoffset="15,875" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="122" x="940,125" y="734,25" width="41,375" height="45,125" xoffset="-6,75" yoffset="15,875" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="123" x="463,875" y="207,375" width="44" height="66,375" xoffset="-6,5" yoffset="4,75" xadvance="33" page="0" chnl="15" />
|
||||
<char id="124" x="616,875" y="207,25" width="23,25" height="66,375" xoffset="5,25" yoffset="4,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="125" x="508" y="207,375" width="44" height="66,375" xoffset="-4,5" yoffset="4,75" xadvance="33" page="0" chnl="15" />
|
||||
<char id="126" x="602,25" y="783,75" width="52,5" height="33" xoffset="-4,5" yoffset="19,375" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="160" x="1002,125" y="0" width="16,125" height="16,125" xoffset="-8" yoffset="45" xadvance="15,5" page="0" chnl="15" />
|
||||
<char id="161" x="766,625" y="682,75" width="26,25" height="54,5" xoffset="-4" yoffset="6,5" xadvance="18,125" page="0" chnl="15" />
|
||||
<char id="162" x="44,75" y="342,25" width="42" height="63,375" xoffset="-4,125" yoffset="6,875" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="163" x="799,375" y="571,375" width="44,125" height="55,25" xoffset="-4,875" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="164" x="25,125" y="797,875" width="43,75" height="43,75" xoffset="-5" yoffset="14" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="165" x="49,875" y="693,25" width="48,75" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="166" x="640,25" y="207,25" width="23,25" height="66,375" xoffset="5,25" yoffset="4,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="167" x="636,875" y="273,75" width="44,375" height="65,375" xoffset="-5,25" yoffset="5,75" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="168" x="855,75" y="780,75" width="35,75" height="23,125" xoffset="-3,5" yoffset="4,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="169" x="292,625" y="341,25" width="60,75" height="60,75" xoffset="-5,75" yoffset="5,75" xadvance="49,25" page="0" chnl="15" />
|
||||
<char id="170" x="314,875" y="789,875" width="37,75" height="40,5" xoffset="-6,125" yoffset="5,75" xadvance="26,875" page="0" chnl="15" />
|
||||
<char id="171" x="114,5" y="796,375" width="45,375" height="42,375" xoffset="-4,625" yoffset="14,75" xadvance="37,25" page="0" chnl="15" />
|
||||
<char id="172" x="474,375" y="787,625" width="49,125" height="35,875" xoffset="-3" yoffset="23,875" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="173" x="924,875" y="779,5" width="33,125" height="23,125" xoffset="-5,125" yoffset="24,375" xadvance="22,875" page="0" chnl="15" />
|
||||
<char id="174" x="231,75" y="341,625" width="60,75" height="60,75" xoffset="-5,75" yoffset="5,75" xadvance="49,25" page="0" chnl="15" />
|
||||
<char id="175" x="0" y="843,125" width="50,5" height="21,25" xoffset="-8,375" yoffset="-2,375" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="176" x="437,25" y="789,75" width="37" height="36,875" xoffset="-4,75" yoffset="5,75" xadvance="27,5" page="0" chnl="15" />
|
||||
<char id="177" x="894,125" y="681,125" width="49,375" height="53" xoffset="-3" yoffset="8" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="178" x="278,25" y="790,875" width="36,5" height="40,625" xoffset="-3,375" yoffset="5,75" xadvance="28,625" page="0" chnl="15" />
|
||||
<char id="179" x="202" y="791,125" width="36" height="41,25" xoffset="-3,625" yoffset="5,75" xadvance="28,625" page="0" chnl="15" />
|
||||
<char id="180" x="775,25" y="782,625" width="29,875" height="26,125" xoffset="0,875" yoffset="1,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="181" x="463,25" y="575,25" width="43,5" height="55,75" xoffset="-4,5" yoffset="15,875" xadvance="34,5" page="0" chnl="15" />
|
||||
<char id="182" x="0" y="342,25" width="44,625" height="63,875" xoffset="-6,25" yoffset="6,5" xadvance="33,75" page="0" chnl="15" />
|
||||
<char id="183" x="805,25" y="781,25" width="25,125" height="26,125" xoffset="-3" yoffset="15,875" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="184" x="715" y="783,625" width="30,125" height="27,375" xoffset="-0,625" yoffset="44,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="185" x="352,75" y="789,875" width="33,875" height="39,875" xoffset="-2,125" yoffset="6,5" xadvance="28,625" page="0" chnl="15" />
|
||||
<char id="186" x="238,125" y="791,125" width="40" height="40,625" xoffset="-5,375" yoffset="5,75" xadvance="28,625" page="0" chnl="15" />
|
||||
<char id="187" x="69" y="797,25" width="45,375" height="42,375" xoffset="-3,25" yoffset="14,75" xadvance="37,25" page="0" chnl="15" />
|
||||
<char id="188" x="69,75" y="637,5" width="68,125" height="54,75" xoffset="-3,75" yoffset="6,25" xadvance="59,75" page="0" chnl="15" />
|
||||
<char id="189" x="0" y="638,375" width="69,625" height="54,75" xoffset="-4,25" yoffset="6,25" xadvance="59,75" page="0" chnl="15" />
|
||||
<char id="190" x="684" y="572,75" width="70,875" height="55,25" xoffset="-4,375" yoffset="5,75" xadvance="59,75" page="0" chnl="15" />
|
||||
<char id="191" x="642,75" y="572,75" width="41,125" height="55,375" xoffset="-6" yoffset="6,5" xadvance="30" page="0" chnl="15" />
|
||||
<char id="192" x="113,75" y="70,375" width="52,5" height="69" xoffset="-8,125" yoffset="-8" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="193" x="166,375" y="70,125" width="52,5" height="69" xoffset="-8,125" yoffset="-8" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="194" x="255,75" y="139,25" width="52,5" height="68,75" xoffset="-8,125" yoffset="-7,75" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="195" x="925,125" y="139" width="52,5" height="67" xoffset="-8,125" yoffset="-6" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="196" x="907,875" y="206,25" width="52,5" height="66" xoffset="-8,125" yoffset="-5" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="197" x="960,5" y="206,125" width="52,5" height="66" xoffset="-8,125" yoffset="-5" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="198" x="321,625" y="633,5" width="66,25" height="54,5" xoffset="-8,5" yoffset="6,5" xadvance="52,375" page="0" chnl="15" />
|
||||
<char id="199" x="767,625" y="206,5" width="47,875" height="66,125" xoffset="-6,25" yoffset="5,75" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="200" x="757,125" y="70" width="42,125" height="69" xoffset="-4" yoffset="-8" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="201" x="799,375" y="70" width="42,125" height="69" xoffset="-4" yoffset="-8" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="202" x="883,875" y="69,875" width="42,125" height="69" xoffset="-4" yoffset="-8" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="203" x="141,375" y="275,625" width="42,125" height="66" xoffset="-4" yoffset="-5" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="204" x="36,75" y="139,875" width="36,625" height="69" xoffset="-5,5" yoffset="-8" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="205" x="0" y="139,875" width="36,625" height="69" xoffset="-5,5" yoffset="-8" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="206" x="968" y="69,75" width="37,875" height="69" xoffset="-6,125" yoffset="-8" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="207" x="183,625" y="275,5" width="36,625" height="66" xoffset="-5,5" yoffset="-5" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="208" x="499" y="631,125" width="54,75" height="54,5" xoffset="-7,5" yoffset="6,5" xadvance="41" page="0" chnl="15" />
|
||||
<char id="209" x="642,375" y="139,125" width="48,875" height="67,25" xoffset="-4" yoffset="-6,25" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="210" x="326,125" y="0" width="53,25" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="211" x="272,75" y="0" width="53,25" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="212" x="219,375" y="0" width="53,25" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="213" x="360,875" y="139,125" width="53,25" height="68,125" xoffset="-6,25" yoffset="-6,25" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="214" x="46,875" y="209" width="53,25" height="66,875" xoffset="-6,25" yoffset="-5" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="215" x="197,75" y="743,875" width="47,125" height="47,125" xoffset="-1,875" yoffset="12,375" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="216" x="353,5" y="341" width="53,25" height="60,5" xoffset="-6,25" yoffset="3,875" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="217" x="580" y="0" width="48,125" height="69,875" xoffset="-4,5" yoffset="-8" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="218" x="531,75" y="0" width="48,125" height="69,875" xoffset="-4,5" yoffset="-8" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="219" x="483,5" y="0" width="48,125" height="69,875" xoffset="-4,5" yoffset="-8" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="220" x="150,875" y="208,5" width="48,125" height="66,875" xoffset="-4,5" yoffset="-5" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="221" x="308,375" y="139,125" width="52,375" height="68,75" xoffset="-8,5" yoffset="-7,75" xadvance="35,5" page="0" chnl="15" />
|
||||
<char id="222" x="384,25" y="688,125" width="45,75" height="54,5" xoffset="-4" yoffset="6,5" xadvance="34,875" page="0" chnl="15" />
|
||||
<char id="223" x="799,75" y="457,75" width="45,375" height="56,875" xoffset="-4,5" yoffset="4,5" xadvance="34,25" page="0" chnl="15" />
|
||||
<char id="224" x="591,375" y="339,25" width="43,125" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="225" x="850,875" y="338" width="43,125" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="226" x="634,625" y="339,25" width="43,125" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="227" x="924,375" y="398" width="43,125" height="58,5" xoffset="-6,625" yoffset="3,375" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="228" x="202,375" y="463,25" width="43,125" height="57,25" xoffset="-6,625" yoffset="4,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="229" x="130,125" y="342,125" width="43,125" height="61,25" xoffset="-6,625" yoffset="0,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="230" x="310,625" y="742,875" width="63,125" height="46,875" xoffset="-6,625" yoffset="15" xadvance="49,625" page="0" chnl="15" />
|
||||
<char id="231" x="0" y="525,125" width="41,75" height="56,875" xoffset="-6,625" yoffset="15" xadvance="28" page="0" chnl="15" />
|
||||
<char id="232" x="0" y="406,25" width="44,75" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="233" x="939" y="337,25" width="44,75" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="234" x="894,125" y="337,75" width="44,75" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="235" x="487,25" y="459,625" width="44,75" height="57,125" xoffset="-6,625" yoffset="4,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="236" x="670,75" y="399,625" width="29,875" height="59,375" xoffset="-8,125" yoffset="1,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="237" x="640,75" y="399,625" width="29,875" height="59,375" xoffset="-5,625" yoffset="1,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="238" x="606,5" y="399,625" width="34,125" height="59,375" xoffset="-9,125" yoffset="1,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="239" x="373,375" y="518,875" width="33,875" height="56,375" xoffset="-8,875" yoffset="4,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="240" x="75,5" y="466" width="46,125" height="57,5" xoffset="-6,625" yoffset="4,375" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="241" x="32,25" y="466,5" width="43,125" height="57,625" xoffset="-4,5" yoffset="3,375" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="242" x="499,125" y="339,375" width="46" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="243" x="453" y="339,75" width="46" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="244" x="406,875" y="339,75" width="46" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="245" x="878,25" y="398,375" width="46" height="58,5" xoffset="-6,625" yoffset="3,375" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="246" x="156,25" y="463,75" width="46" height="57,25" xoffset="-6,625" yoffset="4,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="247" x="0" y="747,875" width="49,375" height="49,875" xoffset="-3" yoffset="11" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="248" x="943,625" y="680,75" width="46" height="52,625" xoffset="-6,625" yoffset="12,5" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="249" x="677,875" y="339,25" width="43,125" height="60,25" xoffset="-4,75" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="250" x="721,125" y="338,25" width="43,125" height="60,25" xoffset="-4,75" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="251" x="764,375" y="338" width="43,125" height="60,25" xoffset="-4,75" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="252" x="245,625" y="463,25" width="43,125" height="57,25" xoffset="-4,75" yoffset="4,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="253" x="172,5" y="0" width="46,75" height="70" xoffset="-8,125" yoffset="1,625" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="254" x="247,125" y="208,25" width="44,5" height="66,875" xoffset="-4,5" yoffset="4,75" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="255" x="0" y="209" width="46,75" height="67" xoffset="-8,125" yoffset="4,625" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="256" x="257,125" y="275,25" width="52,5" height="65,875" xoffset="-8,125" yoffset="-4,875" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="257" x="620" y="459,125" width="43,125" height="57,125" xoffset="-6,625" yoffset="4,75" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="258" x="510,75" y="139,125" width="52,5" height="68" xoffset="-8,125" yoffset="-7" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="259" x="746,875" y="398,625" width="43,125" height="59,25" xoffset="-6,625" yoffset="2,625" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="260" x="723,25" y="272,75" width="52,5" height="65,125" xoffset="-8,125" yoffset="6,5" xadvance="36,25" page="0" chnl="15" />
|
||||
<char id="261" x="217" y="520,625" width="43,125" height="56,625" xoffset="-6,625" yoffset="15" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="262" x="724,5" y="0" width="47,875" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="263" x="174" y="403" width="41,75" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="28" page="0" chnl="15" />
|
||||
<char id="264" x="676,5" y="0" width="47,875" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="265" x="131,875" y="403,5" width="42" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="28" page="0" chnl="15" />
|
||||
<char id="266" x="199,125" y="208,5" width="47,875" height="66,875" xoffset="-6,25" yoffset="-5" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="267" x="663,25" y="459,125" width="41,75" height="57,125" xoffset="-6,625" yoffset="4,625" xadvance="28" page="0" chnl="15" />
|
||||
<char id="268" x="772,5" y="0" width="47,875" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="269" x="89,75" y="403,75" width="42" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="28" page="0" chnl="15" />
|
||||
<char id="270" x="375" y="70" width="50,375" height="69" xoffset="-4" yoffset="-8" xadvance="40,125" page="0" chnl="15" />
|
||||
<char id="271" x="288,875" y="462,75" width="59,25" height="57,125" xoffset="-6,625" yoffset="4,75" xadvance="43,375" page="0" chnl="15" />
|
||||
<char id="272" x="553,875" y="628,375" width="54,75" height="54,5" xoffset="-7,5" yoffset="6,5" xadvance="41" page="0" chnl="15" />
|
||||
<char id="273" x="348,25" y="461,625" width="47,875" height="57,125" xoffset="-6,625" yoffset="4,75" xadvance="33,125" page="0" chnl="15" />
|
||||
<char id="274" x="309,75" y="275,125" width="42,125" height="65,875" xoffset="-4" yoffset="-4,875" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="275" x="705,125" y="459" width="44,75" height="57" xoffset="-6,625" yoffset="4,75" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="276" x="563,375" y="139,125" width="42,125" height="68" xoffset="-4" yoffset="-7" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="277" x="833,375" y="398,375" width="44,75" height="59,125" xoffset="-6,625" yoffset="2,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="278" x="99,125" y="276" width="42,125" height="66" xoffset="-4" yoffset="-5" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="279" x="442,375" y="461,125" width="44,75" height="57,125" xoffset="-6,625" yoffset="4,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="280" x="824,125" y="272,75" width="42,125" height="65,125" xoffset="-4" yoffset="6,5" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="281" x="82,875" y="523,625" width="44,75" height="56,625" xoffset="-6,625" yoffset="15" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="282" x="841,625" y="69,875" width="42,125" height="69" xoffset="-4" yoffset="-8" xadvance="32,625" page="0" chnl="15" />
|
||||
<char id="283" x="44,875" y="405,75" width="44,75" height="60,125" xoffset="-6,625" yoffset="1,625" xadvance="31,5" page="0" chnl="15" />
|
||||
<char id="284" x="432,875" y="0" width="50,5" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="39,5" page="0" chnl="15" />
|
||||
<char id="285" x="44,625" y="0" width="44,5" height="70,25" xoffset="-6,625" yoffset="1,625" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="286" x="156,875" y="139,5" width="50,5" height="68,875" xoffset="-6,25" yoffset="-7" xadvance="39,5" page="0" chnl="15" />
|
||||
<char id="287" x="0" y="70,5" width="44,5" height="69,25" xoffset="-6,625" yoffset="2,625" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="288" x="100,25" y="208,625" width="50,5" height="66,875" xoffset="-6,25" yoffset="-5" xadvance="39,5" page="0" chnl="15" />
|
||||
<char id="289" x="691,375" y="139,125" width="44,5" height="67,25" xoffset="-6,625" yoffset="4,625" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="290" x="717" y="206,5" width="50,5" height="66,125" xoffset="-6,25" yoffset="5,75" xadvance="39,5" page="0" chnl="15" />
|
||||
<char id="291" x="0" y="0" width="44,5" height="70,375" xoffset="-6,625" yoffset="1,5" xadvance="33,375" page="0" chnl="15" />
|
||||
<char id="292" x="523,5" y="70" width="48,5" height="69" xoffset="-4" yoffset="-8" xadvance="40,5" page="0" chnl="15" />
|
||||
<char id="293" x="713,875" y="70" width="43,125" height="69" xoffset="-4,5" yoffset="-8" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="294" x="388" y="631,5" width="55,375" height="54,5" xoffset="-7" yoffset="6,5" xadvance="41,375" page="0" chnl="15" />
|
||||
<char id="295" x="533" y="516,5" width="46,5" height="56,25" xoffset="-8,125" yoffset="4,75" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="296" x="779,75" y="139,125" width="38,75" height="67,25" xoffset="-6,5" yoffset="-6,25" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="297" x="121,75" y="464" width="34,375" height="57,5" xoffset="-9,125" yoffset="3,5" xadvance="16" page="0" chnl="15" />
|
||||
<char id="298" x="352" y="275" width="36,625" height="65,875" xoffset="-5,5" yoffset="-4,875" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="299" x="821,625" y="514,75" width="31,25" height="56,25" xoffset="-7,625" yoffset="4,75" xadvance="16" page="0" chnl="15" />
|
||||
<char id="300" x="605,625" y="139,125" width="36,625" height="68" xoffset="-5,5" yoffset="-7" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="301" x="0" y="466,5" width="32,125" height="58,5" xoffset="-8" yoffset="2,5" xadvance="16" page="0" chnl="15" />
|
||||
<char id="302" x="866,375" y="272,5" width="36,625" height="65,125" xoffset="-5,5" yoffset="6,5" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="303" x="977,75" y="138,875" width="26,375" height="67" xoffset="-5,5" yoffset="4,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="304" x="220,375" y="275,5" width="36,625" height="66" xoffset="-5,5" yoffset="-5" xadvance="25,625" page="0" chnl="15" />
|
||||
<char id="305" x="0" y="797,875" width="25" height="45,125" xoffset="-4,5" yoffset="15,875" xadvance="16" page="0" chnl="15" />
|
||||
<char id="306" x="884,875" y="570,875" width="59,875" height="55,125" xoffset="-5,5" yoffset="6,5" xadvance="49,875" page="0" chnl="15" />
|
||||
<char id="307" x="736" y="139,125" width="43,625" height="67,25" xoffset="-4,75" yoffset="4,625" xadvance="34,375" page="0" chnl="15" />
|
||||
<char id="308" x="961,125" y="0" width="40,875" height="69,625" xoffset="-7,875" yoffset="-8" xadvance="26,5" page="0" chnl="15" />
|
||||
<char id="309" x="89,25" y="0" width="36,25" height="70,25" xoffset="-10,125" yoffset="1,625" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="310" x="440,5" y="274,25" width="49,75" height="65,375" xoffset="-4" yoffset="6,5" xadvance="36,875" page="0" chnl="15" />
|
||||
<char id="311" x="852,625" y="139" width="45" height="67,125" xoffset="-4,5" yoffset="4,75" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="312" x="895" y="734,25" width="45" height="45,125" xoffset="-4,5" yoffset="15,875" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="313" x="926,125" y="69,875" width="41,75" height="69" xoffset="-4" yoffset="-8" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="314" x="73,5" y="139,5" width="29,875" height="69" xoffset="-5,5" yoffset="-8" xadvance="16" page="0" chnl="15" />
|
||||
<char id="315" x="681,375" y="272,75" width="41,75" height="65,375" xoffset="-4" yoffset="6,5" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="316" x="897,75" y="139" width="27,25" height="67,125" xoffset="-5,5" yoffset="4,75" xadvance="16" page="0" chnl="15" />
|
||||
<char id="317" x="668" y="516,375" width="43" height="56,25" xoffset="-4" yoffset="4,75" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="318" x="711,125" y="516,125" width="39,75" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="26" page="0" chnl="15" />
|
||||
<char id="319" x="604,5" y="683" width="41,75" height="54,5" xoffset="-4" yoffset="6,5" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="320" x="751" y="515" width="37,5" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="25,875" page="0" chnl="15" />
|
||||
<char id="321" x="338" y="688,125" width="46,125" height="54,5" xoffset="-7,5" yoffset="6,5" xadvance="31,25" page="0" chnl="15" />
|
||||
<char id="322" x="788,625" y="515" width="32,875" height="56,25" xoffset="-7,5" yoffset="4,75" xadvance="17,75" page="0" chnl="15" />
|
||||
<char id="323" x="425,5" y="70" width="48,875" height="69" xoffset="-4" yoffset="-8" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="324" x="401,375" y="401,625" width="43,125" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="325" x="490,375" y="273,875" width="48,875" height="65,375" xoffset="-4" yoffset="6,5" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="326" x="934,5" y="456,625" width="43,125" height="56,875" xoffset="-4,5" yoffset="15" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="327" x="474,5" y="70" width="48,875" height="69" xoffset="-4" yoffset="-8" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="328" x="444,625" y="400,125" width="43,125" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="329" x="433,125" y="518,875" width="53,125" height="56,25" xoffset="-9" yoffset="4,75" xadvance="39,375" page="0" chnl="15" />
|
||||
<char id="330" x="539,375" y="273,875" width="48,875" height="65,375" xoffset="-4" yoffset="6,5" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="331" x="977,75" y="456,125" width="43,125" height="56,875" xoffset="-4,5" yoffset="15" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="332" x="362,25" y="207,375" width="53,25" height="66,75" xoffset="-6,25" yoffset="-4,875" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="333" x="396,25" y="461,625" width="46" height="57,125" xoffset="-6,625" yoffset="4,75" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="334" x="103,5" y="139,5" width="53,25" height="68,875" xoffset="-6,25" yoffset="-7" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="335" x="700,75" y="399,625" width="46" height="59,25" xoffset="-6,625" yoffset="2,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="336" x="379,5" y="0" width="53,25" height="69,875" xoffset="-6,25" yoffset="-8" xadvance="40,75" page="0" chnl="15" />
|
||||
<char id="337" x="545,25" y="339,375" width="46" height="60,25" xoffset="-6,625" yoffset="1,625" xadvance="32,75" page="0" chnl="15" />
|
||||
<char id="338" x="254,875" y="633,625" width="66,625" height="54,5" xoffset="-6,25" yoffset="6,5" xadvance="55" page="0" chnl="15" />
|
||||
<char id="339" x="245" y="743,875" width="65,5" height="46,875" xoffset="-6,625" yoffset="15" xadvance="52,25" page="0" chnl="15" />
|
||||
<char id="340" x="323,25" y="70" width="51,625" height="69" xoffset="-4" yoffset="-8" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="341" x="570,875" y="399,75" width="35,5" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="23" page="0" chnl="15" />
|
||||
<char id="342" x="388,75" y="274,25" width="51,625" height="65,375" xoffset="-4" yoffset="6,5" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="343" x="380,75" y="575,375" width="35,5" height="56" xoffset="-4,5" yoffset="15,875" xadvance="23" page="0" chnl="15" />
|
||||
<char id="344" x="271,5" y="70" width="51,625" height="69" xoffset="-4" yoffset="-8" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="345" x="983,875" y="336,625" width="38,875" height="59,375" xoffset="-6,625" yoffset="1,625" xadvance="23" page="0" chnl="15" />
|
||||
<char id="346" x="867,375" y="0" width="46,75" height="69,75" xoffset="-6,125" yoffset="-8" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="347" x="256,875" y="402,5" width="40,875" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,25" page="0" chnl="15" />
|
||||
<char id="348" x="820,5" y="0" width="46,75" height="69,75" xoffset="-6,125" yoffset="-8" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="349" x="215,875" y="403" width="40,875" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,25" page="0" chnl="15" />
|
||||
<char id="350" x="815,625" y="206,5" width="46,75" height="66,125" xoffset="-6,125" yoffset="5,75" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="351" x="41,875" y="524,25" width="40,875" height="56,875" xoffset="-6,5" yoffset="15" xadvance="27,25" page="0" chnl="15" />
|
||||
<char id="352" x="914,25" y="0" width="46,75" height="69,75" xoffset="-6,125" yoffset="-8" xadvance="33,625" page="0" chnl="15" />
|
||||
<char id="353" x="297,875" y="402,125" width="40,875" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,25" page="0" chnl="15" />
|
||||
<char id="354" x="588,375" y="273,75" width="48,375" height="65,375" xoffset="-8" yoffset="6,5" xadvance="32,5" page="0" chnl="15" />
|
||||
<char id="355" x="980,875" y="272,25" width="37,25" height="64,25" xoffset="-7,5" yoffset="7,625" xadvance="22" page="0" chnl="15" />
|
||||
<char id="356" x="572,125" y="70" width="48,375" height="69" xoffset="-8" yoffset="-8" xadvance="32,5" page="0" chnl="15" />
|
||||
<char id="357" x="750" y="458" width="49,625" height="56,875" xoffset="-7,5" yoffset="4,75" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="358" x="195,875" y="689,25" width="48,375" height="54,5" xoffset="-8" yoffset="6,5" xadvance="32,5" page="0" chnl="15" />
|
||||
<char id="359" x="856,75" y="681,375" width="37,25" height="54" xoffset="-7,5" yoffset="7,625" xadvance="22" page="0" chnl="15" />
|
||||
<char id="360" x="414,25" y="139,125" width="48,125" height="68,125" xoffset="-4,5" yoffset="-6,25" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="361" x="967,625" y="397,5" width="43,125" height="58,5" xoffset="-4,75" yoffset="3,375" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="362" x="415,625" y="207,375" width="48,125" height="66,75" xoffset="-4,5" yoffset="-4,875" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="363" x="576,75" y="459,25" width="43,125" height="57,125" xoffset="-4,75" yoffset="4,75" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="364" x="207,5" y="139,25" width="48,125" height="68,875" xoffset="-4,5" yoffset="-7" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="365" x="790,125" y="398,375" width="43,125" height="59,25" xoffset="-4,75" yoffset="2,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="366" x="462,5" y="139,125" width="48,125" height="68,125" xoffset="-4,5" yoffset="-6,25" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="367" x="86,875" y="342,125" width="43,125" height="61,5" xoffset="-4,75" yoffset="0,375" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="368" x="628,25" y="0" width="48,125" height="69,875" xoffset="-4,5" yoffset="-8" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="369" x="807,625" y="338" width="43,125" height="60,25" xoffset="-4,75" yoffset="1,625" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="370" x="775,875" y="272,75" width="48,125" height="65,125" xoffset="-4,5" yoffset="6,5" xadvance="39,125" page="0" chnl="15" />
|
||||
<char id="371" x="506,875" y="574,75" width="43,125" height="55,75" xoffset="-4,75" yoffset="15,875" xadvance="33,875" page="0" chnl="15" />
|
||||
<char id="372" x="44,625" y="70,375" width="69" height="69" xoffset="-7,25" yoffset="-8" xadvance="54,5" page="0" chnl="15" />
|
||||
<char id="373" x="338,875" y="402,125" width="62,375" height="59,375" xoffset="-7,625" yoffset="1,625" xadvance="47,125" page="0" chnl="15" />
|
||||
<char id="374" x="219" y="70,125" width="52,375" height="69" xoffset="-8,5" yoffset="-8" xadvance="35,5" page="0" chnl="15" />
|
||||
<char id="375" x="125,625" y="0" width="46,75" height="70" xoffset="-8,125" yoffset="1,625" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="376" x="0" y="276,125" width="52,375" height="66" xoffset="-8,5" yoffset="-5" xadvance="35,5" page="0" chnl="15" />
|
||||
<char id="377" x="667,25" y="70" width="46,5" height="69" xoffset="-6,625" yoffset="-8" xadvance="33" page="0" chnl="15" />
|
||||
<char id="378" x="529,375" y="399,75" width="41,375" height="59,375" xoffset="-6,75" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="379" x="52,5" y="276" width="46,5" height="66" xoffset="-6,625" yoffset="-5" xadvance="33" page="0" chnl="15" />
|
||||
<char id="380" x="331,875" y="520" width="41,375" height="56,375" xoffset="-6,75" yoffset="4,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="381" x="620,625" y="70" width="46,5" height="69" xoffset="-6,625" yoffset="-8" xadvance="33" page="0" chnl="15" />
|
||||
<char id="382" x="487,875" y="400,125" width="41,375" height="59,375" xoffset="-6,75" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="383" x="297,875" y="520" width="33,875" height="56,5" xoffset="-4,5" yoffset="4,5" xadvance="17,125" page="0" chnl="15" />
|
||||
</chars>
|
||||
</font>
|
||||
BIN
rainbow/CoreGl/Fonts/TahomaB_0.png
Normal file
BIN
rainbow/CoreGl/Fonts/TahomaB_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 321 KiB |
796
rainbow/CoreGl/Fonts/TahomaN.fnt
Normal file
796
rainbow/CoreGl/Fonts/TahomaN.fnt
Normal file
|
|
@ -0,0 +1,796 @@
|
|||
<?xml version="1.0"?>
|
||||
<font>
|
||||
<info face="Tahoma" size="64" bold="0" italic="0" charset="" unicode="1" stretchH="100" smooth="0" aa="1" padding="64,64,64,64" spacing="1,1" outline="0" />
|
||||
<common lineHeight="64" base="53" scaleW="1024" scaleH="1024" pages="1" packed="0" alphaChnl="0" redChnl="0" greenChnl="0" blueChnl="0" />
|
||||
<pages>
|
||||
<page id="0" file="TahomaN_0.png" />
|
||||
</pages>
|
||||
<chars count="319">
|
||||
<char id="32" x="1005,625" y="0" width="16,125" height="16,125" xoffset="-8" yoffset="45" xadvance="16,625" page="0" chnl="15" />
|
||||
<char id="33" x="667,125" y="619,5" width="21,75" height="54,5" xoffset="-2,125" yoffset="6,5" xadvance="17,625" page="0" chnl="15" />
|
||||
<char id="34" x="338,875" y="724,5" width="31,375" height="31" xoffset="-5" yoffset="4,75" xadvance="21,25" page="0" chnl="15" />
|
||||
<char id="35" x="647,25" y="564,875" width="47,25" height="54,5" xoffset="-4,375" yoffset="6,5" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="36" x="42,25" y="208,375" width="39,75" height="66,125" xoffset="-5,25" yoffset="4,125" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="37" x="538,875" y="453,5" width="62,5" height="56" xoffset="-5,375" yoffset="5,75" xadvance="51,75" page="0" chnl="15" />
|
||||
<char id="38" x="601,5" y="453,375" width="51,625" height="56" xoffset="-6,25" yoffset="5,75" xadvance="35,75" page="0" chnl="15" />
|
||||
<char id="39" x="370,375" y="724,5" width="21,625" height="31" xoffset="-5,25" yoffset="4,75" xadvance="11,125" page="0" chnl="15" />
|
||||
<char id="40" x="686,25" y="139" width="31,625" height="66,875" xoffset="-5,25" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="41" x="718" y="139" width="31,625" height="66,875" xoffset="-6,125" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="42" x="66,75" y="727,125" width="39,375" height="40" xoffset="-5,125" yoffset="4,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="43" x="973,75" y="613,75" width="46,5" height="46,375" xoffset="-4" yoffset="12,875" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="44" x="267" y="725,875" width="27" height="33" xoffset="-6,125" yoffset="37,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="45" x="598,875" y="719,5" width="30,625" height="20,625" xoffset="-5,625" yoffset="25,75" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="46" x="522,375" y="722,5" width="22,125" height="23,375" xoffset="-3,125" yoffset="37,625" xadvance="16" page="0" chnl="15" />
|
||||
<char id="47" x="79,5" y="274,625" width="35,5" height="64,625" xoffset="-8,625" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="48" x="920,5" y="447,75" width="40,625" height="56" xoffset="-5,875" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="49" x="0" y="571,625" width="34,875" height="54,625" xoffset="-2,25" yoffset="6,375" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="50" x="581,375" y="509,625" width="39,75" height="55,25" xoffset="-5,125" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="51" x="961,25" y="447,125" width="39,375" height="56" xoffset="-5,5" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="52" x="131" y="625,875" width="42,625" height="54,5" xoffset="-7" yoffset="6,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="53" x="660,375" y="506,375" width="39" height="55,25" xoffset="-4,75" yoffset="6,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="54" x="879,375" y="447,75" width="41" height="56" xoffset="-5,75" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="55" x="341,375" y="624,125" width="40,5" height="54,5" xoffset="-5,375" yoffset="6,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="56" x="497,625" y="453,625" width="41,125" height="56,125" xoffset="-6,125" yoffset="5,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="57" x="838,25" y="448,375" width="41" height="56" xoffset="-6,25" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="58" x="723" y="670,25" width="22,125" height="44,875" xoffset="-1,75" yoffset="16,125" xadvance="18,75" page="0" chnl="15" />
|
||||
<char id="59" x="640" y="619,625" width="27" height="54,5" xoffset="-4,875" yoffset="16,125" xadvance="18,75" page="0" chnl="15" />
|
||||
<char id="60" x="354,625" y="678,75" width="43,75" height="45,625" xoffset="-2,75" yoffset="13,375" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="61" x="294,125" y="725,875" width="44,625" height="31" xoffset="-3" yoffset="20,625" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="62" x="310,75" y="678,75" width="43,75" height="45,625" xoffset="-2,375" yoffset="13,375" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="63" x="775,125" y="506" width="36,75" height="55,25" xoffset="-5,125" yoffset="5,75" xadvance="25,125" page="0" chnl="15" />
|
||||
<char id="64" x="708,375" y="271,375" width="57,75" height="61,125" xoffset="-4,625" yoffset="5,75" xadvance="48,125" page="0" chnl="15" />
|
||||
<char id="65" x="550,625" y="565" width="48,25" height="54,5" xoffset="-8,25" yoffset="6,5" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="66" x="216,5" y="625,5" width="42,125" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="31,25" page="0" chnl="15" />
|
||||
<char id="67" x="750,625" y="449,875" width="45,25" height="56" xoffset="-6,25" yoffset="5,75" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="68" x="836,375" y="560,125" width="46,375" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="36" page="0" chnl="15" />
|
||||
<char id="69" x="422,5" y="622,875" width="40,125" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="70" x="462,75" y="622,875" width="39,125" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="27,625" page="0" chnl="15" />
|
||||
<char id="71" x="703,375" y="450,25" width="47,125" height="56" xoffset="-6,25" yoffset="5,75" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="72" x="0" y="626,375" width="44" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="35,75" page="0" chnl="15" />
|
||||
<char id="73" x="579" y="619,625" width="30,875" height="54,5" xoffset="-5,5" yoffset="6,5" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="74" x="901,75" y="503,875" width="34,25" height="55,125" xoffset="-7,75" yoffset="6,5" xadvance="22,125" page="0" chnl="15" />
|
||||
<char id="75" x="975,25" y="558,125" width="44,125" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="31,125" page="0" chnl="15" />
|
||||
<char id="76" x="540,5" y="619,875" width="38,375" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="77" x="501,375" y="565,25" width="49,125" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="40,875" page="0" chnl="15" />
|
||||
<char id="78" x="44,125" y="626" width="43,625" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="79" x="653,25" y="450,25" width="50" height="56" xoffset="-6,25" yoffset="5,75" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="80" x="382" y="624" width="40,375" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="81" x="213,125" y="207,75" width="50,125" height="65,375" xoffset="-6,25" yoffset="5,75" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="82" x="929,25" y="559,125" width="45,875" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="83" x="796" y="448,75" width="42,125" height="56" xoffset="-6" yoffset="5,75" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="84" x="789,125" y="561,375" width="47,125" height="54,5" xoffset="-8,125" yoffset="6,5" xadvance="31" page="0" chnl="15" />
|
||||
<char id="85" x="455,125" y="511" width="43,75" height="55,25" xoffset="-4,5" yoffset="6,5" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="86" x="599" y="565" width="48,125" height="54,5" xoffset="-8,25" yoffset="6,5" xadvance="31,625" page="0" chnl="15" />
|
||||
<char id="87" x="163,125" y="570,875" width="62,5" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="47,75" page="0" chnl="15" />
|
||||
<char id="88" x="882,875" y="559,75" width="46,25" height="54,5" xoffset="-7,75" yoffset="6,5" xadvance="30,75" page="0" chnl="15" />
|
||||
<char id="89" x="741,875" y="561,75" width="47,125" height="54,5" xoffset="-8,25" yoffset="6,5" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="90" x="87,875" y="626" width="43" height="54,5" xoffset="-6,5" yoffset="6,5" xadvance="29,625" page="0" chnl="15" />
|
||||
<char id="91" x="824,75" y="139" width="29,5" height="66,375" xoffset="-3,75" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="92" x="43,875" y="274,625" width="35,5" height="64,625" xoffset="-6,625" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="93" x="854,375" y="139" width="29,5" height="66,375" xoffset="-5,5" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="94" x="137,125" y="727,125" width="47,625" height="36,875" xoffset="-4,5" yoffset="6,5" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="95" x="706,25" y="719,125" width="45,625" height="19,375" xoffset="-8,375" yoffset="49,375" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="96" x="495,375" y="722,5" width="26,875" height="25,625" xoffset="-1,625" yoffset="1,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="97" x="101,625" y="680,625" width="39" height="46,375" xoffset="-6,5" yoffset="15,375" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="98" x="690,375" y="393,125" width="40,25" height="57" xoffset="-4,5" yoffset="4,75" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="99" x="181,75" y="680,125" width="38,125" height="46,25" xoffset="-6,5" yoffset="15,375" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="100" x="650" y="393,125" width="40,25" height="57" xoffset="-6,5" yoffset="4,75" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="101" x="140,75" y="680,5" width="40,875" height="46,25" xoffset="-6,5" yoffset="15,375" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="102" x="966" y="390,5" width="34" height="56,5" xoffset="-7,25" yoffset="4,5" xadvance="16,875" page="0" chnl="15" />
|
||||
<char id="103" x="772,875" y="392,125" width="40,25" height="56,5" xoffset="-6,5" yoffset="15,375" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="104" x="324,125" y="457,125" width="38,625" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="105" x="1000,75" y="446,125" width="21,5" height="54,75" xoffset="-4,625" yoffset="6,25" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="106" x="159,125" y="208" width="29,75" height="65,625" xoffset="-10,375" yoffset="6,25" xadvance="14,875" page="0" chnl="15" />
|
||||
<char id="107" x="284" y="457,5" width="40" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="108" x="1000,125" y="389,75" width="20,875" height="56,25" xoffset="-4,375" yoffset="4,75" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="109" x="257" y="680,125" width="53,625" height="45,625" xoffset="-4,5" yoffset="15,375" xadvance="44,5" page="0" chnl="15" />
|
||||
<char id="110" x="437,25" y="677,5" width="38,625" height="45,625" xoffset="-4,5" yoffset="15,375" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="111" x="59,75" y="680,625" width="41,75" height="46,375" xoffset="-6,5" yoffset="15,375" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="112" x="203,25" y="458,125" width="40,25" height="56,25" xoffset="-4,5" yoffset="15,375" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="113" x="243,625" y="457,625" width="40,25" height="56,25" xoffset="-6,5" yoffset="15,375" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="114" x="691,5" y="674,125" width="31,375" height="44,875" xoffset="-4,5" yoffset="16,125" xadvance="19,125" page="0" chnl="15" />
|
||||
<char id="115" x="220" y="680,125" width="36,875" height="46,25" xoffset="-6,25" yoffset="15,375" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="116" x="710,875" y="616,375" width="33" height="53,75" xoffset="-7,375" yoffset="7,875" xadvance="17,75" page="0" chnl="15" />
|
||||
<char id="117" x="398,5" y="678,625" width="38,625" height="45,625" xoffset="-4,625" yoffset="16,125" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="118" x="530" y="674,5" width="42,125" height="44,875" xoffset="-7,875" yoffset="16,125" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="119" x="476" y="677,5" width="53,875" height="44,875" xoffset="-7,25" yoffset="16,125" xadvance="39,375" page="0" chnl="15" />
|
||||
<char id="120" x="572,25" y="674,5" width="41,75" height="44,875" xoffset="-7,75" yoffset="16,125" xadvance="26,25" page="0" chnl="15" />
|
||||
<char id="121" x="71,875" y="515,625" width="42,125" height="55,5" xoffset="-7,875" yoffset="16,125" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="122" x="654,25" y="674,25" width="37,125" height="44,875" xoffset="-6,75" yoffset="16,125" xadvance="23,5" page="0" chnl="15" />
|
||||
<char id="123" x="749,75" y="139" width="37,375" height="66,375" xoffset="-6,5" yoffset="4,75" xadvance="25,5" page="0" chnl="15" />
|
||||
<char id="124" x="884" y="139" width="20,375" height="66,375" xoffset="0" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="125" x="787,25" y="139" width="37,375" height="66,375" xoffset="-5,5" yoffset="4,75" xadvance="25,5" page="0" chnl="15" />
|
||||
<char id="126" x="392,125" y="724,5" width="47,5" height="29,75" xoffset="-4,5" yoffset="21" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="160" x="1003,5" y="501" width="16,125" height="16,125" xoffset="-8" yoffset="45" xadvance="16,625" page="0" chnl="15" />
|
||||
<char id="161" x="689" y="619,5" width="21,75" height="54,5" xoffset="-2,125" yoffset="6,5" xadvance="17,625" page="0" chnl="15" />
|
||||
<char id="162" x="592,125" y="271,625" width="38,25" height="63,5" xoffset="-5" yoffset="6,875" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="163" x="540,875" y="509,625" width="40,375" height="55,25" xoffset="-5,75" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="164" x="810,25" y="668,25" width="41,625" height="41,75" xoffset="-6,25" yoffset="15,125" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="165" x="258,75" y="624,75" width="41,875" height="54,5" xoffset="-6,625" yoffset="6,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="166" x="904,5" y="139" width="20,375" height="66,375" xoffset="0" yoffset="4,75" xadvance="20,25" page="0" chnl="15" />
|
||||
<char id="167" x="701,875" y="206" width="38,75" height="65,25" xoffset="-4,875" yoffset="5,75" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="168" x="566,875" y="719,5" width="31,875" height="21" xoffset="-1,5" yoffset="6,25" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="169" x="766,25" y="271,375" width="60,75" height="60,75" xoffset="-5,75" yoffset="5,75" xadvance="49,25" page="0" chnl="15" />
|
||||
<char id="170" x="970,875" y="660,875" width="35,625" height="41,25" xoffset="-5" yoffset="5,75" xadvance="26,125" page="0" chnl="15" />
|
||||
<char id="171" x="852" y="665" width="40,375" height="41,375" xoffset="-5,375" yoffset="15,375" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="172" x="220,75" y="726,5" width="46,125" height="34,25" xoffset="-3,875" yoffset="25,25" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="173" x="629,625" y="719,25" width="30,625" height="20,625" xoffset="-5,625" yoffset="25,75" xadvance="19,25" page="0" chnl="15" />
|
||||
<char id="174" x="827,125" y="270,75" width="60,75" height="60,75" xoffset="-5,75" yoffset="5,75" xadvance="49,25" page="0" chnl="15" />
|
||||
<char id="175" x="660,375" y="719,25" width="45,75" height="19,375" xoffset="-8,375" yoffset="-1,25" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="176" x="184,875" y="726,5" width="35,75" height="35,625" xoffset="-5,375" yoffset="5,75" xadvance="25" page="0" chnl="15" />
|
||||
<char id="177" x="865,875" y="614,75" width="46,5" height="48,25" xoffset="-4" yoffset="8,625" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="178" x="33" y="727,5" width="33,625" height="40,625" xoffset="-3,25" yoffset="5,75" xadvance="26,125" page="0" chnl="15" />
|
||||
<char id="179" x="0" y="727,5" width="32,875" height="41,25" xoffset="-3,25" yoffset="5,75" xadvance="26,125" page="0" chnl="15" />
|
||||
<char id="180" x="468,375" y="723,25" width="26,875" height="25,625" xoffset="3,625" yoffset="1,625" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="181" x="156" y="515,25" width="39,125" height="55,5" xoffset="-4,5" yoffset="16,125" xadvance="30,125" page="0" chnl="15" />
|
||||
<char id="182" x="519,125" y="272" width="39,875" height="63,875" xoffset="-6,5" yoffset="6,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="183" x="544,625" y="719,5" width="22,125" height="23,375" xoffset="-1,75" yoffset="16,125" xadvance="18,75" page="0" chnl="15" />
|
||||
<char id="184" x="439,75" y="723,25" width="28,5" height="27,375" xoffset="-0,5" yoffset="44,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="185" x="106,25" y="727,125" width="30,75" height="39,875" xoffset="-1,625" yoffset="6,5" xadvance="26,125" page="0" chnl="15" />
|
||||
<char id="186" x="933" y="660,875" width="37,75" height="41,25" xoffset="-5,75" yoffset="5,75" xadvance="26,125" page="0" chnl="15" />
|
||||
<char id="187" x="892,5" y="663,125" width="40,375" height="41,375" xoffset="-4,625" yoffset="15,375" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="188" x="287,75" y="569,5" width="59,25" height="54,5" xoffset="-3,5" yoffset="6,5" xadvance="53" page="0" chnl="15" />
|
||||
<char id="189" x="225,75" y="570,125" width="61,875" height="54,5" xoffset="-3,5" yoffset="6,5" xadvance="53" page="0" chnl="15" />
|
||||
<char id="190" x="393,375" y="512,875" width="61,625" height="55,25" xoffset="-4,375" yoffset="5,75" xadvance="53" page="0" chnl="15" />
|
||||
<char id="191" x="738,25" y="506,375" width="36,75" height="55,25" xoffset="-6,5" yoffset="6,5" xadvance="25,125" page="0" chnl="15" />
|
||||
<char id="192" x="62,625" y="70,25" width="48,25" height="69" xoffset="-8,25" yoffset="-8" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="193" x="111" y="70,25" width="48,25" height="69" xoffset="-8,25" yoffset="-8" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="194" x="141,25" y="139,375" width="48,25" height="68,5" xoffset="-8,25" yoffset="-7,5" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="195" x="597,5" y="139" width="48,25" height="66,875" xoffset="-8,25" yoffset="-5,875" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="196" x="430,5" y="272,5" width="48,25" height="63,875" xoffset="-8,25" yoffset="-2,875" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="197" x="403,875" y="139" width="48,25" height="67,5" xoffset="-8,25" yoffset="-6,5" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="198" x="99,375" y="571,25" width="63,625" height="54,5" xoffset="-9" yoffset="6,5" xadvance="48,375" page="0" chnl="15" />
|
||||
<char id="199" x="972,25" y="138,875" width="45,25" height="66,125" xoffset="-6,25" yoffset="5,75" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="200" x="778,25" y="69,875" width="40,125" height="69" xoffset="-4,125" yoffset="-8" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="201" x="738" y="69,875" width="40,125" height="69" xoffset="-4,125" yoffset="-8" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="202" x="657,5" y="69,875" width="40,125" height="69" xoffset="-4,125" yoffset="-8" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="203" x="245,75" y="273,25" width="40,125" height="64,375" xoffset="-4,125" yoffset="-3,375" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="204" x="960,5" y="69,75" width="30,875" height="69" xoffset="-5,5" yoffset="-8" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="205" x="929,5" y="69,75" width="30,875" height="69" xoffset="-5,5" yoffset="-8" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="206" x="895,75" y="69,875" width="33,625" height="69" xoffset="-6,75" yoffset="-8" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="207" x="286" y="272,75" width="31,875" height="64,375" xoffset="-6" yoffset="-3,375" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="208" x="399,875" y="568,25" width="50,625" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="37" page="0" chnl="15" />
|
||||
<char id="209" x="487,75" y="139" width="43,625" height="67,375" xoffset="-4,125" yoffset="-6,375" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="210" x="298,875" y="0" width="50" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="211" x="248,75" y="0" width="50" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="212" x="198,625" y="0" width="50" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="213" x="233,5" y="139" width="50" height="68,125" xoffset="-6,25" yoffset="-6,375" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="214" x="771,75" y="205,5" width="50" height="65,125" xoffset="-6,25" yoffset="-3,375" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="215" x="766,25" y="670,25" width="43,875" height="43,875" xoffset="-2,625" yoffset="14,25" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="216" x="705,125" y="332,875" width="50" height="59,875" xoffset="-6,25" yoffset="4,125" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="217" x="670,25" y="0" width="43,75" height="69,75" xoffset="-4,5" yoffset="-8" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="218" x="626,375" y="0" width="43,75" height="69,75" xoffset="-4,5" yoffset="-8" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="219" x="758" y="0" width="43,75" height="69,75" xoffset="-4,5" yoffset="-8" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="220" x="914,5" y="205,5" width="43,75" height="65,125" xoffset="-4,5" yoffset="-3,375" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="221" x="206,625" y="69,875" width="47,125" height="69" xoffset="-8,25" yoffset="-8" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="222" x="300,75" y="624,125" width="40,5" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="30" page="0" chnl="15" />
|
||||
<char id="223" x="512,375" y="396,25" width="40,125" height="57,125" xoffset="-4,5" yoffset="4,5" xadvance="29" page="0" chnl="15" />
|
||||
<char id="224" x="120,875" y="338,625" width="39" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="225" x="81,75" y="339,375" width="39" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="226" x="160" y="338,625" width="39" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="227" x="292,125" y="398" width="39" height="59" xoffset="-6,5" yoffset="2,75" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="228" x="195,25" y="514,5" width="39" height="55,5" xoffset="-6,5" yoffset="6,25" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="229" x="630,5" y="271,375" width="39" height="61,5" xoffset="-6,5" yoffset="0,25" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="230" x="0" y="681" width="59,625" height="46,375" xoffset="-6,5" yoffset="15,375" xadvance="46,625" page="0" chnl="15" />
|
||||
<char id="231" x="890,75" y="391,125" width="38,125" height="56,5" xoffset="-6,5" yoffset="15,375" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="232" x="397,375" y="336,625" width="40,875" height="60" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="233" x="438,375" y="336,5" width="40,875" height="60" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="234" x="315,375" y="337,25" width="40,875" height="60" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="235" x="314,125" y="513,875" width="40,875" height="55,375" xoffset="-6,5" yoffset="6,25" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="236" x="62,5" y="399,625" width="26,875" height="59,375" xoffset="-8,125" yoffset="1,625" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="237" x="995" y="330,25" width="26,875" height="59,375" xoffset="-4,75" yoffset="1,625" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="238" x="31,5" y="399,625" width="30,875" height="59,375" xoffset="-9,375" yoffset="1,625" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="239" x="973,375" y="503,25" width="30" height="54,75" xoffset="-9" yoffset="6,25" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="240" x="439,375" y="396,625" width="41,75" height="57,25" xoffset="-6,5" yoffset="4,5" xadvance="28,875" page="0" chnl="15" />
|
||||
<char id="241" x="370" y="396,875" width="38,625" height="58,25" xoffset="-4,5" yoffset="2,75" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="242" x="971,75" y="270" width="41,75" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="243" x="929,875" y="270,75" width="41,75" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="244" x="888" y="270,75" width="41,75" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="245" x="209,25" y="398,5" width="41,75" height="59" xoffset="-6,5" yoffset="2,75" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="246" x="114,125" y="515,25" width="41,75" height="55,5" xoffset="-6,5" yoffset="6,25" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="247" x="819,375" y="616" width="46,375" height="48,875" xoffset="-3,875" yoffset="11,625" xadvance="38,5" page="0" chnl="15" />
|
||||
<char id="248" x="777,125" y="616,375" width="42,125" height="51,75" xoffset="-6,875" yoffset="13" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="249" x="276,625" y="337,75" width="38,625" height="60,125" xoffset="-4,625" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="250" x="237,875" y="338,125" width="38,625" height="60,125" xoffset="-4,625" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="251" x="199,125" y="338,25" width="38,625" height="60,125" xoffset="-4,625" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="252" x="234,375" y="514,5" width="38,625" height="55,5" xoffset="-4,625" yoffset="6,25" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="253" x="114,125" y="0" width="42,125" height="70" xoffset="-7,875" yoffset="1,625" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="254" x="645,875" y="139" width="40,25" height="66,875" xoffset="-4,5" yoffset="4,75" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="255" x="488,375" y="206,5" width="42,125" height="65,375" xoffset="-7,875" yoffset="6,25" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="256" x="382,125" y="272,625" width="48,25" height="63,875" xoffset="-8,25" yoffset="-2,875" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="257" x="621,25" y="509,5" width="39" height="55,25" xoffset="-6,5" yoffset="6,5" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="258" x="283,625" y="139" width="48,25" height="68" xoffset="-8,25" yoffset="-7" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="259" x="131,375" y="398,875" width="39" height="59,125" xoffset="-6,5" yoffset="2,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="260" x="569,125" y="206,25" width="48,5" height="65,25" xoffset="-8,25" yoffset="6,5" xadvance="31,75" page="0" chnl="15" />
|
||||
<char id="261" x="71,875" y="459,125" width="39,625" height="56,375" xoffset="-6,5" yoffset="15,375" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="262" x="446,375" y="0" width="45,25" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="263" x="479,375" y="336,125" width="38,125" height="60" xoffset="-6,5" yoffset="1,625" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="264" x="491,75" y="0" width="45,25" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="265" x="517,625" y="336,125" width="38,125" height="60" xoffset="-6,5" yoffset="1,625" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="266" x="869,125" y="205,5" width="45,25" height="65,125" xoffset="-6,25" yoffset="-3,375" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="267" x="355,125" y="513,5" width="38,125" height="55,375" xoffset="-6,5" yoffset="6,25" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="268" x="537,125" y="0" width="45,25" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="31,875" page="0" chnl="15" />
|
||||
<char id="269" x="555,875" y="336" width="38,125" height="60" xoffset="-6,5" yoffset="1,625" xadvance="24,5" page="0" chnl="15" />
|
||||
<char id="270" x="301,125" y="69,875" width="46,375" height="69" xoffset="-4,125" yoffset="-8" xadvance="36" page="0" chnl="15" />
|
||||
<char id="271" x="552,625" y="396,25" width="52,625" height="57" xoffset="-6,5" yoffset="4,75" xadvance="36,375" page="0" chnl="15" />
|
||||
<char id="272" x="450,625" y="568,25" width="50,625" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="37" page="0" chnl="15" />
|
||||
<char id="273" x="605,375" y="395,375" width="44,5" height="57" xoffset="-6,5" yoffset="4,75" xadvance="30,375" page="0" chnl="15" />
|
||||
<char id="274" x="478,875" y="272,125" width="40,125" height="63,875" xoffset="-4,125" yoffset="-2,875" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="275" x="860,75" y="504,5" width="40,875" height="55,125" xoffset="-6,5" yoffset="6,5" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="276" x="332" y="139" width="40,125" height="68" xoffset="-4,125" yoffset="-7" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="277" x="251,125" y="398,375" width="40,875" height="59" xoffset="-6,5" yoffset="2,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="278" x="205,5" y="273,625" width="40,125" height="64,375" xoffset="-4,125" yoffset="-3,375" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="279" x="273,125" y="514" width="40,875" height="55,375" xoffset="-6,5" yoffset="6,25" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="280" x="661,625" y="206" width="40,125" height="65,25" xoffset="-4,125" yoffset="6,5" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="281" x="30,875" y="459,125" width="40,875" height="56,375" xoffset="-6,5" yoffset="15,375" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="282" x="697,75" y="69,875" width="40,125" height="69" xoffset="-4,125" yoffset="-8" xadvance="29,75" page="0" chnl="15" />
|
||||
<char id="283" x="356,375" y="336,75" width="40,875" height="60" xoffset="-6,5" yoffset="1,625" xadvance="27,875" page="0" chnl="15" />
|
||||
<char id="284" x="399,125" y="0" width="47,125" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="285" x="0" y="0" width="40,25" height="70,25" xoffset="-6,5" yoffset="1,625" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="286" x="50,125" y="139,5" width="47,125" height="68,75" xoffset="-6,25" yoffset="-7" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="287" x="965,25" y="0" width="40,25" height="69,25" xoffset="-6,5" yoffset="2,625" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="288" x="821,875" y="205,5" width="47,125" height="65,125" xoffset="-6,25" yoffset="-3,375" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="289" x="82,125" y="208,375" width="40,25" height="65,625" xoffset="-6,5" yoffset="6,25" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="290" x="925" y="139" width="47,125" height="66,125" xoffset="-6,25" yoffset="5,75" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="291" x="40,375" y="0" width="40,25" height="70,125" xoffset="-6,5" yoffset="1,75" xadvance="29,25" page="0" chnl="15" />
|
||||
<char id="292" x="439,625" y="69,875" width="44" height="69" xoffset="-4,125" yoffset="-8" xadvance="35,75" page="0" chnl="15" />
|
||||
<char id="293" x="818,5" y="69,875" width="38,625" height="69" xoffset="-4,5" yoffset="-8" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="294" x="347,125" y="569,375" width="52,625" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="37,875" page="0" chnl="15" />
|
||||
<char id="295" x="160,25" y="458,125" width="42,875" height="56,25" xoffset="-7,625" yoffset="4,75" xadvance="30,625" page="0" chnl="15" />
|
||||
<char id="296" x="452,25" y="139" width="35,375" height="67,5" xoffset="-7,75" yoffset="-6,5" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="297" x="481,25" y="396,25" width="31" height="57,25" xoffset="-9,375" yoffset="3,75" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="298" x="559,125" y="272" width="32,875" height="63,875" xoffset="-6,5" yoffset="-2,875" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="299" x="610" y="619,625" width="29,875" height="54,5" xoffset="-8,875" yoffset="6,5" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="300" x="372,25" y="139" width="31,5" height="67,875" xoffset="-5,75" yoffset="-6,875" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="301" x="408,75" y="396,75" width="30,5" height="57,75" xoffset="-9,25" yoffset="3,25" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="302" x="740,75" y="206" width="30,875" height="65,25" xoffset="-5,5" yoffset="6,5" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="303" x="189" y="208" width="24" height="65,5" xoffset="-6,75" yoffset="6,25" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="304" x="318" y="272,625" width="30,875" height="64,375" xoffset="-5,5" yoffset="-3,375" xadvance="19,75" page="0" chnl="15" />
|
||||
<char id="305" x="745,25" y="670,25" width="20,875" height="44,875" xoffset="-4,375" yoffset="16,125" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="306" x="812" y="504,875" width="48,625" height="55,125" xoffset="-5,5" yoffset="6,5" xadvance="38,75" page="0" chnl="15" />
|
||||
<char id="307" x="122,5" y="208,25" width="36,5" height="65,625" xoffset="-4,625" yoffset="6,25" xadvance="27,375" page="0" chnl="15" />
|
||||
<char id="308" x="928,625" y="0" width="36,5" height="69,625" xoffset="-7,75" yoffset="-8" xadvance="22,125" page="0" chnl="15" />
|
||||
<char id="309" x="80,75" y="0" width="33,25" height="70,125" xoffset="-10,375" yoffset="1,75" xadvance="14,875" page="0" chnl="15" />
|
||||
<char id="310" x="356,625" y="207,125" width="44,125" height="65,375" xoffset="-4,125" yoffset="6,5" xadvance="31,125" page="0" chnl="15" />
|
||||
<char id="311" x="531,5" y="139" width="40" height="67,125" xoffset="-4,5" yoffset="4,75" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="312" x="614,125" y="674,25" width="40" height="44,875" xoffset="-4,5" yoffset="16,125" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="313" x="857,25" y="69,875" width="38,375" height="69" xoffset="-4,125" yoffset="-8" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="314" x="991,5" y="69,375" width="26,875" height="69" xoffset="-4,875" yoffset="-8" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="315" x="530,625" y="206,5" width="38,375" height="65,375" xoffset="-4,125" yoffset="6,5" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="316" x="571,625" y="139" width="25,75" height="67,125" xoffset="-6,125" yoffset="4,75" xadvance="12,125" page="0" chnl="15" />
|
||||
<char id="317" x="362,875" y="456,5" width="38,375" height="56,25" xoffset="-4,125" yoffset="4,75" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="318" x="434,75" y="454,625" width="33,25" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="19,125" page="0" chnl="15" />
|
||||
<char id="319" x="502" y="619,875" width="38,375" height="54,5" xoffset="-4,125" yoffset="6,5" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="320" x="401,375" y="455,25" width="33,25" height="56,25" xoffset="-4,5" yoffset="4,75" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="321" x="173,75" y="625,5" width="42,625" height="54,5" xoffset="-7,375" yoffset="6,5" xadvance="27,375" page="0" chnl="15" />
|
||||
<char id="322" x="468,125" y="454" width="29,375" height="56,25" xoffset="-7,375" yoffset="4,75" xadvance="14,5" page="0" chnl="15" />
|
||||
<char id="323" x="527,5" y="69,875" width="43,625" height="69" xoffset="-4,125" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="324" x="848" y="331,625" width="38,625" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="325" x="400,875" y="207" width="43,625" height="65,375" xoffset="-4,125" yoffset="6,5" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="326" x="813,25" y="391,75" width="38,625" height="56,5" xoffset="-4,5" yoffset="15,375" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="327" x="483,75" y="69,875" width="43,625" height="69" xoffset="-4,125" yoffset="-8" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="328" x="809,25" y="332,25" width="38,625" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="329" x="111,625" y="458,875" width="48,5" height="56,25" xoffset="-7,125" yoffset="4,75" xadvance="36,75" page="0" chnl="15" />
|
||||
<char id="330" x="444,625" y="206,625" width="43,625" height="65,375" xoffset="-4,125" yoffset="6,5" xadvance="35,375" page="0" chnl="15" />
|
||||
<char id="331" x="852" y="391,125" width="38,625" height="56,5" xoffset="-4,5" yoffset="15,375" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="332" x="958,375" y="205,25" width="50" height="64,625" xoffset="-6,25" yoffset="-2,875" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="333" x="499" y="509,875" width="41,75" height="55,25" xoffset="-6,5" yoffset="6,5" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="334" x="0" y="139,5" width="50" height="68,75" xoffset="-6,25" yoffset="-7" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="335" x="89,5" y="399,625" width="41,75" height="59,125" xoffset="-6,5" yoffset="2,625" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="336" x="349" y="0" width="50" height="69,75" xoffset="-6,25" yoffset="-8" xadvance="37,5" page="0" chnl="15" />
|
||||
<char id="337" x="0" y="339,375" width="41,75" height="60,125" xoffset="-6,5" yoffset="1,625" xadvance="28,75" page="0" chnl="15" />
|
||||
<char id="338" x="35" y="571,375" width="64,25" height="54,5" xoffset="-6,25" yoffset="6,5" xadvance="51,75" page="0" chnl="15" />
|
||||
<char id="339" x="912,5" y="614,375" width="61,125" height="46,375" xoffset="-6,5" yoffset="15,375" xadvance="48,125" page="0" chnl="15" />
|
||||
<char id="340" x="393,625" y="69,875" width="45,875" height="69" xoffset="-4,125" yoffset="-8" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="341" x="0" y="399,625" width="31,375" height="59,375" xoffset="-4,5" yoffset="1,625" xadvance="19,125" page="0" chnl="15" />
|
||||
<char id="342" x="310,625" y="207,125" width="45,875" height="65,375" xoffset="-4,125" yoffset="6,5" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="343" x="0" y="515,75" width="32,25" height="55,75" xoffset="-5,375" yoffset="16,125" xadvance="19,125" page="0" chnl="15" />
|
||||
<char id="344" x="347,625" y="69,875" width="45,875" height="69" xoffset="-4,125" yoffset="-8" xadvance="32,875" page="0" chnl="15" />
|
||||
<char id="345" x="961,25" y="331" width="33,625" height="59,375" xoffset="-6,5" yoffset="1,625" xadvance="19,125" page="0" chnl="15" />
|
||||
<char id="346" x="801,875" y="0" width="42,125" height="69,75" xoffset="-6" yoffset="-8" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="347" x="594,125" y="335,25" width="36,875" height="60" xoffset="-6,25" yoffset="1,625" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="348" x="886,375" y="0" width="42,125" height="69,75" xoffset="-6" yoffset="-8" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="349" x="631,125" y="333" width="36,875" height="60" xoffset="-6,25" yoffset="1,625" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="350" x="0" y="208,375" width="42,125" height="66,125" xoffset="-6" yoffset="5,75" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="351" x="929" y="390,5" width="36,875" height="56,5" xoffset="-6,25" yoffset="15,375" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="352" x="844,125" y="0" width="42,125" height="69,75" xoffset="-6" yoffset="-8" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="353" x="668,125" y="333" width="36,875" height="60" xoffset="-6,25" yoffset="1,625" xadvance="23,625" page="0" chnl="15" />
|
||||
<char id="354" x="263,375" y="207,25" width="47,125" height="65,375" xoffset="-8,125" yoffset="6,5" xadvance="31" page="0" chnl="15" />
|
||||
<char id="355" x="349" y="272,625" width="33" height="64" xoffset="-7,375" yoffset="7,875" xadvance="17,75" page="0" chnl="15" />
|
||||
<char id="356" x="253,875" y="69,875" width="47,125" height="69" xoffset="-8,125" yoffset="-8" xadvance="31" page="0" chnl="15" />
|
||||
<char id="357" x="730,75" y="392,875" width="42" height="56,875" xoffset="-7,375" yoffset="4,75" xadvance="24,875" page="0" chnl="15" />
|
||||
<char id="358" x="694,625" y="561,75" width="47,125" height="54,5" xoffset="-8,125" yoffset="6,5" xadvance="31" page="0" chnl="15" />
|
||||
<char id="359" x="744" y="616,375" width="33" height="53,75" xoffset="-7,125" yoffset="7,875" xadvance="18" page="0" chnl="15" />
|
||||
<char id="360" x="189,625" y="139,25" width="43,75" height="68,375" xoffset="-4,5" yoffset="-6,625" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="361" x="331,25" y="397,375" width="38,625" height="59" xoffset="-4,625" yoffset="2,75" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="362" x="0" y="274,625" width="43,75" height="64,625" xoffset="-4,5" yoffset="-2,875" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="363" x="699,5" y="506,375" width="38,625" height="55,25" xoffset="-4,625" yoffset="6,5" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="364" x="97,375" y="139,375" width="43,75" height="68,75" xoffset="-4,5" yoffset="-7" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="365" x="170,5" y="398,875" width="38,625" height="59,125" xoffset="-4,625" yoffset="2,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="366" x="582,5" y="0" width="43,75" height="69,75" xoffset="-4,5" yoffset="-8" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="367" x="669,625" y="271,375" width="38,625" height="61,375" xoffset="-4,625" yoffset="0,375" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="368" x="714,125" y="0" width="43,75" height="69,75" xoffset="-4,5" yoffset="-8" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="369" x="41,875" y="339,375" width="39,75" height="60,125" xoffset="-4,625" yoffset="1,625" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="370" x="617,75" y="206" width="43,75" height="65,25" xoffset="-4,5" yoffset="6,5" xadvance="34,75" page="0" chnl="15" />
|
||||
<char id="371" x="32,375" y="515,625" width="39,375" height="55,625" xoffset="-4,625" yoffset="16,125" xadvance="29,5" page="0" chnl="15" />
|
||||
<char id="372" x="0" y="70,375" width="62,5" height="69" xoffset="-7,375" yoffset="-8" xadvance="47,75" page="0" chnl="15" />
|
||||
<char id="373" x="755,25" y="332,625" width="53,875" height="59,375" xoffset="-7,25" yoffset="1,625" xadvance="39,375" page="0" chnl="15" />
|
||||
<char id="374" x="159,375" y="70,125" width="47,125" height="69" xoffset="-8,25" yoffset="-8" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="375" x="156,375" y="0" width="42,125" height="70" xoffset="-7,875" yoffset="1,625" xadvance="26,375" page="0" chnl="15" />
|
||||
<char id="376" x="115,125" y="274,125" width="47,125" height="64,375" xoffset="-8,25" yoffset="-3,375" xadvance="30,5" page="0" chnl="15" />
|
||||
<char id="377" x="571,25" y="69,875" width="43" height="69" xoffset="-6,5" yoffset="-8" xadvance="29,625" page="0" chnl="15" />
|
||||
<char id="378" x="924" y="331" width="37,125" height="59,375" xoffset="-6,75" yoffset="1,625" xadvance="23,5" page="0" chnl="15" />
|
||||
<char id="379" x="162,375" y="273,75" width="43" height="64,375" xoffset="-6,5" yoffset="-3,375" xadvance="29,625" page="0" chnl="15" />
|
||||
<char id="380" x="936,125" y="503,875" width="37,125" height="54,75" xoffset="-6,75" yoffset="6,25" xadvance="23,5" page="0" chnl="15" />
|
||||
<char id="381" x="614,375" y="69,875" width="43" height="69" xoffset="-6,5" yoffset="-8" xadvance="29,625" page="0" chnl="15" />
|
||||
<char id="382" x="886,75" y="331,625" width="37,125" height="59,375" xoffset="-6,75" yoffset="1,625" xadvance="23,5" page="0" chnl="15" />
|
||||
<char id="383" x="0" y="459,125" width="30,75" height="56,5" xoffset="-4,375" yoffset="4,5" xadvance="13,5" page="0" chnl="15" />
|
||||
</chars>
|
||||
<kernings count="465">
|
||||
<kerning first="191" second="74" amount="0,75" />
|
||||
<kerning first="248" second="121" amount="-0,25" />
|
||||
<kerning first="39" second="65" amount="-2,375" />
|
||||
<kerning first="39" second="198" amount="-2,375" />
|
||||
<kerning first="40" second="84" amount="0,5" />
|
||||
<kerning first="40" second="106" amount="1,25" />
|
||||
<kerning first="44" second="41" amount="-2,375" />
|
||||
<kerning first="44" second="55" amount="-1,25" />
|
||||
<kerning first="44" second="93" amount="-2,375" />
|
||||
<kerning first="44" second="125" amount="-2,375" />
|
||||
<kerning first="248" second="120" amount="-0,5" />
|
||||
<kerning first="248" second="118" amount="-0,25" />
|
||||
<kerning first="45" second="65" amount="-1,25" />
|
||||
<kerning first="45" second="73" amount="-0,75" />
|
||||
<kerning first="45" second="74" amount="-2,375" />
|
||||
<kerning first="45" second="83" amount="-0,5" />
|
||||
<kerning first="45" second="84" amount="-3,75" />
|
||||
<kerning first="45" second="86" amount="-1,25" />
|
||||
<kerning first="45" second="87" amount="-1,25" />
|
||||
<kerning first="45" second="88" amount="-2" />
|
||||
<kerning first="45" second="89" amount="-3,375" />
|
||||
<kerning first="45" second="90" amount="-0,75" />
|
||||
<kerning first="45" second="97" amount="-0,5" />
|
||||
<kerning first="45" second="118" amount="-1" />
|
||||
<kerning first="45" second="119" amount="-0,5" />
|
||||
<kerning first="45" second="120" amount="-1,25" />
|
||||
<kerning first="45" second="121" amount="-1" />
|
||||
<kerning first="45" second="122" amount="-1" />
|
||||
<kerning first="45" second="198" amount="-1,25" />
|
||||
<kerning first="45" second="230" amount="-0,5" />
|
||||
<kerning first="46" second="41" amount="-2,625" />
|
||||
<kerning first="46" second="44" amount="-3,5" />
|
||||
<kerning first="46" second="45" amount="-4,25" />
|
||||
<kerning first="46" second="55" amount="-1,25" />
|
||||
<kerning first="46" second="93" amount="-2,625" />
|
||||
<kerning first="46" second="125" amount="-2,625" />
|
||||
<kerning first="248" second="46" amount="-0,5" />
|
||||
<kerning first="248" second="44" amount="-0,75" />
|
||||
<kerning first="216" second="90" amount="-0,5" />
|
||||
<kerning first="216" second="89" amount="-0,5" />
|
||||
<kerning first="52" second="44" amount="-0,5" />
|
||||
<kerning first="52" second="46" amount="-0,5" />
|
||||
<kerning first="55" second="44" amount="-3,875" />
|
||||
<kerning first="55" second="46" amount="-3,875" />
|
||||
<kerning first="216" second="88" amount="-0,25" />
|
||||
<kerning first="65" second="45" amount="-1,25" />
|
||||
<kerning first="65" second="83" amount="-0,125" />
|
||||
<kerning first="65" second="84" amount="-3" />
|
||||
<kerning first="65" second="85" amount="-0,25" />
|
||||
<kerning first="65" second="86" amount="-1,375" />
|
||||
<kerning first="65" second="87" amount="-1,25" />
|
||||
<kerning first="65" second="89" amount="-2" />
|
||||
<kerning first="65" second="116" amount="-0,375" />
|
||||
<kerning first="65" second="117" amount="-0,25" />
|
||||
<kerning first="65" second="118" amount="-0,75" />
|
||||
<kerning first="65" second="119" amount="-0,25" />
|
||||
<kerning first="65" second="121" amount="-0,75" />
|
||||
<kerning first="216" second="84" amount="-1,25" />
|
||||
<kerning first="216" second="46" amount="-0,75" />
|
||||
<kerning first="216" second="44" amount="-0,75" />
|
||||
<kerning first="239" second="108" amount="0,25" />
|
||||
<kerning first="239" second="102" amount="0,375" />
|
||||
<kerning first="238" second="108" amount="0,25" />
|
||||
<kerning first="66" second="44" amount="-0,5" />
|
||||
<kerning first="66" second="45" amount="0,25" />
|
||||
<kerning first="66" second="46" amount="-0,5" />
|
||||
<kerning first="66" second="67" amount="0,25" />
|
||||
<kerning first="66" second="71" amount="0,25" />
|
||||
<kerning first="66" second="79" amount="0,25" />
|
||||
<kerning first="66" second="81" amount="0,25" />
|
||||
<kerning first="66" second="84" amount="-1,375" />
|
||||
<kerning first="66" second="97" amount="0,25" />
|
||||
<kerning first="66" second="101" amount="0,25" />
|
||||
<kerning first="66" second="104" amount="0,25" />
|
||||
<kerning first="66" second="105" amount="0,25" />
|
||||
<kerning first="66" second="106" amount="0,25" />
|
||||
<kerning first="66" second="108" amount="0,25" />
|
||||
<kerning first="66" second="111" amount="0,25" />
|
||||
<kerning first="66" second="114" amount="0,25" />
|
||||
<kerning first="66" second="117" amount="0,25" />
|
||||
<kerning first="66" second="119" amount="0,25" />
|
||||
<kerning first="231" second="45" amount="-0,5" />
|
||||
<kerning first="199" second="338" amount="-0,625" />
|
||||
<kerning first="199" second="45" amount="-1,25" />
|
||||
<kerning first="123" second="106" amount="1,25" />
|
||||
<kerning first="67" second="45" amount="-1,25" />
|
||||
<kerning first="67" second="338" amount="-0,625" />
|
||||
<kerning first="123" second="84" amount="0,5" />
|
||||
<kerning first="122" second="248" amount="-0,25" />
|
||||
<kerning first="68" second="44" amount="-1,25" />
|
||||
<kerning first="68" second="46" amount="-1,25" />
|
||||
<kerning first="68" second="74" amount="-0,5" />
|
||||
<kerning first="68" second="84" amount="-1,25" />
|
||||
<kerning first="68" second="87" amount="-0,5" />
|
||||
<kerning first="68" second="88" amount="-0,25" />
|
||||
<kerning first="68" second="89" amount="-0,5" />
|
||||
<kerning first="68" second="90" amount="-0,5" />
|
||||
<kerning first="122" second="231" amount="-0,25" />
|
||||
<kerning first="70" second="44" amount="-7,375" />
|
||||
<kerning first="70" second="46" amount="-7,375" />
|
||||
<kerning first="70" second="58" amount="-1,375" />
|
||||
<kerning first="122" second="113" amount="-0,25" />
|
||||
<kerning first="70" second="63" amount="1,375" />
|
||||
<kerning first="70" second="65" amount="-2,375" />
|
||||
<kerning first="70" second="74" amount="-1,5" />
|
||||
<kerning first="70" second="84" amount="0,75" />
|
||||
<kerning first="70" second="97" amount="-2,375" />
|
||||
<kerning first="70" second="101" amount="-1,25" />
|
||||
<kerning first="70" second="111" amount="-1,25" />
|
||||
<kerning first="70" second="198" amount="-2,75" />
|
||||
<kerning first="70" second="230" amount="-2,375" />
|
||||
<kerning first="70" second="248" amount="-1,25" />
|
||||
<kerning first="122" second="111" amount="-0,25" />
|
||||
<kerning first="70" second="339" amount="-1,25" />
|
||||
<kerning first="73" second="45" amount="-0,75" />
|
||||
<kerning first="73" second="97" amount="-0,5" />
|
||||
<kerning first="73" second="99" amount="-0,625" />
|
||||
<kerning first="73" second="100" amount="-0,5" />
|
||||
<kerning first="73" second="101" amount="-0,625" />
|
||||
<kerning first="73" second="103" amount="-0,5" />
|
||||
<kerning first="73" second="109" amount="-0,25" />
|
||||
<kerning first="73" second="110" amount="-0,25" />
|
||||
<kerning first="73" second="111" amount="-0,625" />
|
||||
<kerning first="73" second="112" amount="-0,25" />
|
||||
<kerning first="73" second="114" amount="-0,25" />
|
||||
<kerning first="73" second="115" amount="-0,5" />
|
||||
<kerning first="73" second="118" amount="-0,75" />
|
||||
<kerning first="122" second="103" amount="-0,25" />
|
||||
<kerning first="122" second="101" amount="-0,25" />
|
||||
<kerning first="74" second="44" amount="-0,5" />
|
||||
<kerning first="74" second="46" amount="-0,5" />
|
||||
<kerning first="74" second="65" amount="-0,25" />
|
||||
<kerning first="74" second="198" amount="-0,25" />
|
||||
<kerning first="122" second="100" amount="-0,25" />
|
||||
<kerning first="75" second="45" amount="-2,75" />
|
||||
<kerning first="75" second="79" amount="-0,5" />
|
||||
<kerning first="75" second="97" amount="-1,125" />
|
||||
<kerning first="75" second="101" amount="-1,5" />
|
||||
<kerning first="75" second="111" amount="-1,5" />
|
||||
<kerning first="75" second="117" amount="-1" />
|
||||
<kerning first="75" second="118" amount="-1,375" />
|
||||
<kerning first="75" second="119" amount="-1,5" />
|
||||
<kerning first="75" second="121" amount="-1,375" />
|
||||
<kerning first="75" second="216" amount="-0,5" />
|
||||
<kerning first="75" second="230" amount="-1,375" />
|
||||
<kerning first="75" second="248" amount="-1,75" />
|
||||
<kerning first="75" second="338" amount="-0,5" />
|
||||
<kerning first="75" second="339" amount="-1,75" />
|
||||
<kerning first="122" second="99" amount="-0,25" />
|
||||
<kerning first="122" second="45" amount="-0,5" />
|
||||
<kerning first="76" second="39" amount="-3" />
|
||||
<kerning first="76" second="45" amount="-3,875" />
|
||||
<kerning first="76" second="65" amount="-1" />
|
||||
<kerning first="76" second="67" amount="-0,5" />
|
||||
<kerning first="76" second="71" amount="-0,5" />
|
||||
<kerning first="76" second="74" amount="2,375" />
|
||||
<kerning first="76" second="79" amount="-0,5" />
|
||||
<kerning first="76" second="81" amount="-0,5" />
|
||||
<kerning first="76" second="84" amount="-4,25" />
|
||||
<kerning first="76" second="86" amount="-2,75" />
|
||||
<kerning first="76" second="87" amount="-2,375" />
|
||||
<kerning first="76" second="89" amount="-3,875" />
|
||||
<kerning first="76" second="118" amount="-2,75" />
|
||||
<kerning first="76" second="121" amount="-2,75" />
|
||||
<kerning first="76" second="199" amount="-0,5" />
|
||||
<kerning first="76" second="198" amount="-1" />
|
||||
<kerning first="76" second="216" amount="-0,5" />
|
||||
<kerning first="76" second="338" amount="-0,5" />
|
||||
<kerning first="121" second="339" amount="-0,25" />
|
||||
<kerning first="121" second="248" amount="-0,375" />
|
||||
<kerning first="121" second="230" amount="-1" />
|
||||
<kerning first="121" second="231" amount="-0,375" />
|
||||
<kerning first="79" second="44" amount="-0,75" />
|
||||
<kerning first="79" second="46" amount="-0,75" />
|
||||
<kerning first="79" second="74" amount="-0,25" />
|
||||
<kerning first="79" second="84" amount="-1,25" />
|
||||
<kerning first="79" second="88" amount="-0,25" />
|
||||
<kerning first="79" second="89" amount="-0,5" />
|
||||
<kerning first="79" second="90" amount="-0,5" />
|
||||
<kerning first="121" second="113" amount="-0,25" />
|
||||
<kerning first="80" second="44" amount="-7,375" />
|
||||
<kerning first="80" second="46" amount="-7,375" />
|
||||
<kerning first="80" second="65" amount="-1,25" />
|
||||
<kerning first="80" second="74" amount="-1,75" />
|
||||
<kerning first="80" second="89" amount="0,5" />
|
||||
<kerning first="80" second="97" amount="-1,25" />
|
||||
<kerning first="80" second="101" amount="-1,25" />
|
||||
<kerning first="80" second="111" amount="-1,25" />
|
||||
<kerning first="80" second="198" amount="-1,75" />
|
||||
<kerning first="80" second="230" amount="-1,25" />
|
||||
<kerning first="80" second="248" amount="-1,25" />
|
||||
<kerning first="121" second="111" amount="-0,375" />
|
||||
<kerning first="80" second="339" amount="-1,25" />
|
||||
<kerning first="81" second="44" amount="-0,75" />
|
||||
<kerning first="81" second="46" amount="-0,75" />
|
||||
<kerning first="121" second="103" amount="-0,25" />
|
||||
<kerning first="82" second="45" amount="-2,375" />
|
||||
<kerning first="82" second="84" amount="-1,375" />
|
||||
<kerning first="82" second="89" amount="-0,5" />
|
||||
<kerning first="82" second="97" amount="-0,5" />
|
||||
<kerning first="82" second="101" amount="-1" />
|
||||
<kerning first="82" second="111" amount="-1" />
|
||||
<kerning first="82" second="117" amount="-0,25" />
|
||||
<kerning first="82" second="121" amount="-1,25" />
|
||||
<kerning first="82" second="230" amount="-1,25" />
|
||||
<kerning first="82" second="248" amount="-1,25" />
|
||||
<kerning first="82" second="339" amount="-1,375" />
|
||||
<kerning first="121" second="101" amount="-0,375" />
|
||||
<kerning first="121" second="100" amount="-0,25" />
|
||||
<kerning first="121" second="99" amount="-0,375" />
|
||||
<kerning first="121" second="97" amount="-1" />
|
||||
<kerning first="83" second="44" amount="-0,5" />
|
||||
<kerning first="83" second="46" amount="-0,5" />
|
||||
<kerning first="83" second="65" amount="-0,375" />
|
||||
<kerning first="83" second="83" amount="-0,625" />
|
||||
<kerning first="83" second="99" amount="0,125" />
|
||||
<kerning first="83" second="101" amount="0,125" />
|
||||
<kerning first="83" second="111" amount="0,125" />
|
||||
<kerning first="83" second="113" amount="0,125" />
|
||||
<kerning first="83" second="118" amount="-0,75" />
|
||||
<kerning first="83" second="119" amount="-0,5" />
|
||||
<kerning first="83" second="121" amount="-0,75" />
|
||||
<kerning first="83" second="198" amount="-0,5" />
|
||||
<kerning first="121" second="46" amount="-4,625" />
|
||||
<kerning first="84" second="41" amount="0,5" />
|
||||
<kerning first="84" second="44" amount="-7,125" />
|
||||
<kerning first="84" second="45" amount="-3,75" />
|
||||
<kerning first="84" second="46" amount="-7,125" />
|
||||
<kerning first="84" second="58" amount="-4,875" />
|
||||
<kerning first="121" second="45" amount="-1" />
|
||||
<kerning first="84" second="63" amount="1,375" />
|
||||
<kerning first="84" second="65" amount="-3" />
|
||||
<kerning first="84" second="67" amount="-1" />
|
||||
<kerning first="84" second="71" amount="-1" />
|
||||
<kerning first="84" second="74" amount="-1,5" />
|
||||
<kerning first="84" second="79" amount="-1,25" />
|
||||
<kerning first="84" second="83" amount="-0,25" />
|
||||
<kerning first="84" second="84" amount="-2,625" />
|
||||
<kerning first="84" second="89" amount="-1,75" />
|
||||
<kerning first="84" second="93" amount="0,5" />
|
||||
<kerning first="84" second="97" amount="-5,875" />
|
||||
<kerning first="84" second="99" amount="-5,375" />
|
||||
<kerning first="84" second="101" amount="-5,375" />
|
||||
<kerning first="84" second="103" amount="-5,25" />
|
||||
<kerning first="84" second="111" amount="-5,375" />
|
||||
<kerning first="84" second="114" amount="-4,875" />
|
||||
<kerning first="84" second="115" amount="-4,375" />
|
||||
<kerning first="84" second="117" amount="-4,875" />
|
||||
<kerning first="84" second="118" amount="-4,875" />
|
||||
<kerning first="84" second="119" amount="-4,875" />
|
||||
<kerning first="84" second="121" amount="-4,875" />
|
||||
<kerning first="84" second="122" amount="-4,25" />
|
||||
<kerning first="84" second="125" amount="0,5" />
|
||||
<kerning first="84" second="199" amount="-1" />
|
||||
<kerning first="84" second="198" amount="-3,125" />
|
||||
<kerning first="84" second="216" amount="-1,25" />
|
||||
<kerning first="84" second="230" amount="-5,875" />
|
||||
<kerning first="84" second="248" amount="-5,375" />
|
||||
<kerning first="121" second="44" amount="-4,625" />
|
||||
<kerning first="84" second="338" amount="-1,25" />
|
||||
<kerning first="84" second="339" amount="-5,375" />
|
||||
<kerning first="120" second="339" amount="-0,5" />
|
||||
<kerning first="120" second="248" amount="-0,625" />
|
||||
<kerning first="85" second="44" amount="-0,5" />
|
||||
<kerning first="85" second="46" amount="-0,5" />
|
||||
<kerning first="85" second="65" amount="-0,25" />
|
||||
<kerning first="85" second="198" amount="-0,5" />
|
||||
<kerning first="120" second="231" amount="-0,5" />
|
||||
<kerning first="86" second="44" amount="-7,125" />
|
||||
<kerning first="86" second="45" amount="-1,25" />
|
||||
<kerning first="86" second="46" amount="-7,125" />
|
||||
<kerning first="86" second="58" amount="-2" />
|
||||
<kerning first="120" second="111" amount="-0,625" />
|
||||
<kerning first="86" second="65" amount="-1,375" />
|
||||
<kerning first="86" second="97" amount="-2,375" />
|
||||
<kerning first="86" second="101" amount="-2,375" />
|
||||
<kerning first="86" second="111" amount="-2,375" />
|
||||
<kerning first="86" second="117" amount="-1,375" />
|
||||
<kerning first="86" second="121" amount="-1,625" />
|
||||
<kerning first="86" second="198" amount="-1,75" />
|
||||
<kerning first="86" second="230" amount="-2,375" />
|
||||
<kerning first="86" second="248" amount="-2,375" />
|
||||
<kerning first="120" second="103" amount="-0,25" />
|
||||
<kerning first="86" second="339" amount="-2,375" />
|
||||
<kerning first="120" second="101" amount="-0,625" />
|
||||
<kerning first="120" second="100" amount="-0,25" />
|
||||
<kerning first="87" second="44" amount="-7,125" />
|
||||
<kerning first="87" second="45" amount="-1,25" />
|
||||
<kerning first="87" second="46" amount="-5,375" />
|
||||
<kerning first="87" second="58" amount="-2" />
|
||||
<kerning first="120" second="99" amount="-0,5" />
|
||||
<kerning first="87" second="65" amount="-1,25" />
|
||||
<kerning first="87" second="97" amount="-2" />
|
||||
<kerning first="87" second="101" amount="-2" />
|
||||
<kerning first="87" second="111" amount="-2" />
|
||||
<kerning first="87" second="114" amount="-1" />
|
||||
<kerning first="87" second="117" amount="-1" />
|
||||
<kerning first="87" second="121" amount="-1,375" />
|
||||
<kerning first="87" second="198" amount="-1" />
|
||||
<kerning first="87" second="230" amount="-2" />
|
||||
<kerning first="87" second="248" amount="-2" />
|
||||
<kerning first="120" second="45" amount="-1,25" />
|
||||
<kerning first="87" second="339" amount="-2" />
|
||||
<kerning first="119" second="230" amount="-0,5" />
|
||||
<kerning first="119" second="97" amount="-0,5" />
|
||||
<kerning first="88" second="45" amount="-2" />
|
||||
<kerning first="88" second="67" amount="-0,25" />
|
||||
<kerning first="88" second="71" amount="-0,25" />
|
||||
<kerning first="88" second="79" amount="-0,25" />
|
||||
<kerning first="88" second="97" amount="-1" />
|
||||
<kerning first="88" second="101" amount="-1,125" />
|
||||
<kerning first="88" second="111" amount="-1,125" />
|
||||
<kerning first="88" second="117" amount="-0,75" />
|
||||
<kerning first="88" second="121" amount="-1,75" />
|
||||
<kerning first="88" second="199" amount="-0,25" />
|
||||
<kerning first="88" second="216" amount="-0,25" />
|
||||
<kerning first="88" second="230" amount="-1,25" />
|
||||
<kerning first="88" second="248" amount="-1,375" />
|
||||
<kerning first="88" second="338" amount="-0,25" />
|
||||
<kerning first="88" second="339" amount="-1,375" />
|
||||
<kerning first="119" second="46" amount="-1,75" />
|
||||
<kerning first="119" second="45" amount="-0,5" />
|
||||
<kerning first="89" second="44" amount="-7,125" />
|
||||
<kerning first="89" second="45" amount="-3,375" />
|
||||
<kerning first="89" second="46" amount="-7,125" />
|
||||
<kerning first="89" second="58" amount="-4,875" />
|
||||
<kerning first="119" second="44" amount="-1,75" />
|
||||
<kerning first="89" second="65" amount="-2" />
|
||||
<kerning first="89" second="74" amount="-1,5" />
|
||||
<kerning first="89" second="79" amount="-0,5" />
|
||||
<kerning first="89" second="97" amount="-3,375" />
|
||||
<kerning first="89" second="100" amount="-3" />
|
||||
<kerning first="89" second="101" amount="-3,125" />
|
||||
<kerning first="89" second="103" amount="-3,125" />
|
||||
<kerning first="89" second="109" amount="-2,375" />
|
||||
<kerning first="89" second="110" amount="-2,375" />
|
||||
<kerning first="89" second="111" amount="-3,125" />
|
||||
<kerning first="89" second="112" amount="-2,375" />
|
||||
<kerning first="89" second="113" amount="-3,125" />
|
||||
<kerning first="89" second="114" amount="-2,375" />
|
||||
<kerning first="89" second="115" amount="-2,75" />
|
||||
<kerning first="89" second="117" amount="-2,75" />
|
||||
<kerning first="89" second="118" amount="-2,375" />
|
||||
<kerning first="89" second="198" amount="-2" />
|
||||
<kerning first="89" second="216" amount="-0,5" />
|
||||
<kerning first="89" second="230" amount="-3,375" />
|
||||
<kerning first="89" second="248" amount="-3,125" />
|
||||
<kerning first="118" second="339" amount="-0,25" />
|
||||
<kerning first="89" second="338" amount="-0,5" />
|
||||
<kerning first="89" second="339" amount="-3,125" />
|
||||
<kerning first="118" second="248" amount="-0,375" />
|
||||
<kerning first="118" second="230" amount="-1" />
|
||||
<kerning first="90" second="45" amount="-1,375" />
|
||||
<kerning first="90" second="67" amount="-0,5" />
|
||||
<kerning first="90" second="71" amount="-0,5" />
|
||||
<kerning first="90" second="79" amount="-0,5" />
|
||||
<kerning first="90" second="90" amount="-0,25" />
|
||||
<kerning first="90" second="97" amount="-1,25" />
|
||||
<kerning first="90" second="101" amount="-1,375" />
|
||||
<kerning first="90" second="111" amount="-1,375" />
|
||||
<kerning first="90" second="119" amount="-1" />
|
||||
<kerning first="90" second="121" amount="-1,625" />
|
||||
<kerning first="90" second="199" amount="-0,5" />
|
||||
<kerning first="90" second="216" amount="-0,5" />
|
||||
<kerning first="90" second="230" amount="-1,25" />
|
||||
<kerning first="90" second="248" amount="-1,375" />
|
||||
<kerning first="90" second="338" amount="-0,5" />
|
||||
<kerning first="90" second="339" amount="-1,375" />
|
||||
<kerning first="118" second="111" amount="-0,375" />
|
||||
<kerning first="118" second="101" amount="-0,375" />
|
||||
<kerning first="91" second="84" amount="0,5" />
|
||||
<kerning first="91" second="106" amount="1,25" />
|
||||
<kerning first="97" second="118" amount="-0,375" />
|
||||
<kerning first="97" second="119" amount="-0,25" />
|
||||
<kerning first="97" second="121" amount="-0,375" />
|
||||
<kerning first="98" second="44" amount="-0,75" />
|
||||
<kerning first="98" second="46" amount="-0,5" />
|
||||
<kerning first="98" second="121" amount="-0,125" />
|
||||
<kerning first="118" second="97" amount="-1" />
|
||||
<kerning first="99" second="45" amount="-0,5" />
|
||||
<kerning first="99" second="84" amount="-2,5" />
|
||||
<kerning first="99" second="99" amount="-0,125" />
|
||||
<kerning first="99" second="231" amount="-0,125" />
|
||||
<kerning first="118" second="46" amount="-4,375" />
|
||||
<kerning first="118" second="45" amount="-1" />
|
||||
<kerning first="101" second="84" amount="-3,375" />
|
||||
<kerning first="102" second="34" amount="2,25" />
|
||||
<kerning first="102" second="39" amount="2,25" />
|
||||
<kerning first="102" second="41" amount="2,625" />
|
||||
<kerning first="102" second="42" amount="1,75" />
|
||||
<kerning first="102" second="44" amount="-3,875" />
|
||||
<kerning first="102" second="45" amount="-1,75" />
|
||||
<kerning first="102" second="46" amount="-3,875" />
|
||||
<kerning first="102" second="63" amount="3" />
|
||||
<kerning first="102" second="92" amount="2,375" />
|
||||
<kerning first="102" second="93" amount="2,625" />
|
||||
<kerning first="102" second="97" amount="-0,625" />
|
||||
<kerning first="102" second="99" amount="-0,5" />
|
||||
<kerning first="102" second="101" amount="-0,5" />
|
||||
<kerning first="102" second="102" amount="-0,375" />
|
||||
<kerning first="102" second="103" amount="-0,25" />
|
||||
<kerning first="102" second="106" amount="-0,5" />
|
||||
<kerning first="102" second="109" amount="-0,25" />
|
||||
<kerning first="102" second="110" amount="-0,25" />
|
||||
<kerning first="102" second="111" amount="-0,5" />
|
||||
<kerning first="102" second="112" amount="-0,25" />
|
||||
<kerning first="102" second="113" amount="-0,25" />
|
||||
<kerning first="102" second="114" amount="-0,25" />
|
||||
<kerning first="102" second="115" amount="-0,625" />
|
||||
<kerning first="102" second="117" amount="-0,5" />
|
||||
<kerning first="102" second="121" amount="-0,625" />
|
||||
<kerning first="102" second="125" amount="2,625" />
|
||||
<kerning first="102" second="233" amount="-0,5" />
|
||||
<kerning first="102" second="238" amount="3,125" />
|
||||
<kerning first="102" second="230" amount="-0,625" />
|
||||
<kerning first="102" second="248" amount="-0,5" />
|
||||
<kerning first="118" second="44" amount="-4,375" />
|
||||
<kerning first="116" second="121" amount="-0,5" />
|
||||
<kerning first="116" second="118" amount="-0,5" />
|
||||
<kerning first="116" second="116" amount="-0,375" />
|
||||
<kerning first="116" second="45" amount="-1" />
|
||||
<kerning first="103" second="106" amount="0,25" />
|
||||
<kerning first="104" second="118" amount="-0,5" />
|
||||
<kerning first="104" second="119" amount="-0,25" />
|
||||
<kerning first="104" second="121" amount="-0,5" />
|
||||
<kerning first="105" second="102" amount="0,125" />
|
||||
<kerning first="114" second="339" amount="-0,25" />
|
||||
<kerning first="114" second="248" amount="-0,25" />
|
||||
<kerning first="105" second="116" amount="0,125" />
|
||||
<kerning first="107" second="45" amount="-2,375" />
|
||||
<kerning first="107" second="101" amount="-0,5" />
|
||||
<kerning first="107" second="111" amount="-0,5" />
|
||||
<kerning first="107" second="248" amount="-0,5" />
|
||||
<kerning first="107" second="339" amount="-0,5" />
|
||||
<kerning first="114" second="230" amount="-1" />
|
||||
<kerning first="114" second="233" amount="-0,25" />
|
||||
<kerning first="114" second="231" amount="-0,25" />
|
||||
<kerning first="114" second="113" amount="-0,25" />
|
||||
<kerning first="108" second="108" amount="0,125" />
|
||||
<kerning first="108" second="116" amount="0,125" />
|
||||
<kerning first="108" second="238" amount="0,25" />
|
||||
<kerning first="108" second="239" amount="0,25" />
|
||||
<kerning first="114" second="111" amount="-0,25" />
|
||||
<kerning first="109" second="118" amount="-0,5" />
|
||||
<kerning first="109" second="119" amount="-0,25" />
|
||||
<kerning first="109" second="121" amount="-0,5" />
|
||||
<kerning first="110" second="118" amount="-0,5" />
|
||||
<kerning first="110" second="119" amount="-0,25" />
|
||||
<kerning first="110" second="121" amount="-0,5" />
|
||||
<kerning first="111" second="44" amount="-0,75" />
|
||||
<kerning first="111" second="46" amount="-0,5" />
|
||||
<kerning first="111" second="118" amount="-0,25" />
|
||||
<kerning first="111" second="120" amount="-0,5" />
|
||||
<kerning first="111" second="121" amount="-0,25" />
|
||||
<kerning first="114" second="103" amount="-0,25" />
|
||||
<kerning first="112" second="44" amount="-0,75" />
|
||||
<kerning first="112" second="46" amount="-0,5" />
|
||||
<kerning first="112" second="121" amount="-0,125" />
|
||||
<kerning first="114" second="101" amount="-0,25" />
|
||||
<kerning first="114" second="44" amount="-7,125" />
|
||||
<kerning first="114" second="45" amount="-0,625" />
|
||||
<kerning first="114" second="46" amount="-7,125" />
|
||||
<kerning first="114" second="97" amount="-0,875" />
|
||||
<kerning first="114" second="99" amount="-0,25" />
|
||||
<kerning first="114" second="100" amount="-0,25" />
|
||||
</kernings>
|
||||
</font>
|
||||
BIN
rainbow/CoreGl/Fonts/TahomaN_0.png
Normal file
BIN
rainbow/CoreGl/Fonts/TahomaN_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
40
rainbow/CoreGl/Gl.h
Normal file
40
rainbow/CoreGl/Gl.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef _CoreGl_Gl_h_
|
||||
#define _CoreGl_Gl_h_
|
||||
|
||||
#ifdef flagLINUXGL
|
||||
#define Time XTime
|
||||
#define Font XFont
|
||||
#define Display XDisplay
|
||||
#define Picture XPicture
|
||||
#define Screen XScreen
|
||||
#define Window XWindow
|
||||
#define Complex XComplex
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
|
||||
#include <CoreGl/glew.h>
|
||||
|
||||
#ifdef flagWINGL
|
||||
#include <CoreGl/wglew.h>
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#ifdef flagLINUXGL
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#ifdef flagLINUXGL
|
||||
#undef Picture
|
||||
#undef Time
|
||||
#undef Font
|
||||
#undef Display
|
||||
#undef Screen
|
||||
#undef Window
|
||||
#undef Complex
|
||||
#endif
|
||||
|
||||
#endif
|
||||
90
rainbow/CoreGl/Image.cpp
Normal file
90
rainbow/CoreGl/Image.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
Image ImageDraw::Get(bool pm) const
|
||||
{
|
||||
ImageBuffer result(image.GetSize());
|
||||
const RGBA *e = image.End();
|
||||
const RGBA *p = ~image;
|
||||
RGBA *t = ~result;
|
||||
if(has_alpha) {
|
||||
const RGBA *a = ~alpha;
|
||||
while(p < e) {
|
||||
*t = *p++;
|
||||
(t++)->a = (a++)->r;
|
||||
}
|
||||
if(pm)
|
||||
Premultiply(result);
|
||||
result.SetKind(IMAGE_ALPHA);
|
||||
}
|
||||
else {
|
||||
while(p < e) {
|
||||
*t = *p++;
|
||||
(t++)->a = 255;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Draw& ImageDraw::Alpha()
|
||||
{
|
||||
has_alpha = true;
|
||||
return alpha_painter;
|
||||
}
|
||||
|
||||
|
||||
ImageDraw::ImageDraw(Size sz)
|
||||
: ImageDraw__(sz.cx, sz.cy),
|
||||
BufferPainter(image),
|
||||
alpha_painter(alpha)
|
||||
{
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(int cx, int cy)
|
||||
: ImageDraw__(cx, cy),
|
||||
BufferPainter(image),
|
||||
alpha_painter(alpha)
|
||||
{
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
#define IMAGECLASS CoreGlImg
|
||||
#define IMAGEFILE <CoreGl/CoreGl.iml>
|
||||
#include <Draw/iml_source.h>
|
||||
|
||||
Image Image::Arrow() { return CoreGlImg::arrow(); }
|
||||
Image Image::Wait() { return CoreGlImg::wait(); }
|
||||
Image Image::IBeam() { return CoreGlImg::ibeam(); }
|
||||
Image Image::No() { return CoreGlImg::no(); }
|
||||
Image Image::SizeAll() { return CoreGlImg::sizeall(); }
|
||||
Image Image::SizeHorz() { return CoreGlImg::sizehorz(); }
|
||||
Image Image::SizeVert() { return CoreGlImg::sizevert(); }
|
||||
Image Image::SizeTopLeft() { return CoreGlImg::sizetopleft(); }
|
||||
Image Image::SizeTop() { return CoreGlImg::sizetop(); }
|
||||
Image Image::SizeTopRight() { return CoreGlImg::sizetopright(); }
|
||||
Image Image::SizeLeft() { return CoreGlImg::sizeleft(); }
|
||||
Image Image::SizeRight() { return CoreGlImg::sizeright(); }
|
||||
Image Image::SizeBottomLeft() { return CoreGlImg::sizebottomleft(); }
|
||||
Image Image::SizeBottom() { return CoreGlImg::sizebottom(); }
|
||||
Image Image::SizeBottomRight() { return CoreGlImg::sizebottomright(); }
|
||||
Image Image::Hand() { return CoreGlImg::hand(); }
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
103
rainbow/CoreGl/ResGl.h
Normal file
103
rainbow/CoreGl/ResGl.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#ifndef _CoreGl_ResGl_h_
|
||||
#define _CoreGl_ResGl_h_
|
||||
|
||||
struct TextureResource : Moveable<TextureResource>
|
||||
{
|
||||
int64 serialId;
|
||||
int64 atlasSerialId;
|
||||
int realWidth;
|
||||
int realHeight;
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
TextureResource(int w = 0, int h = 0)
|
||||
{
|
||||
serialId = -1;
|
||||
atlasSerialId = -1;
|
||||
realWidth = w;
|
||||
realHeight = h;
|
||||
width = w;
|
||||
height = h;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
String ToString() const
|
||||
{
|
||||
return Format("x: %d, y: %d, w: %d, h:%d (%d, %d) - %ld", x, y, width, height, realWidth, realHeight, serialId);
|
||||
}
|
||||
};
|
||||
|
||||
struct AtlasResource : Moveable<AtlasResource>
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
bool linear;
|
||||
Vector<Image> parts;
|
||||
Image Make(ArrayMap<int64, TextureResource>& textures);
|
||||
};
|
||||
|
||||
struct ImageResource : Moveable<ImageResource>
|
||||
{
|
||||
int type;
|
||||
bool linear;
|
||||
|
||||
//direct image
|
||||
Image img;
|
||||
//brc image
|
||||
const byte* data;
|
||||
int length;
|
||||
//disk image
|
||||
String fileName;
|
||||
};
|
||||
|
||||
struct Resources
|
||||
{
|
||||
enum {
|
||||
NEAREST_FILTERING = 1,
|
||||
LINEAR_FILTERING = 2,
|
||||
FORCE_FILTERING = 4,
|
||||
AUTO_ATLAS = 8,
|
||||
FORCE_BIND = 16
|
||||
};
|
||||
|
||||
Vector<ImageResource> staticImages;
|
||||
VectorMap<String, AtlasResource> staticAtlases;
|
||||
Vector<Font> staticFonts;
|
||||
|
||||
TextureResource autoAtlas;
|
||||
ImageBuffer autoAtlasBuffer;
|
||||
Image autoAtlasImage;
|
||||
int px, py, maxh;
|
||||
|
||||
int bindedTextures;
|
||||
|
||||
int64 currentSerialId;
|
||||
ArrayMap<int64, TextureResource> textures;
|
||||
ArrayMap<String, OpenGLFont> fonts;
|
||||
|
||||
const TextureResource& CreateTexture(const Image& img, int width = -1, int height = -1);
|
||||
void CreateSubTexture(const TextureResource& t, const Image& img, int x, int y);
|
||||
|
||||
const TextureResource& Bind(const Image& img, int opts = NEAREST_FILTERING);
|
||||
bool Bind(int64 serialId, int opts = NEAREST_FILTERING);
|
||||
void Add(const Image& img, bool linear = false);
|
||||
void Add(Iml* images, bool linear = false);
|
||||
void Add(const Font& fnt);
|
||||
void AddAtlas(const char* atlasName, const Image& img);
|
||||
void AddAtlas(const char* atlasName, Iml* images);
|
||||
OpenGLFont& GetFont(const char* fontName, int fontHeight, bool preload = false, const byte* fontDef = NULL, const byte** imagesData = NULL, const int* imagesSize = NULL, int imagesCount = 0);
|
||||
OpenGLFont& GetFont(const Font& font, bool preload = false);
|
||||
void SetTextureFiltring(int opts);
|
||||
|
||||
void BindStatic();
|
||||
|
||||
Resources();
|
||||
};
|
||||
|
||||
extern Resources resources;
|
||||
|
||||
|
||||
#endif
|
||||
8
rainbow/CoreGl/Resources.brc
Normal file
8
rainbow/CoreGl/Resources.brc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
BINARY(alphaMagFrag, "AlphaMag.frag")
|
||||
BINARY(alphaMagVert, "AlphaMag.vert")
|
||||
BINARY(blurVert, "Blur.vert")
|
||||
BINARY(blurFrag, "Blur.frag")
|
||||
BINARY(tahomaNFontDef, "Fonts/TahomaN.fnt")
|
||||
BINARY_ARRAY(tahomaNFontImg, 0, "Fonts/TahomaN_0.png")
|
||||
BINARY(tahomaBFontDef, "Fonts/TahomaB.fnt")
|
||||
BINARY_ARRAY(tahomaBFontImg, 0, "Fonts/TahomaB_0.png")
|
||||
362
rainbow/CoreGl/Resources.cpp
Normal file
362
rainbow/CoreGl/Resources.cpp
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "CoreGl.h"
|
||||
#include <plugin/png/png.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
Resources resources;
|
||||
|
||||
Resources::Resources() : autoAtlas(1024, 1024)
|
||||
{
|
||||
px = 0;
|
||||
py = 0;
|
||||
maxh = 0;
|
||||
currentSerialId = -1;
|
||||
bindedTextures = 0;
|
||||
}
|
||||
|
||||
void Resources::SetTextureFiltring(int opts)
|
||||
{
|
||||
if(opts & LINEAR_FILTERING)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else if(opts & NEAREST_FILTERING)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
const TextureResource& Resources::CreateTexture(const Image& img, int width, int height)
|
||||
{
|
||||
int64 serialId = img.GetSerialId();
|
||||
TextureResource& t = textures.Add(serialId);
|
||||
t.serialId = serialId;
|
||||
t.atlasSerialId = -1;
|
||||
t.width = width > 0 ? width : img.GetWidth();
|
||||
t.height = height > 0 ? height : img.GetHeight();
|
||||
t.realWidth = t.width;
|
||||
t.realHeight = t.height;
|
||||
t.x = 0;
|
||||
t.y = 0;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t.width, t.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, img);
|
||||
++bindedTextures;
|
||||
return t;
|
||||
}
|
||||
|
||||
void Resources::CreateSubTexture(const TextureResource& t, const Image& img, int x, int y)
|
||||
{
|
||||
Bind(autoAtlas.serialId, 0);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, img.GetWidth(), img.GetHeight(), GL_BGRA, GL_UNSIGNED_BYTE, img);
|
||||
}
|
||||
|
||||
const TextureResource& Resources::Bind(const Image& img, int opts)
|
||||
{
|
||||
int64 serialId = img.GetSerialId();
|
||||
|
||||
const TextureResource* texture = textures.FindPtr(serialId);
|
||||
if(texture)
|
||||
{
|
||||
if(texture->atlasSerialId >= 0)
|
||||
serialId = texture->atlasSerialId;
|
||||
}
|
||||
else if(opts & AUTO_ATLAS)
|
||||
{
|
||||
int w = img.GetWidth();
|
||||
int h = img.GetHeight();
|
||||
|
||||
if(w <= autoAtlas.width && h <= autoAtlas.height && w <= 64 && h <= 64)
|
||||
{
|
||||
bool add = px + w <= autoAtlas.width && py + h <= autoAtlas.height;
|
||||
|
||||
if(!add)
|
||||
{
|
||||
if(py + maxh + h > autoAtlas.height)
|
||||
{
|
||||
add = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
px = 0;
|
||||
py += maxh;
|
||||
maxh = 0;
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(add)
|
||||
{
|
||||
if(h > maxh)
|
||||
maxh = h;
|
||||
|
||||
TextureResource& t = textures.Add(img.GetSerialId());
|
||||
t.atlasSerialId = autoAtlas.serialId;
|
||||
t.width = w;
|
||||
t.height = h;
|
||||
t.realWidth = autoAtlas.width;
|
||||
t.realHeight = autoAtlas.height;
|
||||
t.x = px;
|
||||
t.y = py;
|
||||
|
||||
CreateSubTexture(autoAtlas, img, px, py);
|
||||
Copy(autoAtlasImage, Point(px, py), img, img.GetSize());
|
||||
|
||||
px += w;
|
||||
|
||||
texture = &t;
|
||||
serialId = autoAtlas.serialId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!Bind(serialId, opts))
|
||||
return *texture;
|
||||
|
||||
if(!texture)
|
||||
{
|
||||
texture = &CreateTexture(img);
|
||||
}
|
||||
|
||||
return *texture;
|
||||
}
|
||||
|
||||
bool Resources::Bind(int64 serialId, int opts)
|
||||
{
|
||||
if(!(opts & FORCE_BIND) && serialId == currentSerialId)
|
||||
{
|
||||
if(opts & FORCE_FILTERING)
|
||||
SetTextureFiltring(opts);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSerialId = serialId;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint) serialId);
|
||||
SetTextureFiltring(opts);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Resources::BindStatic()
|
||||
{
|
||||
if(autoAtlas.serialId < 0)
|
||||
{
|
||||
autoAtlasBuffer.Create(autoAtlas.width, autoAtlas.height);
|
||||
Fill(autoAtlasBuffer, RGBAZero(), autoAtlasBuffer.GetLength());
|
||||
autoAtlasImage = autoAtlasBuffer;
|
||||
Bind(autoAtlasImage.GetSerialId());
|
||||
autoAtlas = CreateTexture(autoAtlasImage);
|
||||
}
|
||||
|
||||
if(!staticImages.IsEmpty())
|
||||
{
|
||||
for(int i = 0; i < staticImages.GetCount(); i++)
|
||||
Bind(staticImages[i].img, staticImages[i].linear ? Resources::LINEAR_FILTERING : Resources::NEAREST_FILTERING);
|
||||
staticImages.Clear();
|
||||
}
|
||||
|
||||
if(!staticAtlases.IsEmpty())
|
||||
{
|
||||
for(int i = 0; i < staticAtlases.GetCount(); i++)
|
||||
Bind(staticAtlases[i].Make(textures), staticAtlases[i].linear ? Resources::LINEAR_FILTERING : Resources::NEAREST_FILTERING);
|
||||
staticAtlases.Clear();
|
||||
}
|
||||
|
||||
if(!staticFonts.IsEmpty())
|
||||
{
|
||||
for(int i = 0; i < staticFonts.GetCount(); i++)
|
||||
GetFont(staticFonts[i], true);
|
||||
staticFonts.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Resources::Add(const Image& img, bool linear)
|
||||
{
|
||||
ImageResource& ir = staticImages.Add();
|
||||
ir.img = img;
|
||||
ir.linear = linear;
|
||||
}
|
||||
|
||||
void Resources::Add(const Font& fnt)
|
||||
{
|
||||
Font& f = staticFonts.Add(fnt);
|
||||
}
|
||||
|
||||
void Resources::Add(Iml* images, bool linear)
|
||||
{
|
||||
for(int i = 0; i < images->GetCount(); i++)
|
||||
Add(images->Get(i), linear);
|
||||
}
|
||||
|
||||
void Resources::AddAtlas(const char* atlasName, const Image& img)
|
||||
{
|
||||
AtlasResource& atlas = staticAtlases.GetAdd(atlasName);
|
||||
atlas.linear = false;
|
||||
atlas.parts.Add(img);
|
||||
}
|
||||
|
||||
void Resources::AddAtlas(const char* atlasName, Iml* images)
|
||||
{
|
||||
AtlasResource& atlas = staticAtlases.GetAdd(atlasName);
|
||||
atlas.linear = false;
|
||||
for(int i = 0; i < images->GetCount(); i++)
|
||||
atlas.parts.Add(images->Get(i));
|
||||
}
|
||||
|
||||
Image AtlasResource::Make(ArrayMap<int64, TextureResource>& textures)
|
||||
{
|
||||
width = 512;
|
||||
height = 512;
|
||||
|
||||
ImageBuffer ib(width, height);
|
||||
Fill(ib, RGBAZero(), ib.GetLength());
|
||||
|
||||
Point p(0, 0);
|
||||
int maxh = 0;
|
||||
|
||||
int tidx = textures.GetCount();
|
||||
|
||||
for(int i = 0; i < parts.GetCount(); i++)
|
||||
{
|
||||
Image& img = parts[i];
|
||||
|
||||
int w = img.GetWidth();
|
||||
int h = img.GetHeight();
|
||||
|
||||
if(w > width || h > height)
|
||||
continue;
|
||||
|
||||
if(p.x + w > width)
|
||||
{
|
||||
if(p.y + maxh + h > height)
|
||||
continue;
|
||||
|
||||
p.x = 0;
|
||||
p.y += maxh;
|
||||
maxh = 0;
|
||||
}
|
||||
|
||||
if(h > maxh)
|
||||
maxh = h;
|
||||
|
||||
TextureResource& t = textures.Add(img.GetSerialId());
|
||||
t.width = w;
|
||||
t.height = h;
|
||||
t.realWidth = width;
|
||||
t.realHeight = height;
|
||||
t.x = p.x;
|
||||
t.y = p.y;
|
||||
|
||||
Copy(ib, p, img, img.GetSize());
|
||||
|
||||
p.x += w;
|
||||
}
|
||||
|
||||
Image finalImg(ib);
|
||||
int64 finalSerialId = finalImg.GetSerialId();
|
||||
|
||||
for(int i = tidx; i < textures.GetCount(); i++)
|
||||
textures[i].atlasSerialId = finalSerialId;
|
||||
|
||||
return finalImg;
|
||||
}
|
||||
|
||||
OpenGLFont& Resources::GetFont(const char* fontName, int fontHeight, bool preload, const byte* fontDef, const byte** imagesData, const int* imagesSize, int imagesCount)
|
||||
{
|
||||
int n = fonts.Find(fontName);
|
||||
OpenGLFont* fgl = NULL;
|
||||
if(n >= 0)
|
||||
fgl = &fonts[n];
|
||||
else
|
||||
{
|
||||
fgl = &fonts.Add(fontName);
|
||||
fgl->preload = preload;
|
||||
|
||||
if(fontDef)
|
||||
fgl->LoadBrc(fontDef, imagesData, imagesSize, imagesCount);
|
||||
else
|
||||
fgl->Load(fontName);
|
||||
}
|
||||
|
||||
fgl->scale = (fontHeight * 96.f / 72.f) / 72.f;
|
||||
return *fgl;
|
||||
}
|
||||
|
||||
OpenGLFont& Resources::GetFont(const Font& font, bool preload)
|
||||
{
|
||||
if(font.IsBold())
|
||||
return GetFont("TahomaB", font.GetHeight(), preload,
|
||||
tahomaBFontDef, (const byte**) tahomaBFontImg, tahomaBFontImg_length, tahomaBFontImg_count);
|
||||
else
|
||||
return GetFont("TahomaN", font.GetHeight(), preload,
|
||||
tahomaNFontDef, (const byte**) tahomaNFontImg, tahomaNFontImg_length, tahomaNFontImg_count);
|
||||
}
|
||||
|
||||
int64 GetHighTickCount()
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
static int64 counterFreq = 0;
|
||||
if(counterFreq == 0)
|
||||
{
|
||||
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &counterFreq))
|
||||
counterFreq = 0;
|
||||
}
|
||||
if(counterFreq > 0)
|
||||
{
|
||||
int64 counter;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &counter);
|
||||
return counter * 1000 / counterFreq;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
#else
|
||||
return GetTickCount();
|
||||
#endif
|
||||
}
|
||||
|
||||
float GetFps()
|
||||
{
|
||||
static float fps = 0.0f;
|
||||
static int64 updateInterval = 1000;
|
||||
static int64 timeSinceLastUpdate = 0;
|
||||
static int64 frameCount = 0;
|
||||
static int64 currentTick;
|
||||
static int64 lastTick;
|
||||
static bool isFirst = true;
|
||||
|
||||
if(isFirst)
|
||||
{
|
||||
currentTick = frameInfo.curr_tick_count;
|
||||
lastTick = currentTick;
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
frameCount++;
|
||||
currentTick = frameInfo.curr_tick_count;
|
||||
|
||||
int64 elapsed = currentTick - lastTick;
|
||||
|
||||
lastTick = currentTick;
|
||||
timeSinceLastUpdate += elapsed;
|
||||
|
||||
if (timeSinceLastUpdate > updateInterval)
|
||||
{
|
||||
if (timeSinceLastUpdate)
|
||||
{
|
||||
fps = (frameCount / float(timeSinceLastUpdate)) * 1000.f;
|
||||
frameCount = 0;
|
||||
timeSinceLastUpdate -= updateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
return fps;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
10
rainbow/CoreGl/SceneGraph.cpp
Normal file
10
rainbow/CoreGl/SceneGraph.cpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "SceneGraph.h"
|
||||
/*
|
||||
GraphNode::GraphNode() : next(NULL), prev(NULL)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
24
rainbow/CoreGl/SceneGraph.h
Normal file
24
rainbow/CoreGl/SceneGraph.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _WinGl_SceneGraph_h_
|
||||
#define _WinGl_SceneGraph_h_
|
||||
/*
|
||||
struct GraphNode : Moveable<GraphNode>
|
||||
{
|
||||
RGBA color;
|
||||
double x, y, z;
|
||||
|
||||
GraphNode* prev;
|
||||
GraphNode* next;
|
||||
|
||||
GraphNode();
|
||||
};
|
||||
|
||||
class SceneGraph
|
||||
{
|
||||
private:
|
||||
GraphNode* root;
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
*/
|
||||
#endif
|
||||
332
rainbow/CoreGl/Scrollbar.cpp
Normal file
332
rainbow/CoreGl/Scrollbar.cpp
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "Scrollbar.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void AlignedFrame::FrameLayout(Rect &r)
|
||||
{
|
||||
switch(layout)
|
||||
{
|
||||
case LEFT:
|
||||
LayoutFrameLeft(r, this, framesize);
|
||||
break;
|
||||
case TOP:
|
||||
LayoutFrameTop(r, this, framesize);
|
||||
break;
|
||||
case RIGHT:
|
||||
LayoutFrameRight(r, this, framesize);
|
||||
break;
|
||||
case BOTTOM:
|
||||
LayoutFrameBottom(r, this, framesize);
|
||||
break;
|
||||
}
|
||||
r.top += border;
|
||||
r.left += border;
|
||||
r.right -= border;
|
||||
r.bottom -= border;
|
||||
}
|
||||
|
||||
void AlignedFrame::FrameAddSize(Size& sz)
|
||||
{
|
||||
sz += border * 2;
|
||||
IsVert() ? sz.cx += framesize : sz.cy += framesize;
|
||||
}
|
||||
|
||||
void AlignedFrame::FramePaint(Draw& w, const Rect& r)
|
||||
{
|
||||
if(border > 0)
|
||||
{
|
||||
Rect n = r;
|
||||
switch(layout)
|
||||
{
|
||||
case LEFT:
|
||||
n.left += framesize;
|
||||
break;
|
||||
case TOP:
|
||||
n.top += framesize;
|
||||
break;
|
||||
case RIGHT:
|
||||
n.right -= framesize;
|
||||
break;
|
||||
case BOTTOM:
|
||||
n.bottom -= framesize;
|
||||
break;
|
||||
}
|
||||
ViewFrame().FramePaint(w, n);
|
||||
}
|
||||
else
|
||||
FrameCtrl<Ctrl>::FramePaint(w, r);
|
||||
}
|
||||
|
||||
AlignedFrame& AlignedFrame::SetFrameSize(int sz, bool refresh)
|
||||
{
|
||||
framesize = sz;
|
||||
if (refresh) RefreshParentLayout();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AlignedFrame::Fix(Size& sz)
|
||||
{
|
||||
if(IsVert())
|
||||
Swap(sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
void AlignedFrame::Fix(Point& p)
|
||||
{
|
||||
if(IsVert())
|
||||
Swap(p.x, p.y);
|
||||
}
|
||||
|
||||
Size AlignedFrame::Fixed(const Size& sz)
|
||||
{
|
||||
return IsVert() ? Size(sz.cy, sz.cx) : Size(sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
Point AlignedFrame::Fixed(const Point& p)
|
||||
{
|
||||
return IsVert() ? Point(p.y, p.x) : Point(p.x, p.y);
|
||||
}
|
||||
|
||||
// SlimScrollBar
|
||||
SlimScrollBar::SlimScrollBar()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void SlimScrollBar::Clear()
|
||||
{
|
||||
total = 0;
|
||||
t = 0;
|
||||
pos = 0;
|
||||
prev_ps = 0;
|
||||
ps = 0;
|
||||
start_pos = 0;
|
||||
new_pos = 0;
|
||||
old_pos = 0;
|
||||
isend = true;
|
||||
isbegin = true;
|
||||
sz.Clear();
|
||||
ready = false;
|
||||
}
|
||||
|
||||
void SlimScrollBar::UpdatePos(bool update, bool whenscroll)
|
||||
{
|
||||
sz = GetSize();
|
||||
Fix(sz);
|
||||
|
||||
if(total <= 0 || sz.cx <= 0)
|
||||
{
|
||||
cs = ics = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs = sz.cx / double(t + 0.5);
|
||||
ics = t / double(sz.cx);
|
||||
}
|
||||
|
||||
size = max(0.0, sz.cx * cs);
|
||||
|
||||
if(update)
|
||||
pos = new_pos - start_pos;
|
||||
|
||||
isbegin = t < sz.cx;
|
||||
isend = t < sz.cx;
|
||||
|
||||
if(pos <= 0)
|
||||
{
|
||||
pos = 0;
|
||||
isbegin = true;
|
||||
}
|
||||
else if(pos + size >= sz.cx)
|
||||
{
|
||||
pos = sz.cx - size;
|
||||
isend = true;
|
||||
}
|
||||
|
||||
ps = t > sz.cx ? pos * ics : 0;
|
||||
|
||||
if(whenscroll && int(ps) != int(prev_ps))
|
||||
WhenScroll();
|
||||
|
||||
prev_ps = ps;
|
||||
}
|
||||
|
||||
void SlimScrollBar::Paint(Draw &w)
|
||||
{
|
||||
if(!ready)
|
||||
{
|
||||
UpdatePos();
|
||||
ready = true;
|
||||
}
|
||||
|
||||
Ctrl* q = GetParent();
|
||||
if(!q)
|
||||
return;
|
||||
|
||||
Size sz = GetSize();
|
||||
Size psz = q->GetSize();
|
||||
|
||||
if(IsHorz() && total > psz.cx || IsVert() && total > psz.cy) {
|
||||
Point p(int(pos), 0);
|
||||
Size rsz(int(size), IsVert() ? sz.cx : sz.cy);
|
||||
Fix(p);
|
||||
Fix(rsz);
|
||||
#ifdef COLOR_ALPHA
|
||||
w.DrawRect(p.x, p.y, rsz.cx, rsz.cy, White().Alpha(150));
|
||||
#else
|
||||
SystemDraw& sw = (SystemDraw&) w;
|
||||
sw.alpha = 150.f;
|
||||
w.DrawRect(p.x, p.y, rsz.cx, rsz.cy, White);
|
||||
sw.alpha = 255.f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void SlimScrollBar::Layout()
|
||||
{
|
||||
Size csz = GetSize();
|
||||
Fix(csz);
|
||||
if(ready && csz != sz)
|
||||
{
|
||||
sz = csz;
|
||||
UpdatePos(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SlimScrollBar::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
SetCapture();
|
||||
Fix(p);
|
||||
old_pos = new_pos = p.x;
|
||||
if(p.x < pos || p.x > pos + size)
|
||||
start_pos = size / 2;
|
||||
else
|
||||
start_pos = tabs(p.x - pos);
|
||||
UpdatePos();
|
||||
UpdateActionRefresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
ReleaseCapture();
|
||||
Fix(p);
|
||||
old_pos = p.x;
|
||||
}
|
||||
|
||||
void SlimScrollBar::MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
if(!HasCapture())
|
||||
return;
|
||||
|
||||
Fix(p);
|
||||
new_pos = p.x;
|
||||
UpdatePos();
|
||||
UpdateActionRefresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::MouseWheel(Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
AddPos(-zdelta / 4, true);
|
||||
UpdateActionRefresh();
|
||||
}
|
||||
|
||||
int SlimScrollBar::GetPos() const
|
||||
{
|
||||
return int(ps);
|
||||
}
|
||||
|
||||
void SlimScrollBar::SetPos(int p, bool dontscale, bool whenscroll)
|
||||
{
|
||||
pos = total > 0 ? dontscale ? p : iscale(p, sz.cx, t) : 0;
|
||||
UpdatePos(false, whenscroll);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::AddPos(int p, bool dontscale, bool whenscroll)
|
||||
{
|
||||
pos += total > 0 ? dontscale ? p : iscale(p, sz.cx, t) : 0;
|
||||
UpdatePos(false, whenscroll);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
int SlimScrollBar::GetTotal() const
|
||||
{
|
||||
return total;
|
||||
}
|
||||
|
||||
void SlimScrollBar::SetTotal(int total, bool whenscroll)
|
||||
{
|
||||
Ctrl* q = GetParent();
|
||||
|
||||
Size sz = GetSize();
|
||||
Size psz = q ? q->GetSize() : Size(0, 0);
|
||||
|
||||
Fix(sz);
|
||||
Fix(psz);
|
||||
|
||||
this->total = total;
|
||||
this->t = total;
|
||||
if(q)
|
||||
this->t -= psz.cx - sz.cx;
|
||||
|
||||
UpdatePos(false, whenscroll);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::AddTotal(int t)
|
||||
{
|
||||
sz = GetSize();
|
||||
Fix(sz);
|
||||
total += t;
|
||||
if(total <= 0 || sz.cx <= 0)
|
||||
cs = ics = 0;
|
||||
else
|
||||
cs = sz.cx / ((double) t + 0.5);
|
||||
size = int(sz.cx * cs);
|
||||
ps = min(ps, (double)(t - sz.cx));
|
||||
pos = (int)(ps * cs);
|
||||
old_pos = new_pos = (int)(pos - start_pos);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::GoEnd(bool whenscroll)
|
||||
{
|
||||
pos = total;
|
||||
UpdatePos(false, whenscroll);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SlimScrollBar::GoBegin(bool whenscroll)
|
||||
{
|
||||
pos = 0;
|
||||
UpdatePos(false, whenscroll);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
bool SlimScrollBar::IsEnd()
|
||||
{
|
||||
return isend;
|
||||
}
|
||||
|
||||
bool SlimScrollBar::IsBegin()
|
||||
{
|
||||
return isbegin;
|
||||
}
|
||||
|
||||
void SlimScrollBar::Set(const SlimScrollBar& t)
|
||||
{
|
||||
total = t.total;
|
||||
pos = t.pos;
|
||||
ps = t.ps;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
bool SlimScrollBar::IsScrollable() const
|
||||
{
|
||||
return t > sz.cx && sz.cx > 0;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
100
rainbow/CoreGl/Scrollbar.h
Normal file
100
rainbow/CoreGl/Scrollbar.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef _CoreGl_Scrollbar_h_
|
||||
#define _CoreGl_Scrollbar_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct AlignedFrame : FrameCtrl<Ctrl>
|
||||
{
|
||||
int layout;
|
||||
int framesize;
|
||||
int border;
|
||||
public:
|
||||
enum
|
||||
{
|
||||
LEFT = 0,
|
||||
TOP = 1,
|
||||
RIGHT = 2,
|
||||
BOTTOM = 3
|
||||
};
|
||||
|
||||
AlignedFrame() : layout(TOP), framesize(0), border(0) {}
|
||||
|
||||
virtual void FrameAddSize(Size& sz);
|
||||
virtual void FramePaint(Draw& w, const Rect& r);
|
||||
virtual void FrameLayout(Rect& r);
|
||||
|
||||
bool IsVert() const { return (layout & 1) == 0; }
|
||||
bool IsHorz() const { return layout & 1; }
|
||||
bool IsTL() const { return layout < 2; }
|
||||
bool IsBR() const { return layout >= 2; }
|
||||
|
||||
AlignedFrame& SetAlign(int align) { layout = align; FrameSet(); RefreshParentLayout(); return *this; }
|
||||
AlignedFrame& SetLeft() { return SetAlign(LEFT); }
|
||||
AlignedFrame& SetTop() { return SetAlign(TOP); }
|
||||
AlignedFrame& SetRight() { return SetAlign(RIGHT); }
|
||||
AlignedFrame& SetBottom() { return SetAlign(BOTTOM); }
|
||||
AlignedFrame& SetFrameSize(int sz, bool refresh = true);
|
||||
|
||||
int GetAlign() const { return layout; }
|
||||
int GetFrameSize() const { return framesize; }
|
||||
int GetBorder() const { return border; }
|
||||
protected:
|
||||
void Fix(Size& sz);
|
||||
void Fix(Point& p);
|
||||
Size Fixed(const Size& sz);
|
||||
Point Fixed(const Point& p);
|
||||
|
||||
bool HasBorder() { return border >= 0; }
|
||||
AlignedFrame& SetBorder(int _border) { border = _border; return *this; }
|
||||
|
||||
virtual void FrameSet() { }
|
||||
};
|
||||
|
||||
class SlimScrollBar : public AlignedFrame
|
||||
{
|
||||
private:
|
||||
int total;
|
||||
int t;
|
||||
bool isend;
|
||||
bool isbegin;
|
||||
double pos, prev_ps, ps;
|
||||
int new_pos;
|
||||
int old_pos;
|
||||
double start_pos;
|
||||
double size;
|
||||
double cs, ics;
|
||||
virtual void UpdatePos(bool update = true, bool whenscroll = true);
|
||||
void RefreshScroll();
|
||||
bool ready;
|
||||
Size sz;
|
||||
public:
|
||||
SlimScrollBar();
|
||||
|
||||
virtual void Paint(Draw& w);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual void MouseMove(Point p, dword keyflags);
|
||||
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
|
||||
virtual void Layout();
|
||||
|
||||
int GetPos() const;
|
||||
void SetPos(int p, bool dontscale = false, bool whenscroll = true);
|
||||
void AddPos(int p, bool dontscale = false, bool whenscroll = true);
|
||||
int GetTotal() const;
|
||||
void AddTotal(int t);
|
||||
void SetTotal(int t, bool whenscroll = true);
|
||||
void GoEnd(bool whenscroll = true);
|
||||
void GoBegin(bool whenscroll = true);
|
||||
bool IsEnd();
|
||||
bool IsBegin();
|
||||
void Clear();
|
||||
void Set(const SlimScrollBar& t);
|
||||
bool IsScrollable() const;
|
||||
Callback WhenScroll;
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
387
rainbow/CoreGl/Shaders.cpp
Normal file
387
rainbow/CoreGl/Shaders.cpp
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "Shaders.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Shader::PrintShaderInfoLog(GLuint obj, const char* fileName)
|
||||
{
|
||||
int infoLength = 0;
|
||||
int charsWritten = 0;
|
||||
|
||||
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infoLength);
|
||||
|
||||
if(infoLength > 0)
|
||||
{
|
||||
char* info = new char[infoLength];
|
||||
glGetShaderInfoLog(obj, infoLength, &charsWritten, info);
|
||||
if(charsWritten > 0)
|
||||
{
|
||||
compileError = info;
|
||||
FileOut f(fileName);
|
||||
f.Put(info);
|
||||
}
|
||||
delete[] info;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::PrintProgramInfoLog(GLuint obj, const char* fileName)
|
||||
{
|
||||
int infoLength = 0;
|
||||
int charsWritten = 0;
|
||||
|
||||
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infoLength);
|
||||
|
||||
if(infoLength > 0)
|
||||
{
|
||||
char* info = new char[infoLength];
|
||||
glGetShaderInfoLog(obj, infoLength, &charsWritten, info);
|
||||
if(charsWritten > 0)
|
||||
{
|
||||
FileOut f(fileName);
|
||||
f.Put(info);
|
||||
}
|
||||
delete[] info;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::PrintProgramValidationLog(GLuint obj, const char* fileName)
|
||||
{
|
||||
char log[1024];
|
||||
int len = 0;
|
||||
glValidateProgram(obj);
|
||||
glGetProgramInfoLog(obj, 1024, &len, log);
|
||||
if(len > 0)
|
||||
{
|
||||
FileOut f(fileName);
|
||||
f.Put(log);
|
||||
}
|
||||
}
|
||||
|
||||
bool Shader::CheckGLError()
|
||||
{
|
||||
unsigned int lastError = glGetError();
|
||||
if(GL_NO_ERROR != lastError)
|
||||
{
|
||||
error = (const char*) gluErrorString(lastError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Shader::IsProgramCompiled(int program)
|
||||
{
|
||||
GLint result = GL_FALSE;
|
||||
glGetShaderiv(program, GL_COMPILE_STATUS, &result);
|
||||
return result == GL_TRUE;
|
||||
}
|
||||
|
||||
bool Shader::IsProgramLinked(int program)
|
||||
{
|
||||
GLint result = GL_FALSE;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &result);
|
||||
return result == GL_TRUE;
|
||||
}
|
||||
|
||||
int Shader::CompileProgram(const char* vs, const char* fs, const char* gs)
|
||||
{
|
||||
vertSrc = vs;
|
||||
fragSrc = fs;
|
||||
geomSrc = gs;
|
||||
|
||||
const GLchar* vertexShaderSrc = (const GLchar*) vertSrc;
|
||||
const GLchar* fragmentShaderSrc = (const GLchar*) fragSrc;
|
||||
const GLchar* geometryShaderSrc = (const GLchar*) geomSrc;
|
||||
|
||||
DeleteFile("shader_vertex.log");
|
||||
DeleteFile("shader_fragment.log");
|
||||
DeleteFile("shader_geometry.log");
|
||||
DeleteFile("shader_link.log");
|
||||
DeleteFile("shader_validation.log");
|
||||
|
||||
GLenum vertexShader = 0;
|
||||
GLenum fragmentShader = 0;
|
||||
GLenum geometryShader = 0;
|
||||
|
||||
if(!vertSrc.IsEmpty())
|
||||
{
|
||||
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL);
|
||||
glCompileShader(vertexShader);
|
||||
|
||||
if(!IsProgramCompiled(vertexShader))
|
||||
{
|
||||
PrintShaderInfoLog(vertexShader, "shader_vertex.log");
|
||||
error = "Vertex shader compilation error:\n\n" + compileError;
|
||||
glDeleteShader(vertexShader);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!fragSrc.IsEmpty())
|
||||
{
|
||||
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
|
||||
if(!IsProgramCompiled(fragmentShader))
|
||||
{
|
||||
PrintShaderInfoLog(fragmentShader, "shader_fragment.log");
|
||||
error = "Fragment shader compilation error:\n\n" + compileError;
|
||||
glDeleteShader(fragmentShader);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!geomSrc.IsEmpty())
|
||||
{
|
||||
geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
glShaderSource(geometryShader, 1, &geometryShaderSrc, NULL);
|
||||
glCompileShader(geometryShader);
|
||||
|
||||
if(!IsProgramCompiled(geometryShader))
|
||||
{
|
||||
PrintShaderInfoLog(geometryShader, "shader_geometry.log");
|
||||
error = "Geometry shader compilation error:\n\n" + compileError;
|
||||
glDeleteShader(geometryShader);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
program = glCreateProgram();
|
||||
|
||||
if(program > 0)
|
||||
{
|
||||
if(vertexShader > 0)
|
||||
glAttachShader(program, vertexShader);
|
||||
if(fragmentShader > 0)
|
||||
glAttachShader(program, fragmentShader);
|
||||
if(geometryShader > 0)
|
||||
glAttachShader(program, geometryShader);
|
||||
|
||||
glLinkProgram(program);
|
||||
if(!IsProgramLinked(program))
|
||||
{
|
||||
PrintProgramInfoLog(program, "shader_link.log");
|
||||
PrintProgramValidationLog(program, "shader_validation.log");
|
||||
glDeleteProgram(program);
|
||||
program = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
program = -1;
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
int Shader::CompileProgram(const byte* vs, const byte* fs, const byte* gs)
|
||||
{
|
||||
return CompileProgram((const char*) vs, (const char*) fs, (const char*) gs);
|
||||
}
|
||||
|
||||
int Shader::GetProgram()
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
String Shader::GetError()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
int Shader::GetUniformId(const char* var)
|
||||
{
|
||||
int n = uniforms.Find(var);
|
||||
if(n < 0)
|
||||
{
|
||||
int id = glGetUniformLocation(program, var);
|
||||
CheckGLError();
|
||||
if(id >= 0)
|
||||
uniforms.Add(var, id);
|
||||
return id;
|
||||
}
|
||||
else
|
||||
return uniforms[n];
|
||||
}
|
||||
|
||||
int Shader::GetAttributeId(const char* var)
|
||||
{
|
||||
int n = attributes.Find(var);
|
||||
if(n < 0)
|
||||
{
|
||||
int id = glGetAttribLocation(program, var);
|
||||
CheckGLError();
|
||||
if(id >= 0)
|
||||
attributes.Add(var, id);
|
||||
return id;
|
||||
}
|
||||
else
|
||||
return attributes[n];
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, float v)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform1f(id, v);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, bool v)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform1i(id, int(v));
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, int v)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform1i(id, v);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, float v0, float v1)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform2f(id, v0, v1);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, float v0, float v1, float v2)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform3f(id, v0, v1, v2);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, float v0, float v1, float v2, float v3)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
glUniform4f(id, v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const char* var, float* v, int size, int count)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
{
|
||||
if(size == 2)
|
||||
glUniform2fv(id, count, v);
|
||||
else if(size == 3)
|
||||
glUniform3fv(id, count, v);
|
||||
else if(size == 4)
|
||||
glUniform4fv(id, count, v);
|
||||
else if(size == 16)
|
||||
glUniformMatrix4fv(id, count, GL_FALSE, v);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetMatrixUniform(const char* var, float* v, int size, int count)
|
||||
{
|
||||
int id = GetUniformId(var);
|
||||
if(id >= 0)
|
||||
{
|
||||
if(size == 2)
|
||||
glUniform2fv(id, count, v);
|
||||
else if(size == 3)
|
||||
glUniform3fv(id, count, v);
|
||||
else if(size == 4)
|
||||
glUniform4fv(id, count, v);
|
||||
else if(size == 16)
|
||||
glUniformMatrix4fv(id, count, GL_FALSE, v);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::EnableAttribute(const char* var, bool b)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
{
|
||||
if(b)
|
||||
glEnableVertexAttribArray(id);
|
||||
else
|
||||
glDisableVertexAttribArray(id);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::DisableAttribute(const char* var)
|
||||
{
|
||||
EnableAttribute(var, false);
|
||||
}
|
||||
|
||||
void Shader::DisableAllAtrributes()
|
||||
{
|
||||
for(int i = 0; i < attributes.GetCount(); i++)
|
||||
{
|
||||
int id = attributes[i];
|
||||
if(id >= 0)
|
||||
glDisableVertexAttribArray(id);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetAttribute(const char* var, float v)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
glVertexAttrib1f(id, v);
|
||||
}
|
||||
|
||||
void Shader::SetAttribute(const char* var, float v0, float v1)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
glVertexAttrib2f(id, v0, v1);
|
||||
}
|
||||
|
||||
void Shader::SetAttribute(const char* var, float v0, float v1, float v2)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
glVertexAttrib3f(id, v0, v1, v2);
|
||||
}
|
||||
|
||||
void Shader::SetAttribute(const char* var, float v0, float v1, float v2, float v3)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
glVertexAttrib4f(id, v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
void Shader::SetAttribute(const char* var, float* v, int size)
|
||||
{
|
||||
int id = GetAttributeId(var);
|
||||
if(id >= 0)
|
||||
{
|
||||
if(size == 2)
|
||||
glVertexAttrib2fv(id, v);
|
||||
else if(size == 3)
|
||||
glVertexAttrib3fv(id, v);
|
||||
else if(size == 4)
|
||||
glVertexAttrib4fv(id, v);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::Start()
|
||||
{
|
||||
glUseProgram(program);
|
||||
CheckGLError();
|
||||
}
|
||||
|
||||
void Shader::Stop()
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void Shader::Release()
|
||||
{
|
||||
if(program >= 0)
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
Shader::Shader() : program(-1)
|
||||
{}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
65
rainbow/CoreGl/Shaders.h
Normal file
65
rainbow/CoreGl/Shaders.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef _CoreGl_Shaders_h_
|
||||
#define _CoreGl_Shaders_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
#include <Draw/Draw.h>
|
||||
#include "Gl.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class Shader
|
||||
{
|
||||
private:
|
||||
int program;
|
||||
String error;
|
||||
String compileError;
|
||||
String fragSrc;
|
||||
String vertSrc;
|
||||
String geomSrc;
|
||||
VectorMap<String, int> uniforms;
|
||||
VectorMap<String, int> attributes;
|
||||
|
||||
void PrintShaderInfoLog(GLuint obj, const char* fileName);
|
||||
void PrintProgramInfoLog(GLuint obj, const char* fileName);
|
||||
void PrintProgramValidationLog(GLuint obj, const char* fileName);
|
||||
bool CheckGLError();
|
||||
bool IsProgramCompiled(int program);
|
||||
bool IsProgramLinked(int program);
|
||||
|
||||
public:
|
||||
int GetUniformId(const char* var);
|
||||
int GetAttributeId(const char* var);
|
||||
|
||||
int CompileProgram(const char* vs, const char* fs, const char* gs = NULL);
|
||||
int CompileProgram(const byte* vs, const byte* fs, const byte* gs = NULL);
|
||||
int GetProgram();
|
||||
|
||||
void SetUniform(const char* var, float v);
|
||||
void SetUniform(const char* var, bool v);
|
||||
void SetUniform(const char* var, int v);
|
||||
void SetUniform(const char* var, float v0, float v1);
|
||||
void SetUniform(const char* var, float v0, float v1, float v2);
|
||||
void SetUniform(const char* var, float v0, float v1, float v2, float v3);
|
||||
void SetUniform(const char* var, float* v, int size, int count = 1);
|
||||
void SetMatrixUniform(const char* var, float* v, int size, int count = 1);
|
||||
|
||||
void EnableAttribute(const char* var, bool b = true);
|
||||
void DisableAttribute(const char* var);
|
||||
void DisableAllAtrributes();
|
||||
|
||||
void SetAttribute(const char* var, float v);
|
||||
void SetAttribute(const char* var, float v0, float v1);
|
||||
void SetAttribute(const char* var, float v0, float v1, float v2);
|
||||
void SetAttribute(const char* var, float v0, float v1, float v2, float v3);
|
||||
void SetAttribute(const char* var, float* v, int size);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
String GetError();
|
||||
void Release();
|
||||
|
||||
Shader();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
#endif
|
||||
149
rainbow/CoreGl/Top.cpp
Normal file
149
rainbow/CoreGl/Top.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
void TopWindow::SyncFrameRect(const Rect& r)
|
||||
{
|
||||
frame->SetClient(r);
|
||||
}
|
||||
|
||||
void TopWindow::DestroyFrame()
|
||||
{
|
||||
if(frame->IsOpen())
|
||||
frame->DestroyWnd();
|
||||
}
|
||||
|
||||
void TopWindow::GripResize()
|
||||
{
|
||||
frame->GripResize();
|
||||
}
|
||||
|
||||
void TopWindow::SyncSizeHints()
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle()
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncCaption()
|
||||
{
|
||||
GuiLock __;
|
||||
frame->title = title.ToString();
|
||||
frame->minsize = minsize;
|
||||
frame->close.Show(!noclosebox);
|
||||
frame->maximize.Show(maximizebox);
|
||||
frame->sizeable = sizeable;
|
||||
frame->RefreshLayout();
|
||||
frame->Refresh();
|
||||
frame->close <<= Proxy(WhenClose);
|
||||
frame->icon = icon;
|
||||
frame->Enable(IsEnabled());
|
||||
}
|
||||
|
||||
void TopWindow::State(int reason)
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncRect()
|
||||
{
|
||||
frame->SyncRect();
|
||||
Rect r = frame->GetClient();
|
||||
if(r != GetRect()) {
|
||||
SetRect(r);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindow::Open(Ctrl *owner)
|
||||
{
|
||||
GuiLock __;
|
||||
Rect r = GetRect();
|
||||
if(r.IsEmpty())
|
||||
SetRect(GetDefaultWindowRect());
|
||||
else
|
||||
if(r.left == 0 && r.top == 0)
|
||||
if(owner && center == 1)
|
||||
SetRect(owner->GetRect().CenterRect(r.GetSize()));
|
||||
else
|
||||
if(center)
|
||||
SetRect(GetWorkArea().CenterRect(r.GetSize()));
|
||||
frame->SetClient(GetRect());
|
||||
frame->window = this;
|
||||
frame->PopUp(owner, false, true);
|
||||
PopUp(frame, false, true);
|
||||
popup = false;
|
||||
SetRect(frame->GetClient());
|
||||
SyncCaption();
|
||||
if(state == MAXIMIZED)
|
||||
frame->Maximize();
|
||||
}
|
||||
|
||||
void TopWindow::Open()
|
||||
{
|
||||
Open(GetActiveCtrl());
|
||||
}
|
||||
|
||||
void TopWindow::OpenMain()
|
||||
{
|
||||
Open(NULL);
|
||||
}
|
||||
|
||||
void TopWindow::Minimize(bool effect)
|
||||
{
|
||||
// state = MINIMIZED;
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::FullScreen(bool b)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TopWindow::Maximize(bool effect)
|
||||
{
|
||||
state = MAXIMIZED;
|
||||
frame->Maximize();
|
||||
}
|
||||
|
||||
void TopWindow::Overlap(bool effect)
|
||||
{
|
||||
GuiLock __;
|
||||
state = OVERLAPPED;
|
||||
frame->Overlap();
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::TopMost(bool b, bool stay_top)
|
||||
{
|
||||
GuiLock __;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TopWindow::IsTopMost() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformConstruct()
|
||||
{
|
||||
frame = new TopWindowFrame;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformDestruct()
|
||||
{
|
||||
delete frame;
|
||||
}
|
||||
|
||||
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
16
rainbow/CoreGl/Top.h
Normal file
16
rainbow/CoreGl/Top.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//$ class TopWindow {
|
||||
public:
|
||||
virtual void State(int reason);
|
||||
|
||||
private:
|
||||
TopWindowFrame *frame;
|
||||
|
||||
void SyncRect();
|
||||
void SyncFrameRect(const Rect& r);
|
||||
void DestroyFrame();
|
||||
|
||||
friend class Ctrl;
|
||||
|
||||
public:
|
||||
void GripResize();
|
||||
//$ };
|
||||
209
rainbow/CoreGl/TopFrame.cpp
Normal file
209
rainbow/CoreGl/TopFrame.cpp
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
TopWindowFrame::TopWindowFrame()
|
||||
{
|
||||
close.SetImage(CoreGlImg::close());
|
||||
close.EdgeStyle();
|
||||
Add(close);
|
||||
maximize.SetImage(CoreGlImg::maximize());
|
||||
maximize.EdgeStyle();
|
||||
Add(maximize);
|
||||
maximize <<= THISBACK(ToggleMaximize);
|
||||
maximized = false;
|
||||
sizeable = false;
|
||||
holding = false;
|
||||
}
|
||||
|
||||
void TopWindowFrame::SyncRect()
|
||||
{
|
||||
if(maximized) {
|
||||
Size sz = screenRect.GetSize();
|
||||
if(GetRect().GetSize() != sz)
|
||||
SetRect(sz);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::Maximize()
|
||||
{
|
||||
if(!maximized && maximize.IsShown()) {
|
||||
maximized = true;
|
||||
overlapped = GetRect();
|
||||
SetRect(screenRect);
|
||||
maximize.SetImage(CoreGlImg::overlap());
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::Overlap()
|
||||
{
|
||||
if(maximized && maximize.IsShown()) {
|
||||
maximized = false;
|
||||
SetRect(overlapped);
|
||||
maximize.SetImage(CoreGlImg::maximize());
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::ToggleMaximize()
|
||||
{
|
||||
if(maximized)
|
||||
Overlap();
|
||||
else
|
||||
Maximize();
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::Margins() const
|
||||
{
|
||||
return maximized ? Rect(0, 0, 0, 0) : ChMargins(CoreGlImg::border());
|
||||
}
|
||||
|
||||
void TopWindowFrame::Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = Margins();
|
||||
int c = GetStdFontCy() + 4;
|
||||
ChPaintEdge(w, sz, CoreGlImg::border());
|
||||
Image img = window->IsForeground() ? CoreGlImg::title() : CoreGlImg::bgtitle();
|
||||
resources.Bind(img, Resources::FORCE_FILTERING | Resources::LINEAR_FILTERING);
|
||||
ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4, img);
|
||||
int tx = m.left + 2;
|
||||
int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown());
|
||||
if(!IsNull(icon)) {
|
||||
Image h = icon;
|
||||
if(h.GetWidth() > c || h.GetHeight() > c)
|
||||
h = Rescale(h, GetFitSize(h.GetSize(), Size(c)));
|
||||
w.DrawImage(tx, m.top + 2, h);
|
||||
tx += c;
|
||||
tcx -= c;
|
||||
}
|
||||
DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText());
|
||||
}
|
||||
|
||||
void TopWindowFrame::Layout()
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = Margins();
|
||||
int c = GetStdFontCy() + 4;
|
||||
int x = sz.cx - m.right;
|
||||
if(close.IsShown())
|
||||
close.SetRect(x -= c, m.top, c, c);
|
||||
if(maximize.IsShown())
|
||||
maximize.SetRect(x -= c, m.top, c, c);
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::GetClient() const
|
||||
{
|
||||
Rect r = GetRect();
|
||||
Rect m = Margins();
|
||||
r.left += m.left;
|
||||
r.right -= m.right;
|
||||
r.top += m.top;
|
||||
r.bottom -= m.bottom;
|
||||
r.top += GetStdFontCy() + 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::ComputeClient(Rect r)
|
||||
{
|
||||
Rect m = Margins();
|
||||
r.left -= m.left;
|
||||
r.right += m.right;
|
||||
r.top -= m.top;
|
||||
r.bottom += m.bottom;
|
||||
r.top -= GetStdFontCy() + 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
void TopWindowFrame::SetClient(Rect r)
|
||||
{
|
||||
SetRect(ComputeClient(r));
|
||||
}
|
||||
|
||||
Point TopWindowFrame::GetDragMode(Point p)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = ChMargins(CoreGlImg::border());
|
||||
Point dir;
|
||||
dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0;
|
||||
dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0;
|
||||
return dir;
|
||||
}
|
||||
|
||||
void TopWindowFrame::StartDrag()
|
||||
{
|
||||
if(maximized)
|
||||
return;
|
||||
if(!sizeable && (dir.x || dir.y))
|
||||
return;
|
||||
SetCapture();
|
||||
startrect = GetRect();
|
||||
startpos = GetMousePos();
|
||||
}
|
||||
|
||||
void TopWindowFrame::GripResize()
|
||||
{
|
||||
dir = Point(1, 1);
|
||||
StartDrag();
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
dir = GetDragMode(p);
|
||||
StartDrag();
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftDouble(Point p, dword keyflags)
|
||||
{
|
||||
ToggleMaximize();
|
||||
IgnoreMouseUp();
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
||||
void TopWindowFrame::MouseMove(Point, dword)
|
||||
{
|
||||
if(!HasCapture())
|
||||
return;
|
||||
Size msz = ComputeClient(minsize).GetSize();
|
||||
Point p = GetMousePos() - startpos;
|
||||
Rect r = startrect;
|
||||
if(dir.x == -1)
|
||||
r.left = min(r.left + p.x, startrect.right - msz.cx);
|
||||
if(dir.x == 1)
|
||||
r.right = max(r.right + p.x, startrect.left + msz.cx);
|
||||
if(dir.y == -1)
|
||||
r.top = min(r.top + p.y, startrect.bottom - msz.cy);
|
||||
if(dir.y == 1)
|
||||
r.bottom = max(r.bottom + p.y, startrect.top + msz.cy);
|
||||
if(dir.y == 0 && dir.x == 0)
|
||||
r.Offset(p);
|
||||
SetRect(r);
|
||||
}
|
||||
|
||||
Image TopWindowFrame::GetDragImage(Point dir)
|
||||
{
|
||||
static Image (*im[9])() = {
|
||||
Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft,
|
||||
Image::SizeTop, Image::Arrow, Image::SizeBottom,
|
||||
Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight,
|
||||
};
|
||||
return (*im[(dir.x + 1) * 3 + (dir.y + 1)])();
|
||||
}
|
||||
|
||||
Image TopWindowFrame::CursorImage(Point p, dword)
|
||||
{
|
||||
if(!sizeable)
|
||||
return Image::Arrow();
|
||||
return GetDragImage(HasCapture() ? dir : GetDragMode(p));
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
62
rainbow/CoreGl/TopFrame.h
Normal file
62
rainbow/CoreGl/TopFrame.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef _CoreGl_TopFrame_h_
|
||||
#define _CoreGl_TopFrame_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class TopWindowFrame : public Ctrl {
|
||||
public:
|
||||
virtual void Layout();
|
||||
virtual void Paint(Draw& w);
|
||||
virtual Image CursorImage(Point p, dword keyflags);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
virtual void LeftDouble(Point p, dword keyflags);
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual void MouseMove(Point p, dword keyflags);
|
||||
|
||||
private:
|
||||
Point dir;
|
||||
Point startpos;
|
||||
Rect startrect;
|
||||
|
||||
bool maximized;
|
||||
Rect overlapped;
|
||||
|
||||
bool holding;
|
||||
TimeCallback hold;
|
||||
|
||||
Point GetDragMode(Point p);
|
||||
Image GetDragImage(Point dragmode);
|
||||
void StartDrag();
|
||||
Rect Margins() const;
|
||||
Rect ComputeClient(Rect r);
|
||||
void Hold();
|
||||
|
||||
typedef TopWindowFrame CLASSNAME;
|
||||
|
||||
public:
|
||||
String title;
|
||||
Button close, maximize;
|
||||
Image icon;
|
||||
Size minsize;
|
||||
bool sizeable;
|
||||
TopWindow *window;
|
||||
|
||||
void SetTitle(const String& s) { title = s; Refresh(); }
|
||||
Rect GetClient() const;
|
||||
void SetClient(Rect r);
|
||||
void GripResize();
|
||||
|
||||
void Maximize();
|
||||
void Overlap();
|
||||
void ToggleMaximize();
|
||||
bool IsMaximized() const { return maximized; }
|
||||
void SyncRect();
|
||||
|
||||
TopWindowFrame();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
87
rainbow/CoreGl/Util.cpp
Normal file
87
rainbow/CoreGl/Util.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void DDRect(RGBA *t, int dir, const byte *pattern, int pos, int count)
|
||||
{
|
||||
while(count-- > 0) {
|
||||
byte p = pattern[7 & pos++];
|
||||
t->r ^= p;
|
||||
t->g ^= p;
|
||||
t->b ^= p;
|
||||
t += dir;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz, const byte *pattern, int animation)
|
||||
{
|
||||
if(cx <= 0 || cy <= 0)
|
||||
return;
|
||||
|
||||
/* Vector<Rect> rr = Intersection(clip, RectC(x, y, cx, cy));
|
||||
for(int i = 0; i < rr.GetCount(); i++) {
|
||||
Rect r = rr[i];
|
||||
if(horz)
|
||||
for(int y = r.top; y < r.bottom; y++)
|
||||
DDRect(framebuffer[y] + r.left, 1, pattern, r.left + animation, r.GetWidth());
|
||||
else
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
DDRect(framebuffer[r.top] + x, framebuffer.GetWidth(), pattern, r.top + animation, r.GetHeight());
|
||||
}*/
|
||||
|
||||
glColor4ub(255, 0, 0, 255);
|
||||
//glEnable(GL_LINE_STIPPLE);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x + cx, y + cy);
|
||||
//glVertex2i(10, 10);
|
||||
//glVertex2i(100, 100);
|
||||
glEnd();
|
||||
//glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
|
||||
void DragRectDraw0(const Vector<Rect>& clip, const Rect& rect, int n, const byte *pattern, int animation)
|
||||
{
|
||||
int hn = min(rect.GetHeight(), n);
|
||||
int vn = min(rect.GetWidth(), n);
|
||||
DrawLine(clip, rect.left, rect.top, rect.GetWidth(), hn, true, pattern, animation);
|
||||
DrawLine(clip, rect.left, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation);
|
||||
DrawLine(clip, rect.right - vn, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation);
|
||||
DrawLine(clip, rect.left + vn, rect.bottom - hn, rect.GetWidth() - 2 * vn, hn, true, pattern, animation);
|
||||
}
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation)
|
||||
{
|
||||
static byte solid[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
static byte normal[] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
static byte dashed[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
Point p = Ctrl::screenRect.TopLeft();
|
||||
Vector<Rect> pr;
|
||||
if(type & Ctrl::DRAWDRAGRECT_SCREEN) {
|
||||
pr.Add(Rect(Ctrl::screenRect.GetSize()));
|
||||
type &= ~Ctrl::DRAWDRAGRECT_SCREEN;
|
||||
p = Point(0, 0);
|
||||
}
|
||||
else
|
||||
//pr = Intersection(screenRect, clip.Offseted(p));
|
||||
pr.Add(clip.Offseted(p));
|
||||
const byte *pattern = type == DRAWDRAGRECT_DASHED ? dashed :
|
||||
type == DRAWDRAGRECT_NORMAL ? normal : solid;
|
||||
DragRectDraw0(pr, rect1.Offseted(p), n, pattern, animation);
|
||||
DragRectDraw0(pr, rect2.Offseted(p), n, pattern, animation);
|
||||
}
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
}
|
||||
|
||||
void FinishDragRect(Ctrl& q)
|
||||
{
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
658
rainbow/CoreGl/Wnd.cpp
Normal file
658
rainbow/CoreGl/Wnd.cpp
Normal file
|
|
@ -0,0 +1,658 @@
|
|||
#if defined(flagWINGL) || defined(flagLINUXGL)
|
||||
|
||||
#include "TopFrame.h"
|
||||
#include "ControlPanel.h"
|
||||
#include "Console.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) DLOG(x)
|
||||
#define LDUMP(x) DDUMP(x)
|
||||
#define LDUMPC(x) DDUMPC(x)
|
||||
|
||||
Ptr<Ctrl> Ctrl::desktop;
|
||||
Vector<Ctrl *> Ctrl::topctrl;
|
||||
InfoPanel Ctrl::infoPanel;
|
||||
Console Ctrl::console;
|
||||
float Ctrl::angle = 0.f;
|
||||
float Ctrl::scale = 1.f;
|
||||
float Ctrl::alpha = 255.f;
|
||||
Rect Ctrl::screenRect;
|
||||
bool Ctrl::screenReady = false;
|
||||
Point Ctrl::glCursorPos = Null;
|
||||
Image Ctrl::glCursorImage;
|
||||
Rect Ctrl::glCaretRect;
|
||||
int Ctrl::glCaretTm;
|
||||
int64 Ctrl::glEventLoop = 0;
|
||||
int64 Ctrl::glEndSessionLoop = 0;
|
||||
int Ctrl::PaintLock;
|
||||
|
||||
void GlLog(int line, const char* text, Color ink)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl::console.Log(line, text, ink);
|
||||
}
|
||||
|
||||
void GlLog(const char* text, Color ink)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl::console.Log(text, ink);
|
||||
}
|
||||
|
||||
void GlLogF(Color ink, const char* fmt, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(buffer, fmt, argptr);
|
||||
va_end(argptr);
|
||||
GlLog(buffer, ink);
|
||||
}
|
||||
|
||||
void GlLogF(const char* fmt, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(buffer, fmt, argptr);
|
||||
va_end(argptr);
|
||||
GlLog(buffer);
|
||||
}
|
||||
|
||||
void Ctrl::SetDesktop(Ctrl& q)
|
||||
{
|
||||
q.SetRect(screenRect.GetSize());
|
||||
q.SetOpen(true);
|
||||
q.StateH(OPEN);
|
||||
q.NewTop();
|
||||
desktop = &q;
|
||||
}
|
||||
|
||||
void Ctrl::SetWindowSize(Size sz)
|
||||
{
|
||||
screenRect = sz;
|
||||
if(desktop)
|
||||
desktop->SetRect(screenRect);
|
||||
}
|
||||
|
||||
void Ctrl::InitGl()
|
||||
{
|
||||
Ctrl::GlobalBackBuffer();
|
||||
Ctrl::InitTimer();
|
||||
ChStdSkin();
|
||||
static StaticRect x;
|
||||
x.Color(Cyan());
|
||||
SetDesktop(x);
|
||||
}
|
||||
|
||||
void Ctrl::EndSession()
|
||||
{
|
||||
GuiLock __;
|
||||
glEndSession = true;
|
||||
EndSessionLoopNo = EventLoopNo;
|
||||
}
|
||||
|
||||
void Ctrl::ExitGl()
|
||||
{
|
||||
TopWindow::ShutdownWindows();
|
||||
Ctrl::CloseTopCtrls();
|
||||
if(glEndSession)
|
||||
GlQuitSession();
|
||||
}
|
||||
|
||||
|
||||
int Ctrl::FindTopCtrl() const
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(this == topctrl[i])
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Ctrl::IsAlphaSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::IsCompositedGui()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<Ctrl *> Ctrl::GetTopCtrls()
|
||||
{
|
||||
Vector<Ctrl *> ctrl;
|
||||
if(desktop)
|
||||
ctrl.Add(desktop);
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(!dynamic_cast<TopWindowFrame *>(topctrl[i]))
|
||||
ctrl.Add(topctrl[i]);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetOwner()
|
||||
{
|
||||
GuiLock __;
|
||||
int q = FindTopCtrl();
|
||||
if(q > 0 && topctrl[q]->top) {
|
||||
Ctrl *x = topctrl[q]->top->owner_window;
|
||||
return dynamic_cast<TopWindowFrame *>(x) ? x->GetOwner() : x;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetActiveCtrl()
|
||||
{
|
||||
GuiLock __;
|
||||
if(focusCtrl == &infoPanel || focusCtrl == &console)
|
||||
return desktop;
|
||||
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
|
||||
}
|
||||
|
||||
// Vector<Callback> Ctrl::hotkey;
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Callback cb)
|
||||
{
|
||||
/* ASSERT(key >= K_DELTA);
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= MOD_ALT;
|
||||
if(key & K_SHIFT)
|
||||
mod |= MOD_SHIFT;
|
||||
if(key & K_CTRL)
|
||||
mod |= MOD_CONTROL;
|
||||
|
||||
return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
/* if(id >= 0 && id < hotkey.GetCount()) {
|
||||
UnregisterHotKey(NULL, id);
|
||||
hotkey[id].Clear();
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent()
|
||||
{
|
||||
return GlIsWaitingEvent();
|
||||
}
|
||||
|
||||
void Ctrl::SyncTopWindows()
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(topctrl[i]);
|
||||
if(w)
|
||||
w->SyncRect();
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvent(bool *quit)
|
||||
{
|
||||
ASSERT(IsMainThread());
|
||||
if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle())
|
||||
ReleaseCtrlCapture();
|
||||
if(GlProcessEvent(quit)) {
|
||||
SyncTopWindows();
|
||||
DefferedFocusSync();
|
||||
SyncCaret();
|
||||
return true;
|
||||
}
|
||||
else if(glDrawMode == DRAW_ON_IDLE && !Ctrl::painting)
|
||||
{
|
||||
GuiSleep(0);
|
||||
TimerProc(GetTickCount());
|
||||
SweepMkImageCache();
|
||||
DrawScreen();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::DrawScreen()
|
||||
{
|
||||
#ifdef flagWINGL
|
||||
if(hRC)
|
||||
#endif
|
||||
if(desktop && !painting) {
|
||||
screenReady = true;
|
||||
painting = true;
|
||||
resources.BindStatic();
|
||||
int64 t0 = GetHighTickCount();
|
||||
frameInfo.curr_tick_count = t0;
|
||||
desktop->ApplyLayout();
|
||||
desktop->ApplyTransform(TS_BEFORE_SCREEN);
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
topctrl[i]->ApplyLayout();
|
||||
topctrl[i]->ApplyTransform(TS_BEFORE_SCREEN);
|
||||
}
|
||||
Rect clip = desktop->GetRect();
|
||||
SystemDraw draw(clip.GetSize());
|
||||
infoPanel.Init(*desktop);
|
||||
infoPanel.Show(controlPanelActive);
|
||||
console.Init(*desktop);
|
||||
console.Show(consoleActive);
|
||||
draw.alpha = infoPanel.GetAlpha();
|
||||
draw.angle = infoPanel.GetAngle();
|
||||
draw.scale = infoPanel.GetScale();
|
||||
draw.ViewPort();
|
||||
draw.OrthogonalView();
|
||||
draw.Clear(true);
|
||||
screenFbo0.Bind();
|
||||
screenFbo0.Clear();
|
||||
desktop->ApplyTransform(TS_BEFORE_PAINT);
|
||||
desktop->CtrlPaint(draw, clip);
|
||||
screenFbo0.Unbind();
|
||||
draw.OrthogonalView();
|
||||
glDisable(GL_BLEND);
|
||||
RectF drawRect(0.f, 0.f, (float) screenRect.GetWidth(), (float) screenRect.GetHeight());
|
||||
float blur = SystemDraw::blurStrength;
|
||||
float gray = SystemDraw::grayStrength;
|
||||
if(blur > 0 || gray > 0)
|
||||
{
|
||||
float sigma = blur * 3.f;
|
||||
float gx = 1.0f / (sqrt(2.0f * float(M_PI)) * sigma);
|
||||
float gy = exp(-0.5f / (sigma * sigma));
|
||||
float gz = gy * gy;
|
||||
float blurSizeHorz = 1.f / (float) screenFbo0.width;
|
||||
float blurSizeVert = 1.f / (float) screenFbo0.height;
|
||||
blurProg.Start();
|
||||
blurProg.SetUniform("blurSize", blurSizeHorz);
|
||||
blurProg.SetUniform("gaussian", gx, gy, gz);
|
||||
blurProg.SetUniform("blurMultiplyVec", 1, 0);
|
||||
blurProg.SetUniform("blurStrength", blur);
|
||||
blurProg.SetUniform("grayStrength", gray);
|
||||
screenFbo1.Bind();
|
||||
draw.DrawTextureOp(drawRect, screenFbo0.texId, screenFbo0.width, screenFbo0.height, drawRect);
|
||||
screenFbo1.Unbind();
|
||||
|
||||
blurProg.SetUniform("blurSize", blurSizeVert);
|
||||
blurProg.SetUniform("blurMultiplyVec", 0, 1);
|
||||
blurProg.SetUniform("blurStrength", blur);
|
||||
blurProg.SetUniform("grayStrength", gray);
|
||||
draw.ApplyTransforms();
|
||||
draw.DrawTextureOp(drawRect, screenFbo1.texId, screenFbo1.width, screenFbo1.height, drawRect);
|
||||
blurProg.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
draw.ApplyTransforms();
|
||||
draw.DrawTextureOp(drawRect, screenFbo0.texId, screenFbo0.width, screenFbo0.height, drawRect);
|
||||
//screenFbo0.BlitToScreen();
|
||||
}
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
Ctrl* tq = topctrl[i];
|
||||
if(tq == &infoPanel || tq == &console)
|
||||
continue;
|
||||
Rect r = tq->GetRect();
|
||||
tq->ApplyTransform(TS_BEFORE_PAINT);
|
||||
draw.Offset(r.left, r.top);
|
||||
tq->CtrlPaint(draw, clip);
|
||||
draw.End();
|
||||
tq->ApplyTransform(TS_AFTER_PAINT);
|
||||
}
|
||||
|
||||
CursorSync(draw);
|
||||
|
||||
desktop->PostPaint(draw);
|
||||
desktop->ApplyTransform(TS_AFTER_PAINT);
|
||||
|
||||
glLoadIdentity();
|
||||
#if CLIP_MODE == 2
|
||||
//glDisable(GL_STENCIL_TEST);
|
||||
#endif
|
||||
draw.ImageColoring();
|
||||
draw.alpha = 255.f;
|
||||
if(controlPanelActive)
|
||||
{
|
||||
draw.Offset(infoPanel.GetRect().TopLeft());
|
||||
infoPanel.CtrlPaint(draw, clip);
|
||||
draw.End();
|
||||
}
|
||||
if(consoleActive)
|
||||
{
|
||||
draw.Offset(console.GetRect().TopLeft());
|
||||
console.CtrlPaint(draw, clip);
|
||||
draw.End();
|
||||
}
|
||||
#if CLIP_MODE == 2
|
||||
//glEnable(GL_STENCIL_TEST);
|
||||
#endif
|
||||
MouseSync(draw);
|
||||
#ifdef flagWINGL
|
||||
SwapBuffers(hDC);
|
||||
#endif
|
||||
#ifdef flagLINUXGL
|
||||
glXSwapBuffers(dpy, win);
|
||||
#endif
|
||||
int64 t1 = GetHighTickCount();
|
||||
frameInfo.frame_time = t1 - t0;
|
||||
frameInfo.frame_factor = frameInfo.frame_time * frameInfo.frame_skip / 1000.f;
|
||||
frameInfo.fps = frameInfo.frame_time > 0.f ? 1000.f / (float)frameInfo.frame_time : 0.f;
|
||||
//LOGF("ft: %d, t0: %d, t1: %d\n", frameInfo.frame_time, t0, t1);
|
||||
painting = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvents(bool *quit)
|
||||
{
|
||||
if(!ProcessEvent(quit))
|
||||
return false;
|
||||
while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop()));
|
||||
if(glDrawMode == DRAW_ON_TIMER)
|
||||
{
|
||||
TimerProc(GetTickCount());
|
||||
SweepMkImageCache();
|
||||
DrawScreen();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ctrl::EventLoop(Ctrl *ctrl)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT(LoopLevel == 0 || ctrl);
|
||||
LoopLevel++;
|
||||
Ptr<Ctrl> ploop;
|
||||
if(ctrl) {
|
||||
ploop = LoopCtrl;
|
||||
LoopCtrl = ctrl;
|
||||
ctrl->inloop = true;
|
||||
}
|
||||
|
||||
bool quit = false;
|
||||
int64 loopno = ++EventLoopNo;
|
||||
ProcessEvents(&quit);
|
||||
while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()))
|
||||
{
|
||||
SyncCaret();
|
||||
//if(glDrawMode == DRAW_ON_TIMER)
|
||||
// GuiSleep(20);
|
||||
ProcessEvents(&quit);
|
||||
}
|
||||
|
||||
if(ctrl)
|
||||
LoopCtrl = ploop;
|
||||
LoopLevel--;
|
||||
}
|
||||
|
||||
void Ctrl::GuiSleep(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
int level = LeaveGuiMutexAll();
|
||||
GlSleep(ms);
|
||||
EnterGuiMutex(level);
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWndScreenRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
return GetRect();
|
||||
}
|
||||
|
||||
void Ctrl::WndShow(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate()
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndOpen() const {
|
||||
GuiLock __;
|
||||
return FindTopCtrl() >= 0 || this == desktop;
|
||||
}
|
||||
|
||||
void Ctrl::SetAlpha(byte alpha)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea() const
|
||||
{
|
||||
GuiLock __;
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
void Ctrl::GetWorkArea(Array<Rect>& rc)
|
||||
{
|
||||
GuiLock __;
|
||||
//Array<Rect> r;
|
||||
rc.Add(screenRect.GetSize());
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualWorkArea()
|
||||
{
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea(Point pt)
|
||||
{
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualScreenArea()
|
||||
{
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryWorkArea()
|
||||
{
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryScreenArea()
|
||||
{
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdDelay()
|
||||
{
|
||||
GuiLock __;
|
||||
return 500;
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdSpeed()
|
||||
{
|
||||
GuiLock __;
|
||||
return 1000 / 32;
|
||||
}
|
||||
|
||||
void Ctrl::DestroyWnd()
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i]->top && topctrl[i]->top->owner_window == this)
|
||||
topctrl[i]->WndDestroy();
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0) {
|
||||
topctrl.Remove(q);
|
||||
}
|
||||
if(top) {
|
||||
delete top;
|
||||
top = NULL;
|
||||
}
|
||||
isopen = false;
|
||||
TopWindow *win = dynamic_cast<TopWindow *>(this);
|
||||
if(win)
|
||||
win->DestroyFrame();
|
||||
}
|
||||
|
||||
void Ctrl::WndDestroy()
|
||||
{
|
||||
DestroyWnd();
|
||||
if(topctrl.GetCount())
|
||||
topctrl.Top()->ActivateWnd();
|
||||
}
|
||||
|
||||
void Ctrl::PutForeground()
|
||||
{
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0) {
|
||||
topctrl.Remove(q);
|
||||
topctrl.Add(this);
|
||||
}
|
||||
Vector< Ptr<Ctrl> > fw;
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i] && topctrl[i]->top && topctrl[i]->top->owner_window == this && topctrl[i] != this)
|
||||
fw.Add(topctrl[i]);
|
||||
for(int i = 0; i < fw.GetCount(); i++)
|
||||
if(fw[i])
|
||||
fw[i]->PutForeground();
|
||||
}
|
||||
|
||||
void Ctrl::SetWndForeground()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsOpen());
|
||||
if(IsWndForeground())
|
||||
return;
|
||||
Ctrl *to = this;
|
||||
while(to->top && to->top->owner_window)
|
||||
to = to->top->owner_window;
|
||||
to->PutForeground();
|
||||
if(this != focusCtrl)
|
||||
ActivateWnd();
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndForeground() const
|
||||
{
|
||||
GuiLock __;
|
||||
bool b = false;
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
const TopWindow *tw = dynamic_cast<const TopWindow *>(topctrl[i]);
|
||||
if(tw)
|
||||
b = tw == this;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void Ctrl::WndEnable(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndFocus() const
|
||||
{
|
||||
GuiLock __;
|
||||
return focusCtrl && focusCtrl->GetTopCtrl() == this;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndCapture()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::ReleaseWndCapture()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndCapture() const
|
||||
{
|
||||
GuiLock __;
|
||||
return captureCtrl && captureCtrl->GetTopCtrl() == this;
|
||||
}
|
||||
|
||||
void Ctrl::WndInvalidateRect(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
//::InvalidateRect(glHwnd, NULL, false);
|
||||
}
|
||||
|
||||
void Ctrl::WndSetPos(const Rect& rect)
|
||||
{
|
||||
GuiLock __;
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(this);
|
||||
if(w)
|
||||
w->SyncFrameRect(rect);
|
||||
SetWndRect(rect);
|
||||
}
|
||||
|
||||
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
|
||||
{
|
||||
ASSERT(!IsChild() && !IsOpen() && FindTopCtrl() < 0);
|
||||
NewTop();
|
||||
if(owner) {
|
||||
Ctrl *owner_window = owner->GetTopWindow();
|
||||
if(!owner_window)
|
||||
owner_window = owner->GetTopCtrl();
|
||||
ASSERT(owner_window->IsOpen());
|
||||
if(owner_window != desktop) {
|
||||
owner_window->SetForeground();
|
||||
top->owner_window = owner_window;
|
||||
}
|
||||
}
|
||||
topctrl.Add(this);
|
||||
popup = isopen = true;
|
||||
StateH(OPEN);
|
||||
if(activate) SetFocusWnd();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetDefaultWindowRect() {
|
||||
GuiLock __;
|
||||
int ii = 0;
|
||||
Size sz = screenRect.GetSize();
|
||||
Rect rect = sz;
|
||||
rect.Deflate(sz / 8);
|
||||
rect.Offset(Point(sz) / 16 * (ii % 8));
|
||||
return rect;
|
||||
}
|
||||
|
||||
Vector<WString> SplitCmdLine__(const char *cmd)
|
||||
{
|
||||
Vector<WString> out;
|
||||
while(*cmd)
|
||||
if((byte)*cmd <= ' ')
|
||||
cmd++;
|
||||
else if(*cmd == '\"') {
|
||||
WString quoted;
|
||||
while(*++cmd && (*cmd != '\"' || *++cmd == '\"'))
|
||||
quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString());
|
||||
out.Add(quoted);
|
||||
}
|
||||
else {
|
||||
const char *begin = cmd;
|
||||
while((byte)*cmd > ' ')
|
||||
cmd++;
|
||||
out.Add(String(begin, cmd).ToWString());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
15483
rainbow/CoreGl/glew.c
Normal file
15483
rainbow/CoreGl/glew.c
Normal file
File diff suppressed because it is too large
Load diff
15507
rainbow/CoreGl/glew.h
Normal file
15507
rainbow/CoreGl/glew.h
Normal file
File diff suppressed because it is too large
Load diff
1568
rainbow/CoreGl/glxew.h
Normal file
1568
rainbow/CoreGl/glxew.h
Normal file
File diff suppressed because it is too large
Load diff
4
rainbow/CoreGl/init
Normal file
4
rainbow/CoreGl/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _CoreGl_icpp_init_stub
|
||||
#define _CoreGl_icpp_init_stub
|
||||
#include "Painter/init"
|
||||
#endif
|
||||
1361
rainbow/CoreGl/wglew.h
Normal file
1361
rainbow/CoreGl/wglew.h
Normal file
File diff suppressed because it is too large
Load diff
10
rainbow/DevDraw/DevDraw.upp
Normal file
10
rainbow/DevDraw/DevDraw.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Draw,
|
||||
Gtk;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI GTK";
|
||||
|
||||
5
rainbow/DevDraw/init
Normal file
5
rainbow/DevDraw/init
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _DevDraw_icpp_init_stub
|
||||
#define _DevDraw_icpp_init_stub
|
||||
#include "Draw/init"
|
||||
#include "Gtk/init"
|
||||
#endif
|
||||
102
rainbow/DevDraw/main.cpp
Normal file
102
rainbow/DevDraw/main.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
#include <RichEdit/RichEdit.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
void TestDraw(Draw& w)
|
||||
{
|
||||
w.DrawRect(0, 0, 10000, 10000, WhiteGray());
|
||||
w.DrawRect(0, 0, 100, 100, Yellow());
|
||||
|
||||
w.DrawLine(10, 40, 400, 20, 3, Blue());
|
||||
|
||||
w.DrawImage(0, 0, CtrlImg::exclamation());
|
||||
|
||||
w.Clipoff(50, 50, 30, 30);
|
||||
w.DrawImage(0, 0, CtrlImg::exclamation());
|
||||
w.End();
|
||||
|
||||
w.DrawImage(50, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10));
|
||||
|
||||
w.DrawImage(150, 50, CtrlImg::exclamation(), Red());
|
||||
w.DrawImage(150, 50 + 32, CtrlImg::exclamation(), RectC(24, 24, 10, 10), Red());
|
||||
|
||||
// w.DrawText(20, 20, "Hello GTK!", Roman(50));
|
||||
|
||||
|
||||
w.Offset(150, 50);
|
||||
const char *text = "Programming is fun";
|
||||
Font fnt(Roman(60));
|
||||
FontInfo fi = fnt.Info();
|
||||
int x = 0;
|
||||
Vector<int> dx;
|
||||
for(const char *s = text; *s; s++) {
|
||||
int width = fi[*s];
|
||||
w.DrawRect(x, 0, width - 1, fi.GetAscent(), Color(255, 255, 200));
|
||||
w.DrawRect(x, fi.GetAscent(), width - 1, fi.GetDescent(), Color(255, 200, 255));
|
||||
w.DrawRect(x + width - 1, 0, 1, fi.GetHeight(), Black());
|
||||
dx.Add(width + 4);
|
||||
x += width;
|
||||
}
|
||||
w.DrawRect(0, 0, 4, 4, Black());
|
||||
w.DrawText(0, 0, text, fnt);
|
||||
w.DrawText(0, 70, text, fnt, Blue(), dx.GetCount(), dx.Begin());
|
||||
|
||||
w.DrawRect(50, 400, 2, 2, Black());
|
||||
w.DrawText(50, 400, 200, "Angled text", Arial(50).Underline(), Red());
|
||||
|
||||
w.DrawRect(600, 400, 2, 2, Black());
|
||||
w.DrawText(600, 400, 1000, "Angled text", Arial(50).Underline(), Black());
|
||||
w.End();
|
||||
}
|
||||
|
||||
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
SystemDraw w(gdk_cairo_create(widget->window));
|
||||
|
||||
TestDraw(w);
|
||||
|
||||
cairo_destroy(w);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
Ctrl myapp;
|
||||
|
||||
{
|
||||
ImageDraw w(1000, 1000);
|
||||
TestDraw(w);
|
||||
PNGEncoder().SaveFile("/home/cxl/test.png", w);
|
||||
}
|
||||
|
||||
{
|
||||
ImageDraw w(1000, 1000);
|
||||
TestDraw(w);
|
||||
for(int i = 0; i < 100; i++)
|
||||
w.Alpha().DrawRect(i * 10, 0, 10, 1000, GrayColor(255 - i));
|
||||
PNGEncoder().SaveFile("/home/cxl/test_alpha.png", w);
|
||||
}
|
||||
|
||||
GtkWidget *window;
|
||||
|
||||
// window = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_window_set_default_size((GtkWindow *)window, 1000, 600);
|
||||
|
||||
GtkWidget *darea = gtk_drawing_area_new();
|
||||
gtk_container_add(GTK_CONTAINER (window), darea);
|
||||
|
||||
|
||||
gtk_widget_set_events(darea, 0xffffffff);
|
||||
g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), &myapp);
|
||||
// g_signal_connect(window, "expose-event", G_CALLBACK(on_expose_event), NULL);
|
||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
Ctrl::EventLoop(&myapp);
|
||||
// gtk_main();
|
||||
}
|
||||
11
rainbow/DrawDragRect/DrawDragRect.upp
Normal file
11
rainbow/DrawDragRect/DrawDragRect.upp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
uses
|
||||
CtrlLib,
|
||||
Framebuffer,
|
||||
WinFb;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI WINFB";
|
||||
|
||||
6
rainbow/DrawDragRect/init
Normal file
6
rainbow/DrawDragRect/init
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _DrawDragRect_icpp_init_stub
|
||||
#define _DrawDragRect_icpp_init_stub
|
||||
#include "CtrlLib/init"
|
||||
#include "Framebuffer/init"
|
||||
#include "WinFb/init"
|
||||
#endif
|
||||
87
rainbow/DrawDragRect/main.cpp
Normal file
87
rainbow/DrawDragRect/main.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
#include <RichEdit/RichEdit.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
void DDRect(RGBA *t, int dir, const byte *pattern, int pos, int count)
|
||||
{
|
||||
while(count-- > 0) {
|
||||
byte p = pattern[7 & pos++];
|
||||
*t->r ^= p;
|
||||
*t->g ^= p;
|
||||
*t->b ^= p;
|
||||
t += dir;
|
||||
}
|
||||
}
|
||||
|
||||
struct App : public Ctrl {
|
||||
uint64 pattern;
|
||||
int pos;
|
||||
int a;
|
||||
int dir;
|
||||
|
||||
void Paint(Draw& w)
|
||||
{
|
||||
DDUMP(pattern);
|
||||
Size sz = GetSize();
|
||||
w.DrawRect(sz, White());
|
||||
DrawDragRect((SystemDraw&)w,
|
||||
Rect(0, 0, 0, 0),
|
||||
RectC(10, 10, a, a / 3),
|
||||
Size(800, 600),
|
||||
1,
|
||||
Black(),
|
||||
pattern);
|
||||
}
|
||||
|
||||
virtual Image CursorImage(Point p, dword keyflags) {
|
||||
Animate();
|
||||
return Image::Arrow();
|
||||
}
|
||||
|
||||
|
||||
void Animate() {
|
||||
pattern = I64(0xf0f0) >> (pos++ & 7);
|
||||
if(Random() % 100 == 0)
|
||||
dir = (int)Random() % 3 - 1;
|
||||
a += dir;
|
||||
if(a < 0) {
|
||||
a = 0;
|
||||
dir = -dir;
|
||||
}
|
||||
if(a > 1000) {
|
||||
a = 1000;
|
||||
dir = -dir;
|
||||
}
|
||||
// if(++a > 900)
|
||||
// a = 0;
|
||||
DrawDragRect(*this,
|
||||
Rect(0, 0, 0, 0),
|
||||
RectC(10, 10, a, a / 3),
|
||||
Size(800, 600),
|
||||
1,
|
||||
Black(),
|
||||
pattern);
|
||||
PostCallback(THISBACK(Animate));
|
||||
}
|
||||
|
||||
typedef App CLASSNAME;
|
||||
|
||||
App()
|
||||
{
|
||||
pattern = I64(9732030564846854595);
|
||||
pos = 0;
|
||||
a = 200;
|
||||
dir = 1;
|
||||
// PostCallback(THISBACK(Animate));
|
||||
SetCaret(0, 0, 20, 20);
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
App app;
|
||||
Ctrl::SetDesktop(app);
|
||||
app.SetFocus();
|
||||
Ctrl::EventLoop();
|
||||
}
|
||||
236
rainbow/Events/Events.cpp
Normal file
236
rainbow/Events/Events.cpp
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
class App : public TopWindow {
|
||||
public:
|
||||
typedef App CLASSNAME;
|
||||
ArrayCtrl log;
|
||||
|
||||
void Log(const String& s)
|
||||
{
|
||||
log.Add(s);
|
||||
log.GoEnd();
|
||||
}
|
||||
|
||||
virtual void Activate()
|
||||
{
|
||||
Log("Activate");
|
||||
}
|
||||
|
||||
virtual void Deactivate()
|
||||
{
|
||||
Log("Deactivate");
|
||||
}
|
||||
|
||||
virtual Image FrameMouseEvent(int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
if(event != CURSORIMAGE)
|
||||
Log(Format("FrameMouseEvent(%d, Point(%d, %d), %d, %x)",
|
||||
event, p.x, p.y, zdelta, (int)keyflags));
|
||||
return TopWindow::FrameMouseEvent(event, p, zdelta, keyflags);
|
||||
}
|
||||
|
||||
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
if(event != CURSORIMAGE)
|
||||
Log(Format("MouseEvent(%d, Point(%d, %d), %d, %x)",
|
||||
event, p.x, p.y, zdelta, (int)keyflags));
|
||||
return TopWindow::MouseEvent(event, p, zdelta, keyflags);
|
||||
}
|
||||
|
||||
virtual void MouseEnter(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MouseEnter(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MouseMove(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("LeftDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
SetFocus();
|
||||
}
|
||||
|
||||
virtual void LeftDouble(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("LeftDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftTriple(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("LeftTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftDrag(Point p, dword keyflags) {
|
||||
Log(Format("LeftDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftHold(Point p, dword keyflags) {
|
||||
Log(Format("LeftHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftRepeat(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("LeftRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("LeftUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightDown(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("RightDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightDouble(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("RightDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightTriple(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("RightTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightDrag(Point p, dword keyflags) {
|
||||
Log(Format("RightDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightHold(Point p, dword keyflags) {
|
||||
Log(Format("RightHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightRepeat(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("RightRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void RightUp(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("RightUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleDown(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MiddleDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleDouble(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MiddleDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleTriple(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MiddleTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleDrag(Point p, dword keyflags) {
|
||||
Log(Format("MiddleDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleHold(Point p, dword keyflags) {
|
||||
Log(Format("MiddleHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleRepeat(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MiddleRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MiddleUp(Point p, dword keyflags)
|
||||
{
|
||||
Log(Format("MiddleUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MouseWheel(Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
Log(Format("MouseWheel(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags));
|
||||
}
|
||||
|
||||
virtual void MouseLeave()
|
||||
{
|
||||
Log("MouseLeave");
|
||||
}
|
||||
|
||||
virtual Image CursorImage(Point p, dword keyflags)
|
||||
{
|
||||
return keyflags & K_CTRL ? CtrlImg::swap_color_cursor() : Image::Arrow();
|
||||
}
|
||||
|
||||
virtual bool Key(dword key, int count)
|
||||
{
|
||||
Log(Format("Key(%x, %d) ", (int)key, count) + GetKeyDesc(key));
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool WKey(dword key, int count)
|
||||
{
|
||||
Log(Format("WKey(%x, %d) ", (int)key, count) + GetKeyDesc(key));
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void GotFocus()
|
||||
{
|
||||
Log("GotFocus");
|
||||
}
|
||||
|
||||
virtual void LostFocus()
|
||||
{
|
||||
Log("LostFocus");
|
||||
}
|
||||
|
||||
virtual bool HotKey(dword key)
|
||||
{
|
||||
Log(Format("HotKey(%x) ", (int)key) + GetKeyDesc(key));
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ChildGotFocus()
|
||||
{
|
||||
Log("ChildGotFocus");
|
||||
}
|
||||
|
||||
virtual void ChildLostFocus()
|
||||
{
|
||||
Log("ChildLostFocus");
|
||||
}
|
||||
|
||||
virtual void Layout()
|
||||
{
|
||||
Log("Layout");
|
||||
}
|
||||
|
||||
void OnTimer()
|
||||
{
|
||||
Log("Timer");
|
||||
}
|
||||
|
||||
App()
|
||||
{
|
||||
SetFrame(InsetFrame());
|
||||
AddFrame(InsetFrame());
|
||||
AddFrame(InsetFrame());
|
||||
AddFrame(InsetFrame());
|
||||
log.AddColumn("");
|
||||
log.NoHeader();
|
||||
Add(log.HSizePos().BottomPos(0, 200));
|
||||
SetTimeCallback(-1000, THISBACK(OnTimer));
|
||||
}
|
||||
|
||||
~App()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
App().Run();
|
||||
}
|
||||
29
rainbow/Events/Events.upp
Normal file
29
rainbow/Events/Events.upp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
description "Demonstration of basic input events";
|
||||
|
||||
uses
|
||||
CtrlLib;
|
||||
|
||||
uses(SKELETON) Skeleton;
|
||||
|
||||
uses(WINALT) WinAlt;
|
||||
|
||||
uses(WINFB) WinFb;
|
||||
|
||||
uses(LINUXFB) LinuxFb;
|
||||
|
||||
uses(SDLFB) SDLFb;
|
||||
|
||||
uses(WINGL) WinGl;
|
||||
|
||||
file
|
||||
Events.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI SKELETON",
|
||||
"" = "GUI WINALT",
|
||||
"" = "GUI WINFB",
|
||||
"" = "GUI LINUXFB",
|
||||
"" = "GUI SDLFB",
|
||||
"" = "GUI WINGL",
|
||||
"" = "GUI";
|
||||
|
||||
17
rainbow/Framebuffer/After.h
Normal file
17
rainbow/Framebuffer/After.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
class ViewDraw : public SystemDraw {
|
||||
public:
|
||||
ViewDraw(Ctrl *ctrl);
|
||||
~ViewDraw();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
class ViewDraw : public SystemDraw {
|
||||
Vector<Rect> dummy;
|
||||
public:
|
||||
ViewDraw(Ctrl *) : SystemDraw(Ctrl::framebuffer, dummy) { dummy.Add(Rect(10, 10, 100, 100)); }
|
||||
};
|
||||
*/
|
||||
class DHCtrl : Ctrl {};
|
||||
|
||||
#include FRAMEBUFFER_INCLUDE
|
||||
21
rainbow/Framebuffer/ChSysInit.cpp
Normal file
21
rainbow/Framebuffer/ChSysInit.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void ChSysInit()
|
||||
{
|
||||
CtrlImg::Reset();
|
||||
CtrlsImg::Reset();
|
||||
ChReset();
|
||||
}
|
||||
|
||||
void ChHostSkin()
|
||||
{
|
||||
ChSysInit();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
238
rainbow/Framebuffer/Clip.cpp
Normal file
238
rainbow/Framebuffer/Clip.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
static VectorMap<String, ClipData> fbClipboard;
|
||||
|
||||
void ClearClipboard()
|
||||
{
|
||||
GuiLock __;
|
||||
fbClipboard.Clear();
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&))
|
||||
{
|
||||
GuiLock __;
|
||||
ClipData& cd = fbClipboard.GetAdd(format);
|
||||
cd.data = data;
|
||||
cd.render = render;
|
||||
}
|
||||
|
||||
static String sRawRender(const Value& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const String& data)
|
||||
{
|
||||
GuiLock __;
|
||||
AppendClipboard(format, data, sRawRender);
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const byte *data, int length)
|
||||
{
|
||||
GuiLock __;
|
||||
AppendClipboard(format, String(data, length));
|
||||
}
|
||||
|
||||
String ReadClipboard(const char *format)
|
||||
{
|
||||
GuiLock __;
|
||||
int q = fbClipboard.Find(format);
|
||||
return q >= 0 ? (*fbClipboard[q].render)(fbClipboard[q].data) : String();
|
||||
}
|
||||
|
||||
void AppendClipboardText(const String& s)
|
||||
{
|
||||
AppendClipboard("text", ToSystemCharset(s));
|
||||
}
|
||||
|
||||
void AppendClipboardUnicodeText(const WString& s)
|
||||
{
|
||||
AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength());
|
||||
}
|
||||
|
||||
const char *ClipFmtsText()
|
||||
{
|
||||
return "wtext;text";
|
||||
}
|
||||
|
||||
String GetString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.Accept("wtext")) {
|
||||
String s = ~clip;
|
||||
return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString();
|
||||
}
|
||||
if(clip.IsAvailable("text"))
|
||||
return ~clip;
|
||||
return Null;
|
||||
}
|
||||
|
||||
WString GetWString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.Accept("wtext")) {
|
||||
String s = ~clip;
|
||||
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
|
||||
}
|
||||
if(clip.IsAvailable("text"))
|
||||
return (~clip).ToWString();
|
||||
return Null;
|
||||
}
|
||||
|
||||
|
||||
bool AcceptText(PasteClip& clip)
|
||||
{
|
||||
return clip.Accept(ClipFmtsText());
|
||||
}
|
||||
|
||||
static String sText(const Value& data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static String sWText(const Value& data)
|
||||
{
|
||||
return Unicode__(WString(data));
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const String& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(text, sText));
|
||||
data.GetAdd("wtext", ClipData(text, sWText));
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const WString& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(text, sText));
|
||||
data.GetAdd("wtext", ClipData(text, sWText));
|
||||
}
|
||||
|
||||
String GetTextClip(const WString& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return text.ToString();
|
||||
if(fmt == "wtext")
|
||||
return Unicode__(text);
|
||||
return Null;
|
||||
}
|
||||
|
||||
String GetTextClip(const String& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return text;
|
||||
if(fmt == "wtext")
|
||||
return Unicode__(text.ToWString());
|
||||
return Null;
|
||||
}
|
||||
|
||||
String ReadClipboardText()
|
||||
{
|
||||
String w = ReadClipboard("text");
|
||||
return w.GetCount() ? w : ReadClipboardUnicodeText().ToString();
|
||||
}
|
||||
|
||||
WString ReadClipboardUnicodeText()
|
||||
{
|
||||
String w = ReadClipboard("wtext");
|
||||
if(w.GetCount())
|
||||
return WString((const wchar *)~w, w.GetLength() / 2);
|
||||
return ReadClipboard("text").ToWString();
|
||||
}
|
||||
|
||||
bool IsClipboardAvailable(const char *id)
|
||||
{
|
||||
return fbClipboard.Find(id) >= 0;
|
||||
}
|
||||
|
||||
bool IsClipboardAvailableText()
|
||||
{
|
||||
return IsClipboardAvailable("text") || IsClipboardAvailable("wtext");
|
||||
}
|
||||
|
||||
const char *ClipFmtsImage()
|
||||
{
|
||||
static const char *q;
|
||||
ONCELOCK {
|
||||
static String s = "dib;" + ClipFmt<Image>();
|
||||
q = s;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
bool AcceptImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
return clip.Accept(ClipFmtsImage());
|
||||
}
|
||||
|
||||
Image GetImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Image m;
|
||||
if(Accept<Image>(clip)) {
|
||||
LoadFromString(m, ~clip);
|
||||
if(!m.IsEmpty())
|
||||
return m;
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
Image ReadClipboardImage()
|
||||
{
|
||||
GuiLock __;
|
||||
PasteClip d = Ctrl::Clipboard();
|
||||
return GetImage(d);
|
||||
}
|
||||
|
||||
String sImage(const Value& image)
|
||||
{
|
||||
Image img = image;
|
||||
return StoreAsString(const_cast<Image&>(img));
|
||||
}
|
||||
|
||||
String GetImageClip(const Image& img, const String& fmt)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.IsEmpty()) return Null;
|
||||
if(fmt == ClipFmt<Image>())
|
||||
return sImage(img);
|
||||
return Null;
|
||||
}
|
||||
|
||||
void AppendClipboardImage(const Image& img)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.IsEmpty()) return;
|
||||
AppendClipboard(ClipFmt<Image>(), img, sImage);
|
||||
}
|
||||
|
||||
bool AcceptFiles(PasteClip& clip)
|
||||
{
|
||||
if(clip.Accept("files")) {
|
||||
clip.SetAction(DND_COPY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAvailableFiles(PasteClip& clip)
|
||||
{
|
||||
return clip.IsAvailable("files");
|
||||
}
|
||||
|
||||
Vector<String> GetFiles(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Vector<String> f;
|
||||
return f;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
81
rainbow/Framebuffer/Ctrl.cpp
Normal file
81
rainbow/Framebuffer/Ctrl.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Ctrl::GuiPlatformConstruct()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformRemove()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformGetTopRect(Rect& r) const
|
||||
{
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformSetFullRefreshSpecial()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
}
|
||||
|
||||
String GuiPlatformGetKeyDesc(dword key)
|
||||
{
|
||||
return Null;
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformSelection(PasteClip&)
|
||||
{
|
||||
}
|
||||
|
||||
void GuiPlatformAdjustDragImage(ImageBuffer&)
|
||||
{
|
||||
}
|
||||
|
||||
bool GuiPlatformHasSizeGrip()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiPlatformGripResize(TopWindow *q)
|
||||
{
|
||||
q->GripResize();
|
||||
}
|
||||
|
||||
Color GuiPlatformGetScreenPixel(int x, int y)
|
||||
{
|
||||
return Ctrl::GetFrameBuffer()[y][x];
|
||||
}
|
||||
|
||||
void GuiPlatformAfterMenuPopUp()
|
||||
{
|
||||
}
|
||||
|
||||
String Ctrl::Name() const {
|
||||
GuiLock __;
|
||||
#ifdef CPU_64
|
||||
String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this);
|
||||
#else
|
||||
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
|
||||
#endif
|
||||
if(IsChild())
|
||||
s << "(parent " << String(typeid(*parent).name()) << ")";
|
||||
return s;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
86
rainbow/Framebuffer/Ctrl.h
Normal file
86
rainbow/Framebuffer/Ctrl.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//$ class Ctrl {
|
||||
private:
|
||||
static Ptr<Ctrl> desktop;
|
||||
static Vector<Ctrl *> topctrl;
|
||||
static ImageBuffer framebuffer;
|
||||
static Vector<Rect> invalid, update;
|
||||
|
||||
static Point fbCursorPos;
|
||||
static Image fbCursorImage;
|
||||
|
||||
static Point fbCursorBakPos;
|
||||
static Image fbCursorBak;
|
||||
|
||||
static Rect fbCaretRect;
|
||||
static Image fbCaretBak;
|
||||
static int fbCaretTm;
|
||||
|
||||
static int renderingMode;
|
||||
|
||||
static bool fbEndSession;
|
||||
static int64 fbEventLoop;
|
||||
static int64 fbEndSessionLoop;
|
||||
|
||||
static Image GetBak(Rect& tr);
|
||||
static void RemoveCursor();
|
||||
static void RemoveCaret();
|
||||
static void CursorSync();
|
||||
|
||||
int FindTopCtrl() const;
|
||||
static Rect GetClipBound(const Vector<Rect>& inv, const Rect& r);
|
||||
static void DoPaint();
|
||||
static void DoUpdate();
|
||||
static void SyncTopWindows();
|
||||
|
||||
static void AddInvalid(const Rect& rect);
|
||||
|
||||
void DestroyWnd();
|
||||
|
||||
void NewTop() { top = new Top; top->owner_window = NULL; }
|
||||
void PutForeground();
|
||||
static void MouseEventFB(Ptr<Ctrl> t, int event, Point p, int zdelta);
|
||||
Vector<Rect> GetPaintRects();
|
||||
|
||||
static void DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz,
|
||||
const byte *pattern, int animation);
|
||||
static void DragRectDraw0(const Vector<Rect>& clip, const Rect& rect, int n,
|
||||
const byte *pattern, int animation);
|
||||
|
||||
friend struct PaintProxy__;
|
||||
friend class TopWindowFrame;
|
||||
friend class SystemDraw;
|
||||
friend struct DnDLoop;
|
||||
|
||||
void SetOpen(bool b) { isopen = b; }
|
||||
|
||||
protected:
|
||||
static int PaintLock;
|
||||
|
||||
public:
|
||||
static void DoMouseFB(int event, Point p, int zdelta = 0);
|
||||
static bool DoKeyFB(dword key, int cnt);
|
||||
|
||||
static void InitFB();
|
||||
static void ExitFB();
|
||||
static void EndSession();
|
||||
|
||||
static void SetDesktop(Ctrl& q);
|
||||
static Ctrl *GetDesktop() { return desktop; }
|
||||
static void SetFramebufferSize(Size sz);
|
||||
|
||||
static const ImageBuffer& GetFrameBuffer() { return framebuffer; }
|
||||
|
||||
static void SetRenderingMode(int mode);
|
||||
|
||||
static void AddUpdate(const Rect& rect);
|
||||
|
||||
void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
|
||||
static Ctrl *FindMouseTopCtrl();
|
||||
|
||||
static bool FullWindowDrag;
|
||||
|
||||
enum { DRAWDRAGRECT_SCREEN = 0x8000 };
|
||||
|
||||
//$ };
|
||||
150
rainbow/Framebuffer/DnD.cpp
Normal file
150
rainbow/Framebuffer/DnD.cpp
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
Ptr<Ctrl> sDnDSource;
|
||||
|
||||
Ctrl * Ctrl::GetDragAndDropSource()
|
||||
{
|
||||
return sDnDSource;
|
||||
}
|
||||
|
||||
struct DnDLoop : LocalLoop {
|
||||
const VectorMap<String, ClipData> *data;
|
||||
Vector<String> fmts;
|
||||
|
||||
Image move, copy, reject;
|
||||
Ptr<Ctrl> target;
|
||||
int action;
|
||||
byte actions;
|
||||
|
||||
void Sync();
|
||||
String GetData(const String& f);
|
||||
void DnD(bool paste);
|
||||
|
||||
virtual void LeftUp(Point, dword);
|
||||
virtual bool Key(dword, int);
|
||||
virtual void MouseMove(Point p, dword);
|
||||
virtual Image CursorImage(Point, dword);
|
||||
};
|
||||
|
||||
Ptr<DnDLoop> dndloop;
|
||||
|
||||
bool PasteClip::IsAvailable(const char *fmt) const
|
||||
{
|
||||
GuiLock __;
|
||||
return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0
|
||||
: IsClipboardAvailable(fmt);
|
||||
}
|
||||
|
||||
String DnDLoop::GetData(const String& f)
|
||||
{
|
||||
GuiLock __;
|
||||
int i = data->Find(f);
|
||||
String d;
|
||||
if(i >= 0)
|
||||
d = (*data)[i].Render();
|
||||
else
|
||||
if(sDnDSource)
|
||||
d = sDnDSource->GetDropData(f);
|
||||
return d;
|
||||
}
|
||||
|
||||
String PasteClip::Get(const char *fmt) const
|
||||
{
|
||||
return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt);
|
||||
}
|
||||
|
||||
void PasteClip::GuiPlatformConstruct()
|
||||
{
|
||||
dnd = false;
|
||||
}
|
||||
|
||||
void DnDLoop::DnD(bool paste)
|
||||
{
|
||||
PasteClip d;
|
||||
d.paste = paste;
|
||||
d.accepted = false;
|
||||
d.allowed = (byte)actions;
|
||||
d.action = GetCtrl() ? DND_COPY : DND_MOVE;
|
||||
d.dnd = true;
|
||||
if(target)
|
||||
target->DnD(GetMousePos(), d);
|
||||
action = d.IsAccepted() ? d.GetAction() : DND_NONE;
|
||||
}
|
||||
|
||||
void DnDLoop::Sync()
|
||||
{
|
||||
GuiLock __;
|
||||
Ptr<Ctrl> t = FindMouseTopCtrl();
|
||||
if(t != target)
|
||||
if(target)
|
||||
target->DnDLeave();
|
||||
target = t;
|
||||
DnD(false);
|
||||
}
|
||||
|
||||
void DnDLoop::LeftUp(Point, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::LeftUp");
|
||||
DnD(true);
|
||||
EndLoop();
|
||||
}
|
||||
|
||||
void DnDLoop::MouseMove(Point p, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::MouseMove");
|
||||
Sync();
|
||||
}
|
||||
|
||||
bool DnDLoop::Key(dword, int)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("DnDLoop::Key");
|
||||
Sync();
|
||||
return false;
|
||||
}
|
||||
|
||||
Image DnDLoop::CursorImage(Point, dword)
|
||||
{
|
||||
GuiLock __;
|
||||
return action == DND_MOVE ? move : action == DND_COPY ? copy : reject;
|
||||
}
|
||||
|
||||
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
|
||||
const VectorMap<String, ClipData>& data)
|
||||
{
|
||||
GuiLock __;
|
||||
DnDLoop d;
|
||||
d.actions = (byte)actions;
|
||||
d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample);
|
||||
if(actions & DND_COPY)
|
||||
d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample);
|
||||
if(actions & DND_MOVE)
|
||||
d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample);
|
||||
d.SetMaster(*this);
|
||||
d.data = &data;
|
||||
d.action = DND_NONE;
|
||||
d.fmts = Split(fmts, ';');
|
||||
dndloop = &d;
|
||||
sDnDSource = this;
|
||||
d.Run();
|
||||
sDnDSource = NULL;
|
||||
SyncCaret();
|
||||
LLOG("DoDragAndDrop finished");
|
||||
return d.action;
|
||||
}
|
||||
|
||||
void Ctrl::SetSelectionSource(const char *fmts) {}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
105
rainbow/Framebuffer/Draw.cpp
Normal file
105
rainbow/Framebuffer/Draw.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
SystemDraw::SystemDraw()
|
||||
: BufferPainter(Ctrl::framebuffer, Ctrl::renderingMode)
|
||||
{
|
||||
}
|
||||
|
||||
SystemDraw::~SystemDraw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SystemDraw::Push()
|
||||
{
|
||||
Point p = GetOffset();
|
||||
offset.Add(p);
|
||||
BufferPainter::BeginOp();
|
||||
}
|
||||
|
||||
void SystemDraw::Pop()
|
||||
{
|
||||
if(offset.GetCount())
|
||||
offset.Drop();
|
||||
BufferPainter::EndOp();
|
||||
}
|
||||
|
||||
Point SystemDraw::GetOffset() const
|
||||
{
|
||||
return offset.GetCount() ? offset.Top() : Point(0, 0);
|
||||
}
|
||||
|
||||
void SystemDraw::BeginOp()
|
||||
{
|
||||
Push();
|
||||
}
|
||||
|
||||
void SystemDraw::EndOp()
|
||||
{
|
||||
Pop();
|
||||
}
|
||||
|
||||
void SystemDraw::OffsetOp(Point p)
|
||||
{
|
||||
Push();
|
||||
offset.Top() += p;
|
||||
Translate(p.x, p.y);
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipOp(const Rect& r)
|
||||
{
|
||||
Push();
|
||||
RectPath(r);
|
||||
Painter::Clip();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
Push();
|
||||
offset.Top() += r.TopLeft();
|
||||
RectPath(r);
|
||||
Painter::Clip();
|
||||
Translate(r.left, r.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
Rect rr = r + GetOffset();
|
||||
for(int i = 0; i < Ctrl::invalid.GetCount(); i++)
|
||||
if(Ctrl::invalid[i].Intersects(rr))
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*Rect SystemDraw::GetVirtualScreenArea()
|
||||
{
|
||||
GuiLock __;
|
||||
}*/
|
||||
|
||||
/*
|
||||
void BackDraw::Destroy()
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void BackDraw::Create(SystemDraw& w, int cx, int cy) {
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void BackDraw::Put(SystemDraw& w, int x, int y) {
|
||||
GuiLock __;
|
||||
}
|
||||
*/
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
189
rainbow/Framebuffer/Event.cpp
Normal file
189
rainbow/Framebuffer/Event.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) //DLOG(x)
|
||||
#define LDUMP(x) //DDUMP(x)
|
||||
|
||||
static Point fbmousepos;
|
||||
|
||||
Point GetMousePos() {
|
||||
return fbmousepos;
|
||||
}
|
||||
|
||||
void Ctrl::MouseEventFB(Ptr<Ctrl> t, int event, Point p, int zdelta)
|
||||
{
|
||||
if(!t->IsEnabled())
|
||||
return;
|
||||
Rect rr = t->GetRect();
|
||||
if((event & Ctrl::ACTION) == DOWN) {
|
||||
Ptr<Ctrl> q = t;
|
||||
TopWindowFrame *wf = dynamic_cast<TopWindowFrame *>(~t);
|
||||
if(wf)
|
||||
q = wf->window;
|
||||
if(q) q->ClickActivateWnd();
|
||||
if(q) q->SetForeground();
|
||||
if(ignoreclick)
|
||||
return;
|
||||
}
|
||||
if(t)
|
||||
t->DispatchMouse(event, p - rr.TopLeft(), zdelta);
|
||||
if(t)
|
||||
t->PostInput();
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::FindMouseTopCtrl()
|
||||
{
|
||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||
Ctrl *t = topctrl[i];
|
||||
if(t->GetRect().Contains(fbmousepos))
|
||||
return t->IsEnabled() ? t : NULL;
|
||||
}
|
||||
return desktop->IsEnabled() ? desktop : NULL;
|
||||
}
|
||||
|
||||
void Ctrl::DoMouseFB(int event, Point p, int zdelta)
|
||||
{
|
||||
fbmousepos = p;
|
||||
int a = event & Ctrl::ACTION;
|
||||
if(a == Ctrl::UP && Ctrl::ignoreclick) {
|
||||
EndIgnore();
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(a == Ctrl::DOWN && ignoreclick)
|
||||
return;
|
||||
LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl));
|
||||
if(captureCtrl)
|
||||
MouseEventFB(captureCtrl->GetTopCtrl(), event, p, zdelta);
|
||||
else
|
||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||
Ptr<Ctrl> t = topctrl[i];
|
||||
Rect rr = t->GetRect();
|
||||
if(rr.Contains(p)) {
|
||||
MouseEventFB(t, event, p, zdelta);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ctrl *desktop = GetDesktop();
|
||||
if(desktop) {
|
||||
desktop->DispatchMouse(event, p, zdelta);
|
||||
desktop->PostInput();
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::DoKeyFB(dword key, int cnt)
|
||||
{
|
||||
bool b = DispatchKey(key, cnt);
|
||||
SyncCaret();
|
||||
Ctrl *desktop = GetDesktop();
|
||||
if(desktop)
|
||||
desktop->PostInput();
|
||||
return b;
|
||||
}
|
||||
|
||||
Image Ctrl::GetBak(Rect& tr)
|
||||
{
|
||||
Image bak;
|
||||
tr.Intersect(framebuffer.GetSize());
|
||||
if(!tr.IsEmpty()) {
|
||||
Image h = framebuffer;
|
||||
bak = CreateImage(tr.GetSize(), Black);
|
||||
Copy(bak, Point(0, 0), h, tr);
|
||||
framebuffer = h;
|
||||
}
|
||||
return bak;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveCursor()
|
||||
{
|
||||
if(!IsNull(fbCursorBakPos)) {
|
||||
Copy(framebuffer, fbCursorBakPos, fbCursorBak, fbCursorBak.GetSize());
|
||||
AddUpdate(Rect(fbCursorBakPos, fbCursorBak.GetSize()));
|
||||
}
|
||||
fbCursorPos = fbCursorBakPos = Null;
|
||||
fbCursorBak = Null;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveCaret()
|
||||
{
|
||||
if(!IsNull(fbCaretRect)) {
|
||||
Copy(framebuffer, fbCaretRect.TopLeft(), fbCaretBak, fbCaretBak.GetSize());
|
||||
AddUpdate(fbCaretRect);
|
||||
}
|
||||
fbCaretRect = Null;
|
||||
fbCaretBak = Null;
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
fbCaretTm = GetTickCount();
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::CursorSync()
|
||||
{
|
||||
LLOG("@ CursorSync");
|
||||
Point p = GetMousePos() - fbCursorImage.GetHotSpot();
|
||||
Rect cr = Null;
|
||||
if(focusCtrl && (((GetTickCount() - fbCaretTm) / 500) & 1) == 0)
|
||||
cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy)
|
||||
+ focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView();
|
||||
LDUMP(GetTickCount());
|
||||
if(fbCursorPos != p || cr != fbCaretRect) {
|
||||
LDUMP(fbCaretRect);
|
||||
RemoveCursor();
|
||||
RemoveCaret();
|
||||
|
||||
fbCursorPos = p;
|
||||
Size sz = fbCursorImage.GetSize();
|
||||
Rect tr(p, sz);
|
||||
fbCursorBak = GetBak(tr);
|
||||
fbCursorBakPos = tr.TopLeft();
|
||||
|
||||
fbCaretRect = cr;
|
||||
if(!cr.IsEmpty()) {
|
||||
fbCaretBak = GetBak(cr);
|
||||
for(int y = cr.top; y < cr.bottom; y++) {
|
||||
RGBA *s = framebuffer[y] + cr.left;
|
||||
const RGBA *e = framebuffer[y] + cr.right;
|
||||
while(s < e) {
|
||||
s->r = ~s->r;
|
||||
s->g = ~s->g;
|
||||
s->b = ~s->b;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
AddUpdate(fbCaretRect);
|
||||
}
|
||||
|
||||
Over(framebuffer, p, fbCursorImage, sz);
|
||||
LLOG("Cursor: " << p << ", rect " << tr);
|
||||
AddUpdate(tr);
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SetMouseCursor(const Image& image)
|
||||
{
|
||||
GuiLock __;
|
||||
if(image.GetSerialId() != fbCursorImage.GetSerialId()) {
|
||||
fbCursorImage = image;
|
||||
fbCursorPos = Null;
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
59
rainbow/Framebuffer/FB.iml
Normal file
59
rainbow/Framebuffer/FB.iml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
PREMULTIPLIED
|
||||
IMAGE_ID(arrow)
|
||||
IMAGE_ID(ibeam)
|
||||
IMAGE_ID(wait)
|
||||
IMAGE_ID(no)
|
||||
IMAGE_ID(sizeall)
|
||||
IMAGE_ID(sizehorz)
|
||||
IMAGE_ID(sizeright)
|
||||
IMAGE_ID(sizeleft)
|
||||
IMAGE_ID(sizevert)
|
||||
IMAGE_ID(sizetopleft)
|
||||
IMAGE_ID(sizetop)
|
||||
IMAGE_ID(sizetopright)
|
||||
IMAGE_ID(sizebottomleft)
|
||||
IMAGE_ID(sizebottom)
|
||||
IMAGE_ID(sizebottomright)
|
||||
IMAGE_ID(overlap)
|
||||
IMAGE_ID(maximize)
|
||||
IMAGE_ID(close)
|
||||
IMAGE_ID(bgtitle)
|
||||
IMAGE_ID(title)
|
||||
IMAGE_ID(border)
|
||||
IMAGE_ID(hand)
|
||||
|
||||
IMAGE_BEGIN_DATA
|
||||
IMAGE_DATA(120,156,237,90,205,75,84,81,20,191,101,163,6,74,72,180,115,209,166,77,127,66,4,109,91,6,22,4,209,38,23,209)
|
||||
IMAGE_DATA(162,93,45,162,204,9,34,130,8,13,178,36,44,45,11,212,172,197,108,68,84,212,133,31,8,126,224,7,12,162,8,34)
|
||||
IMAGE_DATA(136,136,160,43,221,157,238,140,51,227,245,188,251,206,61,231,206,27,43,120,231,113,208,247,238,239,119,238,57,191,115,222)
|
||||
IMAGE_DATA(123,227,135,170,82,23,84,198,202,213,169,204,23,80,50,3,33,7,0,68,28,56,56,184,8,251,251,151,184,28,216,219)
|
||||
IMAGE_DATA(187,2,187,187,215,96,103,231,58,135,3,219,219,55,96,107,235,38,108,110,222,129,245,245,122,23,7,54,54,234,53,238)
|
||||
IMAGE_DATA(62,172,173,61,132,213,213,71,144,78,63,165,56,176,178,242,24,150,151,159,104,92,35,44,46,190,130,249,249,183,48,59)
|
||||
IMAGE_DATA(219,28,198,129,165,165,151,176,176,240,26,230,230,154,96,102,166,21,166,166,58,97,114,242,59,76,76,180,219,56,26,211)
|
||||
IMAGE_DATA(12,211,211,239,53,174,13,198,199,187,97,100,100,36,231,191,96,120,184,19,115,116,172,86,141,107,131,177,177,78,24,29)
|
||||
IMAGE_DATA(253,93,192,171,163,94,154,28,141,249,172,189,3,134,134,126,192,224,224,79,232,239,79,145,245,14,12,180,67,95,223,215)
|
||||
IMAGE_DATA(66,156,84,170,155,196,167,82,95,2,57,118,117,125,11,213,199,166,65,71,199,39,10,111,221,183,165,229,157,104,14,155)
|
||||
IMAGE_DATA(154,222,136,103,61,153,124,46,218,163,161,225,153,120,15,1,54,104,9,117,78,157,86,21,89,87,168,241,42,123,179,30)
|
||||
IMAGE_DATA(26,250,190,176,57,58,255,239,175,133,212,27,208,69,85,105,225,18,90,180,196,113,225,184,158,229,212,246,124,32,221,192)
|
||||
IMAGE_DATA(158,4,158,228,88,176,161,28,2,27,224,48,176,5,142,4,235,147,139,79,173,62,90,254,133,254,202,230,179,70,31,149)
|
||||
IMAGE_DATA(185,131,18,206,226,92,227,222,36,28,126,49,235,146,60,139,229,7,26,200,136,97,127,250,248,243,195,242,146,242,185,49)
|
||||
IMAGE_DATA(36,235,174,61,56,57,82,117,82,230,210,88,194,183,229,36,153,21,219,53,95,62,55,142,207,125,231,115,223,186,98,217)
|
||||
IMAGE_DATA(141,249,64,58,140,26,124,189,139,204,124,253,23,195,207,187,52,14,230,251,196,1,195,208,169,51,6,198,217,244,160,98)
|
||||
IMAGE_DATA(133,225,57,215,204,235,56,111,91,45,24,139,249,62,110,139,227,147,71,84,122,68,213,23,91,44,91,45,46,46,222,31)
|
||||
IMAGE_DATA(187,36,134,45,142,148,143,227,248,242,81,28,218,106,244,199,254,74,85,150,117,76,118,5,160,48,220,34,194,112,212,208)
|
||||
IMAGE_DATA(218,76,169,147,191,121,56,121,68,165,135,185,238,213,151,184,209,113,163,253,2,50,19,118,225,138,21,216,188,230,227,182)
|
||||
IMAGE_DATA(56,62,121,68,165,135,185,238,213,151,10,221,234,178,92,171,45,27,178,19,193,194,186,4,183,9,132,206,157,133,255,235)
|
||||
IMAGE_DATA(107,84,125,148,46,148,158,156,92,140,245,35,171,214,71,121,238,8,100,130,68,39,2,146,73,185,56,46,124,177,28,44)
|
||||
IMAGE_DATA(182,139,131,155,197,221,47,108,239,98,121,146,62,72,106,53,121,170,132,189,240,157,17,235,44,198,79,166,210,173,81,245)
|
||||
IMAGE_DATA(81,186,80,122,114,114,49,214,143,204,124,50,81,22,200,18,53,132,216,236,68,159,66,92,14,22,223,197,161,26,201,197)
|
||||
IMAGE_DATA(227,117,28,75,146,3,7,111,114,212,9,235,207,205,77,58,83,241,192,198,3,91,18,14,55,55,241,192,198,175,210,210)
|
||||
IMAGE_DATA(173,81,245,81,186,80,122,114,114,49,214,143,44,254,144,31,228,224,102,113,247,11,219,187,88,158,164,15,146,90,77,158)
|
||||
IMAGE_DATA(42,97,47,124,103,196,58,139,85,250,136,200,172,119,154,225,54,60,21,203,23,207,201,3,227,93,123,70,133,231,232,83)
|
||||
IMAGE_DATA(42,93,204,107,146,62,241,45,130,97,114,37,39,17,203,134,137,241,209,227,37,253,226,91,20,79,166,171,213,213,161,155)
|
||||
IMAGE_DATA(227,181,204,121,222,109,88,219,154,237,58,21,7,175,187,176,97,28,10,43,197,75,242,145,212,235,171,39,149,39,85,7)
|
||||
IMAGE_DATA(105,103,244,145,183,186,186,86,184,253,160,23,238,190,232,133,123,31,123,65,122,94,8,86,150,253,219,76,18,206,94,238)
|
||||
IMAGE_DATA(129,243,183,150,160,182,49,243,18,22,158,103,198,60,161,143,220,207,178,220,251,233,216,155,223,101,230,255,83,231,207,41)
|
||||
IMAGE_DATA(79,38,147,49,190,68,248,252,185,203,125,102,33,59,76,142,95,140,80,159,94,48,14,210,233,244,177,175,97,88,140,51)
|
||||
IMAGE_DATA(240,214,79,32,97,120,180,79,33,6,23,239,194,217,240,121,151,226,195,28,213,44,197,59,57,148,166,76,44,11,255,7)
|
||||
IMAGE_DATA(113,204,146,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
IMAGE_END_DATA(1056, 22)
|
||||
64
rainbow/Framebuffer/Fb.h
Normal file
64
rainbow/Framebuffer/Fb.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#ifndef _Framebuffer_Fb_h_
|
||||
#define _Framebuffer_Fb_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class TopWindowFrame : public Ctrl {
|
||||
public:
|
||||
virtual void Layout();
|
||||
virtual void Paint(Draw& w);
|
||||
virtual Image CursorImage(Point p, dword keyflags);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
virtual void LeftHold(Point p, dword keyflags);
|
||||
virtual void LeftDouble(Point p, dword keyflags);
|
||||
virtual void MouseMove(Point p, dword keyflags);
|
||||
virtual void CancelMode();
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
|
||||
private:
|
||||
Point dir;
|
||||
Point startpos;
|
||||
Rect startrect;
|
||||
|
||||
bool maximized;
|
||||
Rect overlapped;
|
||||
|
||||
bool holding;
|
||||
TimeCallback hold;
|
||||
|
||||
Point GetDragMode(Point p);
|
||||
Image GetDragImage(Point dragmode);
|
||||
void StartDrag();
|
||||
Rect Margins() const;
|
||||
Rect ComputeClient(Rect r);
|
||||
void Hold();
|
||||
|
||||
typedef TopWindowFrame CLASSNAME;
|
||||
|
||||
public:
|
||||
String title;
|
||||
Button close, maximize;
|
||||
Image icon;
|
||||
Size minsize;
|
||||
bool sizeable;
|
||||
TopWindow *window;
|
||||
|
||||
void SetTitle(const String& s) { title = s; Refresh(); }
|
||||
Rect GetClient() const;
|
||||
void SetClient(Rect r);
|
||||
void GripResize();
|
||||
|
||||
void Maximize();
|
||||
void Overlap();
|
||||
void ToggleMaximize();
|
||||
bool IsMaximized() const { return maximized; }
|
||||
void SyncRect();
|
||||
|
||||
TopWindowFrame();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
141
rainbow/Framebuffer/Framebuffer.h
Normal file
141
rainbow/Framebuffer/Framebuffer.h
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#define GUI_FB
|
||||
|
||||
#include <Painter/Painter.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define IMAGECLASS FBImg
|
||||
#define IMAGEFILE <Framebuffer/FB.iml>
|
||||
#include <Draw/iml_header.h>
|
||||
|
||||
class SystemDraw : public BufferPainter {
|
||||
public:
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
private:
|
||||
Vector<Point> offset;
|
||||
|
||||
void Push();
|
||||
void Pop();
|
||||
|
||||
public:
|
||||
Point GetOffset() const;
|
||||
bool CanSetSurface() { return false; }
|
||||
bool Clip(const Rect& r) { return Draw::Clip(r); }
|
||||
bool Clip(int x, int y, int cx, int cy) { return Draw::Clip(x, y, cx, cy); }
|
||||
|
||||
static void Flush() {}
|
||||
|
||||
SystemDraw();
|
||||
~SystemDraw();
|
||||
};
|
||||
|
||||
struct BackDraw__ : public SystemDraw {
|
||||
BackDraw__() : SystemDraw() {}
|
||||
};
|
||||
|
||||
class BackDraw : public BackDraw__ { // Dummy only, as we are running in GlobalBackBuffer mode
|
||||
Size size;
|
||||
Draw *painting;
|
||||
Point painting_offset;
|
||||
ImageBuffer ib;
|
||||
|
||||
public:
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
public:
|
||||
void Put(SystemDraw& w, int x, int y) {}
|
||||
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
|
||||
|
||||
void Create(SystemDraw& w, int cx, int cy) {}
|
||||
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
|
||||
void Destroy() {}
|
||||
|
||||
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
|
||||
|
||||
BackDraw();
|
||||
~BackDraw();
|
||||
};
|
||||
|
||||
struct ImageDraw__ {
|
||||
ImageBuffer image;
|
||||
ImageBuffer alpha;
|
||||
|
||||
ImageDraw__(int cx, int cy) : image(cx, cy), alpha(cx, cy) {}
|
||||
};
|
||||
|
||||
class ImageDraw : private ImageDraw__, public BufferPainter {
|
||||
BufferPainter alpha_painter;
|
||||
bool has_alpha;
|
||||
|
||||
Image Get(bool pm) const;
|
||||
|
||||
public:
|
||||
Draw& Alpha();
|
||||
|
||||
operator Image() const { return Get(true); }
|
||||
|
||||
Image GetStraight() const { return Get(false); }
|
||||
|
||||
ImageDraw(Size sz);
|
||||
ImageDraw(int cx, int cy);
|
||||
};
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, uint64 pattern);
|
||||
|
||||
class TopWindowFrame;
|
||||
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window;
|
||||
|
||||
#define GUIPLATFORM_CTRL_DECLS_INCLUDE <Framebuffer/Ctrl.h>
|
||||
|
||||
#define GUIPLATFORM_PASTECLIP_DECLS \
|
||||
bool dnd; \
|
||||
friend struct DnDLoop; \
|
||||
|
||||
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Framebuffer/Top.h>
|
||||
|
||||
// to be implemented by final FB {
|
||||
|
||||
bool FBIsWaitingEvent();
|
||||
bool FBProcessEvent(bool *quit);
|
||||
void FBSleep(int ms);
|
||||
void FBInitUpdate();
|
||||
void FBUpdate(const Rect& area);
|
||||
void FBFlush();
|
||||
void FBQuitSession();
|
||||
|
||||
// }
|
||||
|
||||
class PrinterJob { // Dummy only...
|
||||
NilDraw nil;
|
||||
Vector<int> pages;
|
||||
|
||||
public:
|
||||
Draw& GetDraw() { return nil; }
|
||||
operator Draw&() { return GetDraw(); }
|
||||
const Vector<int>& GetPages() const { return pages; }
|
||||
int operator[](int i) const { return 0; }
|
||||
int GetPageCount() const { return 0; }
|
||||
|
||||
bool Execute() { return false; }
|
||||
|
||||
PrinterJob& Landscape(bool b = true) { return *this; }
|
||||
PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; }
|
||||
PrinterJob& PageCount(int n) { return *this; }
|
||||
PrinterJob& CurrentPage(int currentpage) { return *this; }
|
||||
PrinterJob& Name(const char *_name) { return *this; }
|
||||
|
||||
PrinterJob(const char *name = NULL) {}
|
||||
~PrinterJob() {}
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#define GUIPLATFORM_INCLUDE_AFTER <Framebuffer/After.h>
|
||||
25
rainbow/Framebuffer/Framebuffer.upp
Normal file
25
rainbow/Framebuffer/Framebuffer.upp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
description "Generic framebuffer GUI rainbow\377";
|
||||
|
||||
uses
|
||||
Painter,
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
Framebuffer.h,
|
||||
After.h,
|
||||
Fb.h,
|
||||
Draw.cpp,
|
||||
Image.cpp,
|
||||
Util.cpp,
|
||||
FB.iml,
|
||||
Ctrl.h,
|
||||
Ctrl.cpp,
|
||||
Wnd.cpp,
|
||||
Event.cpp,
|
||||
Top.h,
|
||||
TopFrame.cpp,
|
||||
Top.cpp,
|
||||
Clip.cpp,
|
||||
DnD.cpp,
|
||||
ChSysInit.cpp;
|
||||
|
||||
358
rainbow/Framebuffer/Gui.h
Normal file
358
rainbow/Framebuffer/Gui.h
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
#define GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class SystemDraw : public Draw {
|
||||
public:
|
||||
virtual dword GetInfo() const;
|
||||
virtual Size GetPageSize() const;
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool ExcludeClipOp(const Rect& r);
|
||||
virtual bool IntersectClipOp(const Rect& r);
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
virtual Rect GetPaintRect() const;
|
||||
|
||||
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
|
||||
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
|
||||
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor);
|
||||
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor);
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
|
||||
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx);
|
||||
|
||||
virtual Size GetNativeDpi() const;
|
||||
virtual void BeginNative();
|
||||
virtual void EndNative();
|
||||
|
||||
virtual int GetCloffLevel() const;
|
||||
|
||||
private:
|
||||
Size pageSize;
|
||||
Size nativeSize;
|
||||
Size nativeDpi;
|
||||
bool palette:1;
|
||||
bool color16:1;
|
||||
bool is_mono:1;
|
||||
int native;
|
||||
|
||||
friend class ImageDraw;
|
||||
friend class FontInfo;
|
||||
friend class Font;
|
||||
|
||||
friend void StaticExitDraw_();
|
||||
|
||||
Point actual_offset_bak;
|
||||
|
||||
struct Cloff : Moveable<Cloff> {
|
||||
Point org;
|
||||
HRGN hrgn;
|
||||
Rect drawingclip;
|
||||
};
|
||||
|
||||
Array<Cloff> cloff;
|
||||
Rect drawingclip;
|
||||
|
||||
COLORREF lastTextColor;
|
||||
Color lastColor;
|
||||
HBRUSH orgBrush;
|
||||
HBRUSH actBrush;
|
||||
HPEN orgPen;
|
||||
HPEN actPen;
|
||||
int lastPen;
|
||||
Color lastPenColor;
|
||||
|
||||
void Unselect0();
|
||||
void Cinit();
|
||||
|
||||
void LoadCaps();
|
||||
void SetPrinterMode();
|
||||
void Reset();
|
||||
void SetOrg();
|
||||
friend HPALETTE GetQlibPalette();
|
||||
void DotsMode();
|
||||
|
||||
static void InitColors();
|
||||
|
||||
friend class BackDraw;
|
||||
friend class ScreenDraw;
|
||||
friend class PrintDraw;
|
||||
|
||||
protected:
|
||||
dword style;
|
||||
HDC handle;
|
||||
Point actual_offset;
|
||||
|
||||
SystemDraw();
|
||||
void Init();
|
||||
void InitClip(const Rect& clip);
|
||||
|
||||
public:
|
||||
static Rect GetVirtualScreenArea();
|
||||
|
||||
static void SetAutoPalette(bool ap);
|
||||
static bool AutoPalette();
|
||||
bool PaletteMode() { return palette; }
|
||||
|
||||
static void Flush() { GdiFlush(); }
|
||||
|
||||
COLORREF GetColor(Color color) const;
|
||||
|
||||
Point GetOffset() const { return actual_offset; }
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
Point LPtoDP(Point p) const;
|
||||
Point DPtoLP(Point p) const;
|
||||
Rect LPtoDP(const Rect& r) const;
|
||||
Rect DPtoLP(const Rect& r) const;
|
||||
#endif
|
||||
|
||||
void SetColor(Color color);
|
||||
void SetDrawPen(int width, Color color);
|
||||
|
||||
Size GetSizeCaps(int i, int j) const;
|
||||
HDC BeginGdi();
|
||||
void EndGdi();
|
||||
HDC GetHandle() { return handle; }
|
||||
operator HDC() const { return handle; }
|
||||
void Unselect();
|
||||
void Attach(HDC ahandle) { handle = ahandle; Init(); }
|
||||
HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; }
|
||||
|
||||
SystemDraw(HDC hdc);
|
||||
virtual ~SystemDraw();
|
||||
|
||||
bool CanSetSurface() { return IsGui() && IsWinNT(); }
|
||||
};
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
class WinMetaFile {
|
||||
Size size;
|
||||
HENHMETAFILE hemf;
|
||||
|
||||
void Init();
|
||||
|
||||
public:
|
||||
void Attach(HENHMETAFILE emf);
|
||||
HENHMETAFILE Detach();
|
||||
|
||||
void Set(const void *data, dword len);
|
||||
void Set(const String& data) { Set(~data, data.GetCount()); }
|
||||
|
||||
String Get() const;
|
||||
|
||||
operator bool() const { return hemf; }
|
||||
void SetSize(const Size& sz) { size = sz; }
|
||||
Size GetSize() const { return hemf ? size : Size(0, 0); }
|
||||
|
||||
void Clear();
|
||||
|
||||
void Paint(Draw& w, const Rect& r) const;
|
||||
void Paint(Draw& w, int x, int y, int cx, int cy) const;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
|
||||
void ReadClipboard();
|
||||
void WriteClipboard() const;
|
||||
void Load(const char *file) { Set(LoadFile(file)); }
|
||||
|
||||
WinMetaFile() { Init(); }
|
||||
WinMetaFile(HENHMETAFILE hemf);
|
||||
WinMetaFile(HENHMETAFILE hemf, Size sz);
|
||||
WinMetaFile(const char *file);
|
||||
WinMetaFile(void *data, int len);
|
||||
WinMetaFile(const String& data);
|
||||
|
||||
~WinMetaFile() { Clear(); }
|
||||
|
||||
HENHMETAFILE GetHEMF() const { return hemf; }
|
||||
};
|
||||
|
||||
class WinMetaFileDraw : public SystemDraw {
|
||||
Size size;
|
||||
|
||||
public:
|
||||
bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
WinMetaFile Close();
|
||||
|
||||
WinMetaFileDraw() {}
|
||||
WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
~WinMetaFileDraw();
|
||||
};
|
||||
|
||||
void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf);
|
||||
void DrawWMF(Draw& w, int x, int y, const String& wmf);
|
||||
Drawing LoadWMF(const char *path, int cx, int cy);
|
||||
Drawing LoadWMF(const char *path);
|
||||
|
||||
String AsWMF(const Drawing& iw);
|
||||
|
||||
#endif
|
||||
|
||||
class ScreenDraw : public SystemDraw {
|
||||
public:
|
||||
ScreenDraw(bool ic = false);
|
||||
~ScreenDraw();
|
||||
};
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
class PrintDraw : public SystemDraw {
|
||||
public:
|
||||
virtual void StartPage();
|
||||
virtual void EndPage();
|
||||
|
||||
private:
|
||||
bool aborted;
|
||||
|
||||
void InitPrinter();
|
||||
public:
|
||||
PrintDraw(HDC hdc, const char *jobname);
|
||||
~PrintDraw();
|
||||
};
|
||||
#endif
|
||||
|
||||
inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY)
|
||||
{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); }
|
||||
|
||||
inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY)
|
||||
{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); }
|
||||
|
||||
inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY)
|
||||
{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); }
|
||||
|
||||
inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); }
|
||||
inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); }
|
||||
|
||||
inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); }
|
||||
inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); }
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); }
|
||||
#endif
|
||||
inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); }
|
||||
inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); }
|
||||
inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); }
|
||||
|
||||
inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); }
|
||||
|
||||
HDC ScreenHDC();
|
||||
HPALETTE GetQlibPalette();
|
||||
|
||||
Image Win32Icon(LPCSTR id, int iconsize = 0);
|
||||
Image Win32Icon(int id, int iconsize = 0);
|
||||
Image Win32Cursor(LPCSTR id);
|
||||
Image Win32Cursor(int id);
|
||||
HICON IconWin32(const Image& img, bool cursor = false);
|
||||
Image Win32DllIcon(const char *dll, int ii, bool large);
|
||||
|
||||
class BackDraw : public SystemDraw {
|
||||
public:
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
protected:
|
||||
HBITMAP hbmpold;
|
||||
HBITMAP hbmp;
|
||||
|
||||
Size size;
|
||||
Draw *painting;
|
||||
Point painting_offset;
|
||||
|
||||
public:
|
||||
void Put(SystemDraw& w, int x, int y);
|
||||
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
|
||||
|
||||
void Create(SystemDraw& w, int cx, int cy);
|
||||
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
|
||||
void Destroy();
|
||||
|
||||
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
|
||||
|
||||
BackDraw();
|
||||
~BackDraw();
|
||||
};
|
||||
|
||||
class ImageDraw : public SystemDraw {
|
||||
Size size;
|
||||
|
||||
struct Section {
|
||||
HDC dc;
|
||||
HBITMAP hbmp, hbmpOld;
|
||||
RGBA *pixels;
|
||||
|
||||
void Init(int cx, int cy);
|
||||
~Section();
|
||||
};
|
||||
|
||||
Section rgb;
|
||||
Section a;
|
||||
SystemDraw alpha;
|
||||
|
||||
|
||||
bool has_alpha;
|
||||
|
||||
void Init();
|
||||
Image Get(bool pm) const;
|
||||
|
||||
public:
|
||||
Draw& Alpha();
|
||||
|
||||
operator Image() const;
|
||||
|
||||
Image GetStraight() const;
|
||||
|
||||
ImageDraw(Size sz);
|
||||
ImageDraw(int cx, int cy);
|
||||
~ImageDraw();
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h"
|
||||
|
||||
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS \
|
||||
HWND hwnd; \
|
||||
UDropTarget *dndtgt; \
|
||||
|
||||
|
||||
#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h"
|
||||
|
||||
|
||||
#define GUIPLATFORM_PASTECLIP_DECLS \
|
||||
UDropTarget *dt; \
|
||||
|
||||
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
inline unsigned GetHashValue(const HWND& hwnd)
|
||||
{
|
||||
return (unsigned)(intptr_t)hwnd;
|
||||
}
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifndef PLATFORM_WINCE
|
||||
|
||||
#include <ShellAPI.h>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h"
|
||||
92
rainbow/Framebuffer/Image.cpp
Normal file
92
rainbow/Framebuffer/Image.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels)
|
||||
{
|
||||
GuiLock __;
|
||||
// Empty as CanSetSurface is false
|
||||
}
|
||||
|
||||
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff)
|
||||
{
|
||||
GuiLock __;
|
||||
// Empty as CanSetSurface is false
|
||||
}
|
||||
|
||||
Image ImageDraw::Get(bool pm) const
|
||||
{
|
||||
ImageBuffer result(image.GetSize());
|
||||
const RGBA *e = image.End();
|
||||
const RGBA *p = ~image;
|
||||
RGBA *t = ~result;
|
||||
if(has_alpha) {
|
||||
const RGBA *a = ~alpha;
|
||||
while(p < e) {
|
||||
*t = *p++;
|
||||
(t++)->a = (a++)->r;
|
||||
}
|
||||
if(pm)
|
||||
Premultiply(result);
|
||||
result.SetKind(IMAGE_ALPHA);
|
||||
}
|
||||
else {
|
||||
while(p < e) {
|
||||
*t = *p++;
|
||||
(t++)->a = 255;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Draw& ImageDraw::Alpha()
|
||||
{
|
||||
has_alpha = true;
|
||||
return alpha_painter;
|
||||
}
|
||||
|
||||
|
||||
ImageDraw::ImageDraw(Size sz)
|
||||
: ImageDraw__(sz.cx, sz.cy),
|
||||
BufferPainter(image),
|
||||
alpha_painter(alpha)
|
||||
{
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(int cx, int cy)
|
||||
: ImageDraw__(cx, cy),
|
||||
BufferPainter(image),
|
||||
alpha_painter(alpha)
|
||||
{
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
#define IMAGECLASS FBImg
|
||||
#define IMAGEFILE <Framebuffer/FB.iml>
|
||||
#include <Draw/iml_source.h>
|
||||
|
||||
Image Image::Arrow() { return FBImg::arrow(); }
|
||||
Image Image::Wait() { return FBImg::wait(); }
|
||||
Image Image::IBeam() { return FBImg::ibeam(); }
|
||||
Image Image::No() { return FBImg::no(); }
|
||||
Image Image::SizeAll() { return FBImg::sizeall(); }
|
||||
Image Image::SizeHorz() { return FBImg::sizehorz(); }
|
||||
Image Image::SizeVert() { return FBImg::sizevert(); }
|
||||
Image Image::SizeTopLeft() { return FBImg::sizetopleft(); }
|
||||
Image Image::SizeTop() { return FBImg::sizetop(); }
|
||||
Image Image::SizeTopRight() { return FBImg::sizetopright(); }
|
||||
Image Image::SizeLeft() { return FBImg::sizeleft(); }
|
||||
Image Image::SizeRight() { return FBImg::sizeright(); }
|
||||
Image Image::SizeBottomLeft() { return FBImg::sizebottomleft(); }
|
||||
Image Image::SizeBottom() { return FBImg::sizebottom(); }
|
||||
Image Image::SizeBottomRight() { return FBImg::sizebottomright(); }
|
||||
Image Image::Hand() { return FBImg::hand(); }
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
150
rainbow/Framebuffer/Top.cpp
Normal file
150
rainbow/Framebuffer/Top.cpp
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
void TopWindow::SyncFrameRect(const Rect& r)
|
||||
{
|
||||
frame->SetClient(r);
|
||||
}
|
||||
|
||||
void TopWindow::DestroyFrame()
|
||||
{
|
||||
if(frame->IsOpen())
|
||||
frame->DestroyWnd();
|
||||
}
|
||||
|
||||
void TopWindow::GripResize()
|
||||
{
|
||||
frame->GripResize();
|
||||
}
|
||||
|
||||
void TopWindow::SyncSizeHints()
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle()
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncCaption()
|
||||
{
|
||||
GuiLock __;
|
||||
frame->title = title.ToString();
|
||||
frame->minsize = minsize;
|
||||
frame->close.Show(!noclosebox);
|
||||
frame->maximize.Show(maximizebox);
|
||||
frame->sizeable = sizeable;
|
||||
frame->RefreshLayout();
|
||||
frame->Refresh();
|
||||
frame->close <<= Proxy(WhenClose);
|
||||
frame->icon = icon;
|
||||
frame->Enable(IsEnabled());
|
||||
}
|
||||
|
||||
void TopWindow::State(int reason)
|
||||
{
|
||||
SyncCaption();
|
||||
}
|
||||
|
||||
void TopWindow::SyncRect()
|
||||
{
|
||||
frame->SyncRect();
|
||||
Rect r = frame->GetClient();
|
||||
if(r != GetRect()) {
|
||||
SetRect(r);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindow::Open(Ctrl *owner)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("Open " << Upp::Name(owner));
|
||||
Rect r = GetRect();
|
||||
if(r.IsEmpty())
|
||||
SetRect(GetDefaultWindowRect());
|
||||
else
|
||||
if(r.left == 0 && r.top == 0)
|
||||
if(owner && center == 1)
|
||||
SetRect(owner->GetRect().CenterRect(r.GetSize()));
|
||||
else
|
||||
if(center)
|
||||
SetRect(GetWorkArea().CenterRect(r.GetSize()));
|
||||
frame->SetClient(GetRect());
|
||||
frame->window = this;
|
||||
frame->PopUp(owner, false, true);
|
||||
PopUp(frame, false, true);
|
||||
popup = false;
|
||||
SetRect(frame->GetClient());
|
||||
SyncCaption();
|
||||
if(state == MAXIMIZED)
|
||||
frame->Maximize();
|
||||
}
|
||||
|
||||
void TopWindow::Open()
|
||||
{
|
||||
Open(GetActiveCtrl());
|
||||
}
|
||||
|
||||
void TopWindow::OpenMain()
|
||||
{
|
||||
Open(NULL);
|
||||
}
|
||||
|
||||
void TopWindow::Minimize(bool effect)
|
||||
{
|
||||
// state = MINIMIZED;
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::FullScreen(bool b)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TopWindow::Maximize(bool effect)
|
||||
{
|
||||
state = MAXIMIZED;
|
||||
frame->Maximize();
|
||||
}
|
||||
|
||||
void TopWindow::Overlap(bool effect)
|
||||
{
|
||||
GuiLock __;
|
||||
state = OVERLAPPED;
|
||||
frame->Overlap();
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::TopMost(bool b, bool stay_top)
|
||||
{
|
||||
GuiLock __;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TopWindow::IsTopMost() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformConstruct()
|
||||
{
|
||||
frame = new TopWindowFrame;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformDestruct()
|
||||
{
|
||||
delete frame;
|
||||
}
|
||||
|
||||
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
16
rainbow/Framebuffer/Top.h
Normal file
16
rainbow/Framebuffer/Top.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//$ class TopWindow {
|
||||
public:
|
||||
virtual void State(int reason);
|
||||
|
||||
private:
|
||||
TopWindowFrame *frame;
|
||||
|
||||
void SyncRect();
|
||||
void SyncFrameRect(const Rect& r);
|
||||
void DestroyFrame();
|
||||
|
||||
friend class Ctrl;
|
||||
|
||||
public:
|
||||
void GripResize();
|
||||
//$ };
|
||||
259
rainbow/Framebuffer/TopFrame.cpp
Normal file
259
rainbow/Framebuffer/TopFrame.cpp
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LDUMP(x) //DDUMP(x)
|
||||
|
||||
TopWindowFrame::TopWindowFrame()
|
||||
{
|
||||
close.SetImage(FBImg::close());
|
||||
close.EdgeStyle();
|
||||
Add(close);
|
||||
maximize.SetImage(FBImg::maximize());
|
||||
maximize.EdgeStyle();
|
||||
Add(maximize);
|
||||
maximize <<= THISBACK(ToggleMaximize);
|
||||
maximized = false;
|
||||
sizeable = false;
|
||||
holding = false;
|
||||
}
|
||||
|
||||
void TopWindowFrame::SyncRect()
|
||||
{
|
||||
if(maximized) {
|
||||
Size sz = framebuffer.GetSize();
|
||||
if(GetRect().GetSize() != sz)
|
||||
SetRect(sz);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::Maximize()
|
||||
{
|
||||
if(!maximized && maximize.IsShown()) {
|
||||
maximized = true;
|
||||
overlapped = GetRect();
|
||||
SetRect(framebuffer.GetSize());
|
||||
maximize.SetImage(FBImg::overlap());
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::Overlap()
|
||||
{
|
||||
if(maximized && maximize.IsShown()) {
|
||||
maximized = false;
|
||||
SetRect(overlapped);
|
||||
maximize.SetImage(FBImg::maximize());
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::ToggleMaximize()
|
||||
{
|
||||
if(maximized)
|
||||
Overlap();
|
||||
else
|
||||
Maximize();
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::Margins() const
|
||||
{
|
||||
return maximized ? Rect(0, 0, 0, 0) : ChMargins(FBImg::border());
|
||||
}
|
||||
|
||||
void TopWindowFrame::Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = Margins();
|
||||
int c = GetStdFontCy() + 4;
|
||||
ChPaintEdge(w, sz, FBImg::border());
|
||||
ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4,
|
||||
window->IsForeground() ? FBImg::title() : FBImg::bgtitle());
|
||||
int tx = m.left + 2;
|
||||
int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown());
|
||||
if(!IsNull(icon)) {
|
||||
Image h = icon;
|
||||
if(h.GetWidth() > c || h.GetHeight() > c)
|
||||
h = Rescale(h, GetFitSize(h.GetSize(), Size(c)));
|
||||
w.DrawImage(tx, m.top + 2, h);
|
||||
tx += c;
|
||||
tcx -= c;
|
||||
}
|
||||
DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText());
|
||||
}
|
||||
|
||||
void TopWindowFrame::Layout()
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = Margins();
|
||||
int c = GetStdFontCy() + 4;
|
||||
int x = sz.cx - m.right;
|
||||
if(close.IsShown())
|
||||
close.SetRect(x -= c, m.top, c, c);
|
||||
if(maximize.IsShown())
|
||||
maximize.SetRect(x -= c, m.top, c, c);
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::GetClient() const
|
||||
{
|
||||
Rect r = GetRect();
|
||||
Rect m = Margins();
|
||||
r.left += m.left;
|
||||
r.right -= m.right;
|
||||
r.top += m.top;
|
||||
r.bottom -= m.bottom;
|
||||
r.top += GetStdFontCy() + 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
Rect TopWindowFrame::ComputeClient(Rect r)
|
||||
{
|
||||
Rect m = Margins();
|
||||
r.left -= m.left;
|
||||
r.right += m.right;
|
||||
r.top -= m.top;
|
||||
r.bottom += m.bottom;
|
||||
r.top -= GetStdFontCy() + 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
void TopWindowFrame::SetClient(Rect r)
|
||||
{
|
||||
SetRect(ComputeClient(r));
|
||||
}
|
||||
|
||||
Point TopWindowFrame::GetDragMode(Point p)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
Rect m = ChMargins(FBImg::border());
|
||||
Point dir;
|
||||
dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0;
|
||||
dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0;
|
||||
return dir;
|
||||
}
|
||||
|
||||
void TopWindowFrame::StartDrag()
|
||||
{
|
||||
if(maximized)
|
||||
return;
|
||||
if(!sizeable && (dir.x || dir.y))
|
||||
return;
|
||||
if(FullWindowDrag) {
|
||||
SetCapture();
|
||||
startrect = GetRect();
|
||||
startpos = GetMousePos();
|
||||
}
|
||||
else {
|
||||
Rect r = GetScreenRect();
|
||||
RectTracker tr(*this);
|
||||
tr.SetCursorImage(GetDragImage(dir))
|
||||
.MaxRect(framebuffer.GetSize())
|
||||
.MinSize(ComputeClient(minsize).GetSize())
|
||||
.Pattern(DRAWDRAGRECT_DASHED | DRAWDRAGRECT_SCREEN)
|
||||
.Width(2)
|
||||
.Animation();
|
||||
PaintLock++;
|
||||
r = tr.Track(r, dir.x < 0 ? ALIGN_LEFT : dir.x > 0 ? ALIGN_RIGHT : ALIGN_CENTER,
|
||||
dir.y < 0 ? ALIGN_TOP : dir.y > 0 ? ALIGN_BOTTOM : ALIGN_CENTER);
|
||||
PaintLock--;
|
||||
SetRect(r);
|
||||
}
|
||||
LLOG("START DRAG ---------------");
|
||||
}
|
||||
|
||||
void TopWindowFrame::GripResize()
|
||||
{
|
||||
dir = Point(1, 1);
|
||||
StartDrag();
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
dir = GetDragMode(p);
|
||||
if(dir.x || dir.y || FullWindowDrag)
|
||||
StartDrag();
|
||||
else {
|
||||
SetCapture();
|
||||
holding = true;
|
||||
hold.Set(GetKbdDelay() / 3, THISBACK(Hold));
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::CancelMode()
|
||||
{
|
||||
holding = false;
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
holding = false;
|
||||
}
|
||||
|
||||
void TopWindowFrame::Hold()
|
||||
{
|
||||
if(HasCapture()) {
|
||||
if(HasMouse() && GetMouseLeft() && holding)
|
||||
StartDrag();
|
||||
ReleaseCapture();
|
||||
holding = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftHold(Point p, dword keyflags)
|
||||
{
|
||||
if(HasCapture() || FullWindowDrag)
|
||||
return;
|
||||
dir = GetDragMode(p);
|
||||
if(!dir.x && !dir.y)
|
||||
StartDrag();
|
||||
}
|
||||
|
||||
void TopWindowFrame::LeftDouble(Point p, dword keyflags)
|
||||
{
|
||||
ToggleMaximize();
|
||||
IgnoreMouseUp();
|
||||
}
|
||||
|
||||
void TopWindowFrame::MouseMove(Point, dword)
|
||||
{
|
||||
LDUMP(HasWndCapture());
|
||||
LDUMP(HasCapture());
|
||||
if(!HasCapture() || holding)
|
||||
return;
|
||||
Size msz = ComputeClient(minsize).GetSize();
|
||||
Point p = GetMousePos() - startpos;
|
||||
Rect r = startrect;
|
||||
if(dir.x == -1)
|
||||
r.left = min(r.left + p.x, startrect.right - msz.cx);
|
||||
if(dir.x == 1)
|
||||
r.right = max(r.right + p.x, startrect.left + msz.cx);
|
||||
if(dir.y == -1)
|
||||
r.top = min(r.top + p.y, startrect.bottom - msz.cy);
|
||||
if(dir.y == 1)
|
||||
r.bottom = max(r.bottom + p.y, startrect.top + msz.cy);
|
||||
if(dir.y == 0 && dir.x == 0)
|
||||
r.Offset(p);
|
||||
SetRect(r);
|
||||
}
|
||||
|
||||
Image TopWindowFrame::GetDragImage(Point dir)
|
||||
{
|
||||
static Image (*im[9])() = {
|
||||
Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft,
|
||||
Image::SizeTop, Image::Arrow, Image::SizeBottom,
|
||||
Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight,
|
||||
};
|
||||
return (*im[(dir.x + 1) * 3 + (dir.y + 1)])();
|
||||
}
|
||||
|
||||
Image TopWindowFrame::CursorImage(Point p, dword)
|
||||
{
|
||||
if(!sizeable)
|
||||
return Image::Arrow();
|
||||
return GetDragImage(HasCapture() ? dir : GetDragMode(p));
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
75
rainbow/Framebuffer/Util.cpp
Normal file
75
rainbow/Framebuffer/Util.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
/*
|
||||
static void sRenderLine(SystemDraw& w, int x, int y, int dx, int dy, int cx, int cy, int len, byte pattern)
|
||||
{
|
||||
DLOG(len);
|
||||
for(int i = 0; i < len; i++)
|
||||
if((128 >> (i & 7)) & pattern)
|
||||
w.DrawRect(x + dx * i, y + dy * i, cx, cy, Black);
|
||||
DDUMP("~sRenderLine");
|
||||
}
|
||||
|
||||
static void sRenderRect(SystemDraw& w, const Rect& r, int n, byte pattern)
|
||||
{
|
||||
sRenderLine(w, r.left, r.top, 1, 0, 1, n, r.GetWidth(), pattern);
|
||||
sRenderLine(w, r.left, r.bottom - 1, 1, 0, 1, n, r.GetWidth(), pattern);
|
||||
sRenderLine(w, r.left, r.top, 0, 1, n, 1, r.GetHeight(), pattern);
|
||||
sRenderLine(w, r.right - 1, r.top, 0, 1, n, 1, r.GetHeight(), pattern);
|
||||
}
|
||||
|
||||
void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2,
|
||||
const Rect& clip, int n, Color color, uint64 pattern)
|
||||
{
|
||||
DLOG("@ DrawDragRect " << rect1 << " " << rect2 << ", clip: " << clip << ", pattern: " << pattern);
|
||||
TIMING("DrawDrawRect");
|
||||
w.Clip(clip);
|
||||
w.Invert();
|
||||
sRenderRect(w, rect1, n, (byte)pattern);
|
||||
sRenderRect(w, rect2, n, (byte)pattern);
|
||||
Ctrl::AddUpdate((rect1 | rect2).Offseted(w.GetOffset()));
|
||||
// MemoryProfile mem;
|
||||
// DDUMP(mem);
|
||||
w.End();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint64 sGetAniPat(uint64 src, int pos)
|
||||
{
|
||||
uint64 out = 0;
|
||||
pos &= 7;
|
||||
for(int i = 8; --i >= 0;) {
|
||||
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
|
||||
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Size GetScreenSize()
|
||||
{
|
||||
return ScreenInfo().GetPageSize();
|
||||
}
|
||||
*/
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
q.DragRectDraw(rect1, rect2, clip, n, color, type, animation);
|
||||
}
|
||||
|
||||
void FinishDragRect(Ctrl& q)
|
||||
{
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
766
rainbow/Framebuffer/Wnd.cpp
Normal file
766
rainbow/Framebuffer/Wnd.cpp
Normal file
|
|
@ -0,0 +1,766 @@
|
|||
#include "Fb.h"
|
||||
|
||||
#ifdef GUI_FB
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) //DLOG(x)
|
||||
#define LDUMP(x) //DDUMP(x)
|
||||
#define LDUMPC(x) //DDUMPC(x)
|
||||
|
||||
ImageBuffer Ctrl::framebuffer;
|
||||
Vector<Rect> Ctrl::invalid;
|
||||
Vector<Rect> Ctrl::update;
|
||||
|
||||
Ptr<Ctrl> Ctrl::desktop;
|
||||
Vector<Ctrl *> Ctrl::topctrl;
|
||||
|
||||
Point Ctrl::fbCursorPos = Null;
|
||||
Image Ctrl::fbCursorImage;
|
||||
Point Ctrl::fbCursorBakPos = Null;
|
||||
Image Ctrl::fbCursorBak;
|
||||
Rect Ctrl::fbCaretRect;
|
||||
Image Ctrl::fbCaretBak;
|
||||
int Ctrl::fbCaretTm;
|
||||
int Ctrl::renderingMode = MODE_ANTIALIASED;
|
||||
bool Ctrl::fbEndSession;
|
||||
bool Ctrl::FullWindowDrag;
|
||||
int Ctrl::PaintLock;
|
||||
|
||||
void Ctrl::SetDesktop(Ctrl& q)
|
||||
{
|
||||
desktop = &q;
|
||||
desktop->SetRect(framebuffer.GetSize());
|
||||
desktop->SetOpen(true);
|
||||
desktop->NewTop();
|
||||
invalid.Add(framebuffer.GetSize());
|
||||
}
|
||||
|
||||
void Ctrl::SetRenderingMode(int mode)
|
||||
{
|
||||
renderingMode = mode;
|
||||
invalid.Add(framebuffer.GetSize());
|
||||
}
|
||||
|
||||
void Ctrl::InitFB()
|
||||
{
|
||||
Ctrl::GlobalBackBuffer();
|
||||
Ctrl::InitTimer();
|
||||
framebuffer.Create(1, 1);
|
||||
|
||||
#ifdef PLATFORM_POSIX
|
||||
SetStdFont(ScreenSans(12)); //FIXME general handling
|
||||
#endif
|
||||
ChStdSkin();
|
||||
|
||||
static StaticRect x;
|
||||
x.Color(Cyan());
|
||||
SetDesktop(x);
|
||||
}
|
||||
|
||||
void Ctrl::EndSession()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("Ctrl::EndSession");
|
||||
fbEndSession = true;
|
||||
EndSessionLoopNo = EventLoopNo;
|
||||
}
|
||||
|
||||
void Ctrl::ExitFB()
|
||||
{
|
||||
TopWindow::ShutdownWindows();
|
||||
Ctrl::CloseTopCtrls();
|
||||
if(fbEndSession)
|
||||
FBQuitSession();
|
||||
}
|
||||
|
||||
void Ctrl::SetFramebufferSize(Size sz)
|
||||
{
|
||||
framebuffer.Create(sz);
|
||||
if(desktop)
|
||||
desktop->SetRect(sz);
|
||||
invalid.Add(sz);
|
||||
SyncTopWindows();
|
||||
}
|
||||
|
||||
int Ctrl::FindTopCtrl() const
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(this == topctrl[i])
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Ctrl::IsAlphaSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::IsCompositedGui()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<Ctrl *> Ctrl::GetTopCtrls()
|
||||
{
|
||||
Vector<Ctrl *> ctrl;
|
||||
if(desktop)
|
||||
ctrl.Add(desktop);
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(!dynamic_cast<TopWindowFrame *>(topctrl[i]))
|
||||
ctrl.Add(topctrl[i]);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetOwner()
|
||||
{
|
||||
GuiLock __;
|
||||
int q = FindTopCtrl();
|
||||
if(q > 0 && topctrl[q]->top) {
|
||||
Ctrl *x = topctrl[q]->top->owner_window;
|
||||
LDUMP(Upp::Name(x));
|
||||
return dynamic_cast<TopWindowFrame *>(x) ? x->GetOwner() : x;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetActiveCtrl()
|
||||
{
|
||||
GuiLock __;
|
||||
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
|
||||
}
|
||||
|
||||
// Vector<Callback> Ctrl::hotkey;
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Callback cb)
|
||||
{
|
||||
/* ASSERT(key >= K_DELTA);
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= MOD_ALT;
|
||||
if(key & K_SHIFT)
|
||||
mod |= MOD_SHIFT;
|
||||
if(key & K_CTRL)
|
||||
mod |= MOD_CONTROL;
|
||||
|
||||
return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
/* if(id >= 0 && id < hotkey.GetCount()) {
|
||||
UnregisterHotKey(NULL, id);
|
||||
hotkey[id].Clear();
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent()
|
||||
{
|
||||
return FBIsWaitingEvent();
|
||||
}
|
||||
|
||||
void Ctrl::AddUpdate(const Rect& rect)
|
||||
{
|
||||
LLOG("@AddUpdate " << rect);
|
||||
AddRefreshRect(update, rect);
|
||||
}
|
||||
|
||||
void Ctrl::AddInvalid(const Rect& rect)
|
||||
{
|
||||
LLOG("@AddInvalid " << rect);
|
||||
AddRefreshRect(invalid, rect);
|
||||
}
|
||||
|
||||
void Ctrl::SyncTopWindows()
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(topctrl[i]);
|
||||
if(w)
|
||||
w->SyncRect();
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvent(bool *quit)
|
||||
{
|
||||
LLOG("@ ProcessEvent");
|
||||
ASSERT(IsMainThread());
|
||||
if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle())
|
||||
ReleaseCtrlCapture();
|
||||
if(FBProcessEvent(quit)) {
|
||||
LLOG("FBProcesEvent returned true");
|
||||
SyncTopWindows();
|
||||
DefferedFocusSync();
|
||||
SyncCaret();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetClipBound(const Vector<Rect>& inv, const Rect& r)
|
||||
{
|
||||
Rect ri = Null;
|
||||
for(int j = 0; j < inv.GetCount(); j++) {
|
||||
Rect rr = inv[j] & r;
|
||||
if(!rr.IsEmpty())
|
||||
ri = IsNull(ri) ? rr : rr | ri;
|
||||
}
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
ViewDraw::ViewDraw(Ctrl *ctrl)
|
||||
{
|
||||
if(Ctrl::invalid.GetCount())
|
||||
Ctrl::DoPaint();
|
||||
Ctrl::invalid.Clear();
|
||||
Ctrl::RemoveCursor();
|
||||
Ctrl::RemoveCaret();
|
||||
Rect r = ctrl->GetScreenView();
|
||||
Ctrl::invalid.Add(r);
|
||||
Ctrl::AddUpdate(r);
|
||||
for(int i = max(ctrl->GetTopCtrl()->FindTopCtrl() + 1, 0); i < Ctrl::topctrl.GetCount(); i++) {
|
||||
Rect rr = Ctrl::topctrl[i]->GetScreenRect();
|
||||
ExcludeClip(rr);
|
||||
Subtract(Ctrl::invalid, rr);
|
||||
}
|
||||
Offset(r.TopLeft());
|
||||
}
|
||||
|
||||
ViewDraw::~ViewDraw()
|
||||
{
|
||||
FBInitUpdate();
|
||||
Ctrl::DoUpdate();
|
||||
FBFlush();
|
||||
// Ctrl::invalid.Clear();
|
||||
}
|
||||
|
||||
void Ctrl::DoUpdate()
|
||||
{
|
||||
LLOG("DoUpdate");
|
||||
invalid.Clear();
|
||||
CursorSync();
|
||||
LDUMPC(update);
|
||||
#if 0
|
||||
FBUpdate(framebuffer.GetSize());
|
||||
#else
|
||||
for(int i = 0; i < update.GetCount(); i++) {
|
||||
LDUMP(update[i]);
|
||||
FBUpdate(update[i]);
|
||||
}
|
||||
#endif
|
||||
update.Clear();
|
||||
// Sleep(1000);
|
||||
}
|
||||
|
||||
Vector<Rect> Ctrl::GetPaintRects()
|
||||
{
|
||||
Vector<Rect> r;
|
||||
r.Add(GetScreenRect());
|
||||
for(int i = max(FindTopCtrl() + 1, 0); i < topctrl.GetCount(); i++)
|
||||
Subtract(r, topctrl[i]->GetScreenRect());
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void DDRect(RGBA *t, int dir, const byte *pattern, int pos, int count)
|
||||
{
|
||||
while(count-- > 0) {
|
||||
byte p = pattern[7 & pos++];
|
||||
t->r ^= p;
|
||||
t->g ^= p;
|
||||
t->b ^= p;
|
||||
t += dir;
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz, const byte *pattern, int animation)
|
||||
{
|
||||
if(cx <= 0 || cy <= 0)
|
||||
return;
|
||||
Vector<Rect> rr = Intersection(clip, RectC(x, y, cx, cy));
|
||||
for(int i = 0; i < rr.GetCount(); i++) {
|
||||
Rect r = rr[i];
|
||||
AddUpdate(r);
|
||||
if(horz)
|
||||
for(int y = r.top; y < r.bottom; y++)
|
||||
DDRect(framebuffer[y] + r.left, 1, pattern, r.left + animation, r.GetWidth());
|
||||
else
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
DDRect(framebuffer[r.top] + x, framebuffer.GetWidth(), pattern, r.top + animation, r.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::DragRectDraw0(const Vector<Rect>& clip, const Rect& rect, int n, const byte *pattern, int animation)
|
||||
{
|
||||
int hn = min(rect.GetHeight(), n);
|
||||
int vn = min(rect.GetWidth(), n);
|
||||
DrawLine(clip, rect.left, rect.top, rect.GetWidth(), hn, true, pattern, animation);
|
||||
DrawLine(clip, rect.left, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation);
|
||||
DrawLine(clip, rect.right - vn, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation);
|
||||
DrawLine(clip, rect.left + vn, rect.bottom - hn, rect.GetWidth() - 2 * vn, hn, true, pattern, animation);
|
||||
}
|
||||
|
||||
void Ctrl::DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
static byte solid[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
static byte normal[] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
static byte dashed[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
Point p = GetScreenView().TopLeft();
|
||||
Vector<Rect> pr;
|
||||
if(type & DRAWDRAGRECT_SCREEN) {
|
||||
pr.Add(Rect(framebuffer.GetSize()));
|
||||
type &= ~DRAWDRAGRECT_SCREEN;
|
||||
p = Point(0, 0);
|
||||
}
|
||||
else
|
||||
pr = Intersection(GetPaintRects(), clip.Offseted(p));
|
||||
const byte *pattern = type == DRAWDRAGRECT_DASHED ? dashed :
|
||||
type == DRAWDRAGRECT_NORMAL ? normal : solid;
|
||||
RemoveCursor();
|
||||
RemoveCaret();
|
||||
DragRectDraw0(pr, rect1.Offseted(p), n, pattern, animation);
|
||||
DragRectDraw0(pr, rect2.Offseted(p), n, pattern, animation);
|
||||
}
|
||||
|
||||
void Ctrl::DoPaint()
|
||||
{
|
||||
LLOG("@ DoPaint");
|
||||
if(!PaintLock) {
|
||||
bool scroll = false;
|
||||
if(desktop)
|
||||
desktop->SyncScroll();
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
topctrl[i]->SyncScroll();
|
||||
if((invalid.GetCount() || scroll) && desktop) {
|
||||
RemoveCursor();
|
||||
RemoveCaret();
|
||||
for(int phase = 0; phase < 2; phase++) {
|
||||
LLOG("DoPaint invalid phase " << phase);
|
||||
LDUMPC(invalid);
|
||||
SystemDraw painter;
|
||||
painter.Begin();
|
||||
for(int i = 0; i < invalid.GetCount(); i++) {
|
||||
painter.RectPath(invalid[i]);
|
||||
AddUpdate(invalid[i]);
|
||||
}
|
||||
painter.Painter::Clip();
|
||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||
Rect r = topctrl[i]->GetRect();
|
||||
Rect ri = GetClipBound(invalid, r);
|
||||
if(!IsNull(ri)) {
|
||||
painter.Clipoff(r);
|
||||
topctrl[i]->UpdateArea(painter, ri - r.TopLeft());
|
||||
painter.End();
|
||||
Subtract(invalid, r);
|
||||
painter.ExcludeClip(r);
|
||||
}
|
||||
}
|
||||
Rect ri = GetClipBound(invalid, framebuffer.GetSize());
|
||||
if(!IsNull(ri))
|
||||
desktop->UpdateArea(painter, ri);
|
||||
}
|
||||
}
|
||||
}
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
Rect rr = r + GetRect().TopLeft();
|
||||
bool dummy;
|
||||
Vector<Rect> h;
|
||||
h <<= invalid;
|
||||
invalid = Intersect(invalid, rr, dummy);
|
||||
FBInitUpdate();
|
||||
DoPaint();
|
||||
invalid <<= h;
|
||||
Subtract(invalid, rr);
|
||||
FBFlush();
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvents(bool *quit)
|
||||
{
|
||||
//LOGBLOCK("@ ProcessEvents");
|
||||
// MemoryCheckDebug();
|
||||
if(!ProcessEvent(quit))
|
||||
return false;
|
||||
while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop()));
|
||||
TimeStop tm;
|
||||
TimerProc(GetTickCount());
|
||||
LLOG("TimerProc elapsed: " << tm);
|
||||
SweepMkImageCache();
|
||||
FBInitUpdate();
|
||||
DoPaint();
|
||||
FBFlush();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ctrl::EventLoop(Ctrl *ctrl)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT(LoopLevel == 0 || ctrl);
|
||||
LoopLevel++;
|
||||
LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
|
||||
Ptr<Ctrl> ploop;
|
||||
if(ctrl) {
|
||||
ploop = LoopCtrl;
|
||||
LoopCtrl = ctrl;
|
||||
ctrl->inloop = true;
|
||||
}
|
||||
|
||||
bool quit = false;
|
||||
int64 loopno = ++EventLoopNo;
|
||||
ProcessEvents(&quit);
|
||||
while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()))
|
||||
{
|
||||
// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep");
|
||||
SyncCaret();
|
||||
GuiSleep(20);
|
||||
// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents");
|
||||
ProcessEvents(&quit);
|
||||
// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents");
|
||||
LDUMP(loopno);
|
||||
LDUMP(fbEndSessionLoop);
|
||||
}
|
||||
|
||||
if(ctrl)
|
||||
LoopCtrl = ploop;
|
||||
LoopLevel--;
|
||||
LLOG(LOG_END << "Leaving event loop ");
|
||||
}
|
||||
|
||||
void Ctrl::GuiSleep(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
LLOG("GuiSleep");
|
||||
int level = LeaveGuiMutexAll();
|
||||
FBSleep(ms);
|
||||
EnterGuiMutex(level);
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWndScreenRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
return GetRect();
|
||||
}
|
||||
|
||||
void Ctrl::WndShow(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate()
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndOpen() const {
|
||||
GuiLock __;
|
||||
return FindTopCtrl() >= 0 || this == desktop;
|
||||
}
|
||||
|
||||
void Ctrl::SetAlpha(byte alpha)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea() const
|
||||
{
|
||||
GuiLock __;
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
void Ctrl::GetWorkArea(Array<Rect>& rc)
|
||||
{
|
||||
GuiLock __;
|
||||
Array<Rect> r;
|
||||
r.Add(framebuffer.GetSize());
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualWorkArea()
|
||||
{
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea(Point pt)
|
||||
{
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualScreenArea()
|
||||
{
|
||||
GuiLock __;
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryWorkArea()
|
||||
{
|
||||
Rect r;
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryScreenArea()
|
||||
{
|
||||
return framebuffer.GetSize();
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdDelay()
|
||||
{
|
||||
GuiLock __;
|
||||
return 500;
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdSpeed()
|
||||
{
|
||||
GuiLock __;
|
||||
return 1000 / 32;
|
||||
}
|
||||
|
||||
void Ctrl::DestroyWnd()
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i]->top && topctrl[i]->top->owner_window == this)
|
||||
topctrl[i]->WndDestroy();
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0) {
|
||||
AddInvalid(GetRect());
|
||||
topctrl.Remove(q);
|
||||
}
|
||||
if(top) {
|
||||
delete top;
|
||||
top = NULL;
|
||||
}
|
||||
isopen = false;
|
||||
TopWindow *win = dynamic_cast<TopWindow *>(this);
|
||||
if(win)
|
||||
win->DestroyFrame();
|
||||
}
|
||||
|
||||
void Ctrl::WndDestroy()
|
||||
{
|
||||
DestroyWnd();
|
||||
if(topctrl.GetCount())
|
||||
topctrl.Top()->ActivateWnd();
|
||||
}
|
||||
|
||||
void Ctrl::PutForeground()
|
||||
{
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0) {
|
||||
AddInvalid(GetRect());
|
||||
topctrl.Remove(q);
|
||||
topctrl.Add(this);
|
||||
}
|
||||
Vector< Ptr<Ctrl> > fw;
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i] && topctrl[i]->top && topctrl[i]->top->owner_window == this && topctrl[i] != this)
|
||||
fw.Add(topctrl[i]);
|
||||
for(int i = 0; i < fw.GetCount(); i++)
|
||||
if(fw[i])
|
||||
fw[i]->PutForeground();
|
||||
}
|
||||
|
||||
void Ctrl::SetWndForeground()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsOpen());
|
||||
if(IsWndForeground())
|
||||
return;
|
||||
Ctrl *to = this;
|
||||
while(to->top && to->top->owner_window)
|
||||
to = to->top->owner_window;
|
||||
to->PutForeground();
|
||||
if(this != focusCtrl)
|
||||
ActivateWnd();
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndForeground() const
|
||||
{
|
||||
GuiLock __;
|
||||
bool b = false;
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
const TopWindow *tw = dynamic_cast<const TopWindow *>(topctrl[i]);
|
||||
if(tw)
|
||||
b = tw == this;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void Ctrl::WndEnable(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndFocus() const
|
||||
{
|
||||
GuiLock __;
|
||||
return focusCtrl && focusCtrl->GetTopCtrl() == this;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndCapture()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::ReleaseWndCapture()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndCapture() const
|
||||
{
|
||||
GuiLock __;
|
||||
return captureCtrl && captureCtrl->GetTopCtrl() == this;
|
||||
}
|
||||
|
||||
void Ctrl::WndInvalidateRect(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0)
|
||||
AddInvalid(r + topctrl[q]->GetRect().TopLeft());
|
||||
else
|
||||
AddInvalid(r);
|
||||
}
|
||||
|
||||
void Ctrl::WndSetPos(const Rect& rect)
|
||||
{
|
||||
GuiLock __;
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(this);
|
||||
if(w)
|
||||
w->SyncFrameRect(rect);
|
||||
invalid.Add(GetRect());
|
||||
SetWndRect(rect);
|
||||
invalid.Add(rect);
|
||||
}
|
||||
|
||||
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
if(dx == 0 && dy == 0)
|
||||
return;
|
||||
if(dx && dy) {
|
||||
Refresh(r);
|
||||
return;
|
||||
}
|
||||
RemoveCursor();
|
||||
RemoveCaret();
|
||||
Rect sr = r.Offseted(GetScreenRect().TopLeft());
|
||||
Vector<Rect> pr = Intersection(GetPaintRects(), sr);
|
||||
for(int i = 0; i < pr.GetCount(); i++) {
|
||||
Rect r = pr[i];
|
||||
if(dx) {
|
||||
int n = r.GetWidth() - abs(dx);
|
||||
if(n > 0) {
|
||||
int to = r.left + dx * (dx > 0);
|
||||
int from = r.left - dx * (dx < 0);
|
||||
for(int y = r.top; y < r.bottom; y++)
|
||||
memmove(framebuffer[y] + to, framebuffer[y] + from, n * sizeof(RGBA));
|
||||
}
|
||||
n = min(abs(dx), r.GetWidth());
|
||||
Refresh(dx < 0 ? r.left : r.right - n, r.top, n, r.GetHeight());
|
||||
}
|
||||
else {
|
||||
int n = r.GetHeight() - abs(dy);
|
||||
for(int y = 0; y < n; y++)
|
||||
memmove(framebuffer[dy < 0 ? r.top + y : r.bottom - 1 - y] + r.left,
|
||||
framebuffer[dy < 0 ? r.top + y - dy : r.bottom - 1 - y - dy] + r.left,
|
||||
r.GetWidth() * sizeof(RGBA));
|
||||
n = min(abs(dy), r.GetHeight());
|
||||
Refresh(r.left, dy < 0 ? r.bottom - n : r.top, r.GetWidth(), n);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<Rect> ur;
|
||||
for(int i = 0; i < invalid.GetCount(); i++)
|
||||
if(invalid[i].Intersects(sr))
|
||||
ur.Add(invalid[i]);
|
||||
for(int i = 0; i < ur.GetCount(); i++)
|
||||
AddInvalid(ur[i].Offseted(dx, dy));
|
||||
}
|
||||
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
|
||||
{
|
||||
ASSERT(!IsChild() && !IsOpen() && FindTopCtrl() < 0);
|
||||
NewTop();
|
||||
if(owner) {
|
||||
Ctrl *owner_window = owner->GetTopWindow();
|
||||
if(!owner_window)
|
||||
owner_window = owner->GetTopCtrl();
|
||||
ASSERT(owner_window->IsOpen());
|
||||
if(owner_window != desktop) {
|
||||
owner_window->SetForeground();
|
||||
top->owner_window = owner_window;
|
||||
}
|
||||
}
|
||||
topctrl.Add(this);
|
||||
popup = isopen = true;
|
||||
RefreshLayoutDeep();
|
||||
if(activate) SetFocusWnd();
|
||||
AddInvalid(GetRect());
|
||||
}
|
||||
|
||||
Rect Ctrl::GetDefaultWindowRect() {
|
||||
GuiLock __;
|
||||
static int ii = 0;
|
||||
Size sz = framebuffer.GetSize();
|
||||
Rect rect = framebuffer.GetSize();
|
||||
rect.Deflate(sz / 10);
|
||||
rect.Offset(Size(GetStdFontCy(), 2 * GetStdFontCy()) * (++ii % 8));
|
||||
return rect;
|
||||
}
|
||||
|
||||
Vector<WString> SplitCmdLine__(const char *cmd)
|
||||
{
|
||||
Vector<WString> out;
|
||||
while(*cmd)
|
||||
if((byte)*cmd <= ' ')
|
||||
cmd++;
|
||||
else if(*cmd == '\"') {
|
||||
WString quoted;
|
||||
while(*++cmd && (*cmd != '\"' || *++cmd == '\"'))
|
||||
quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString());
|
||||
out.Add(quoted);
|
||||
}
|
||||
else {
|
||||
const char *begin = cmd;
|
||||
while((byte)*cmd > ' ')
|
||||
cmd++;
|
||||
out.Add(String(begin, cmd).ToWString());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void Ctrl::InstallPanicBox()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::SysEndLoop()
|
||||
{
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
5
rainbow/Framebuffer/init
Normal file
5
rainbow/Framebuffer/init
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _Framebuffer_icpp_init_stub
|
||||
#define _Framebuffer_icpp_init_stub
|
||||
#include "Painter/init"
|
||||
#include "CtrlLib/init"
|
||||
#endif
|
||||
62
rainbow/Gtk/GdkImage.cpp
Normal file
62
rainbow/Gtk/GdkImage.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void ImageGdk::Free()
|
||||
{
|
||||
if(pixbuf) {
|
||||
g_object_unref(pixbuf);
|
||||
pixbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageGdk::Set(const Image& m)
|
||||
{
|
||||
Free();
|
||||
if(m.GetSerialId() != img.GetSerialId()) {
|
||||
img = Unmultiply(m);
|
||||
if(!IsNull(img)) {
|
||||
Size sz = img.GetSize();
|
||||
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, sz.cx, sz.cy);
|
||||
byte *l = (byte *)gdk_pixbuf_get_pixels(pixbuf);
|
||||
int stride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
const RGBA *s = img[y];
|
||||
const RGBA *e = s + sz.cx;
|
||||
byte *t = l;
|
||||
while(s < e) {
|
||||
*t++ = s->r;
|
||||
*t++ = s->g;
|
||||
*t++ = s->b;
|
||||
*t++ = s->a;
|
||||
s++;
|
||||
}
|
||||
l += stride;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageGdk::ImageGdk(const Image& m)
|
||||
{
|
||||
pixbuf = NULL;
|
||||
Set(m);
|
||||
}
|
||||
|
||||
ImageGdk::ImageGdk()
|
||||
{
|
||||
pixbuf = NULL;
|
||||
}
|
||||
|
||||
ImageGdk::~ImageGdk()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
174
rainbow/Gtk/Gtk.h
Normal file
174
rainbow/Gtk/Gtk.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#define GUI_GTK
|
||||
|
||||
#define PLATFORM_X11 // To keep legacy code happy
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class SystemDraw : public Draw {
|
||||
virtual dword GetInfo() const;
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool ExcludeClipOp(const Rect& r);
|
||||
virtual bool IntersectClipOp(const Rect& r);
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
virtual Rect GetPaintRect() const;
|
||||
|
||||
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
virtual void SysDrawImageOp(int x, int y, const Image& img, Color color);
|
||||
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
|
||||
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor);
|
||||
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor);
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
|
||||
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx);
|
||||
|
||||
|
||||
private:
|
||||
void RectPath(const Rect& r);
|
||||
void Push();
|
||||
void Pop();
|
||||
Vector<Point> offset;
|
||||
|
||||
cairo_t *cr;
|
||||
SystemDraw() {}
|
||||
|
||||
friend class ImageDraw;
|
||||
friend class BackDraw;
|
||||
friend class ViewDraw;
|
||||
|
||||
public:
|
||||
void SetColor(Color c);
|
||||
operator cairo_t*() { return cr; }
|
||||
|
||||
Point GetOffset() const;
|
||||
bool CanSetSurface() { return false; } // TODO?
|
||||
static void Flush() {} // TODO?
|
||||
|
||||
SystemDraw(cairo_t *cr) : cr(cr) {}
|
||||
};
|
||||
|
||||
class ImageDraw : public SystemDraw {
|
||||
cairo_surface_t *surface;
|
||||
Size isz;
|
||||
|
||||
SystemDraw alpha;
|
||||
cairo_surface_t *alpha_surface;
|
||||
bool del;
|
||||
|
||||
void Init(Size sz);
|
||||
void FetchStraight(ImageBuffer& b) const;
|
||||
|
||||
public:
|
||||
Draw& Alpha();
|
||||
|
||||
operator Image() const;
|
||||
|
||||
Image GetStraight() const;
|
||||
|
||||
ImageDraw(Size sz);
|
||||
ImageDraw(int cx, int cy);
|
||||
~ImageDraw();
|
||||
|
||||
ImageDraw(cairo_t *cr, Size sz); // Special variant for chameleon skinning
|
||||
};
|
||||
|
||||
class BackDraw : public SystemDraw {
|
||||
Size size;
|
||||
Draw *painting;
|
||||
Point painting_offset;
|
||||
|
||||
public:
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
public:
|
||||
void Put(SystemDraw& w, int x, int y);
|
||||
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
|
||||
|
||||
void Create(SystemDraw& w, int cx, int cy);
|
||||
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
|
||||
void Destroy();
|
||||
|
||||
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
|
||||
|
||||
BackDraw();
|
||||
~BackDraw();
|
||||
};
|
||||
|
||||
struct GdkRect : GdkRectangle {
|
||||
operator GdkRectangle *() { return this; }
|
||||
GdkRect(const Rect& r);
|
||||
};
|
||||
|
||||
class ImageGdk {
|
||||
GdkPixbuf *pixbuf;
|
||||
Image img;
|
||||
|
||||
void Free();
|
||||
|
||||
public:
|
||||
operator GdkPixbuf *() { return pixbuf; }
|
||||
|
||||
bool Set(const Image& m);
|
||||
|
||||
ImageGdk();
|
||||
ImageGdk(const Image& m);
|
||||
~ImageGdk();
|
||||
};
|
||||
|
||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf);
|
||||
|
||||
GdkAtom GAtom(const String& id);
|
||||
|
||||
struct DrawDragRectInfo {
|
||||
Rect rect1, rect2, clip;
|
||||
int n;
|
||||
Color color;
|
||||
int type;
|
||||
int animation;
|
||||
};
|
||||
|
||||
#ifndef PLATFORM_WIN32
|
||||
#include <CtrlCore/stdids.h>
|
||||
#endif
|
||||
|
||||
#define GUIPLATFORM_KEYCODES_INCLUDE <Gtk/GtkKeys.h>
|
||||
|
||||
//$ struct Ctrl::Top {
|
||||
#define GUIPLATFORM_CTRL_TOP_DECLS \
|
||||
GtkWidget *window; \
|
||||
GtkIMContext *im_context; \
|
||||
int64 cursor_id; \
|
||||
One<DrawDragRectInfo> dr; \
|
||||
int id; \
|
||||
//$ }
|
||||
|
||||
#define GUIPLATFORM_CTRL_DECLS_INCLUDE <Gtk/GtkCtrl.h>
|
||||
|
||||
#define GUIPLATFORM_PASTECLIP_DECLS \
|
||||
int type; \
|
||||
|
||||
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Gtk/GtkTop.h>
|
||||
|
||||
#define GUIPLATFORM_NOSCROLL
|
||||
|
||||
int rmsecs();
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#define GUIPLATFORM_INCLUDE_AFTER <Gtk/GtkAfter.h>
|
||||
23
rainbow/Gtk/Gtk.upp
Normal file
23
rainbow/Gtk/Gtk.upp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
description "Gtk backend\377";
|
||||
|
||||
file
|
||||
Gtk.h,
|
||||
GtkAfter.h,
|
||||
GtkKeys.h,
|
||||
GtkDrawOp.cpp,
|
||||
GtkDrawText.cpp,
|
||||
GtkDrawImage.cpp,
|
||||
GtkUtil.cpp,
|
||||
GdkImage.cpp,
|
||||
GtkCtrl.h,
|
||||
GtkCtrl.cpp,
|
||||
GtkWnd.cpp,
|
||||
GtkCreate.cpp,
|
||||
GtkCapture.cpp,
|
||||
GtkEvent.cpp,
|
||||
GtkApp.cpp,
|
||||
GtkTop.h,
|
||||
GtkTop.cpp,
|
||||
GtkClip.cpp,
|
||||
GtkDnD.cpp;
|
||||
|
||||
25
rainbow/Gtk/GtkAfter.h
Normal file
25
rainbow/Gtk/GtkAfter.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
class ViewDraw : public SystemDraw {
|
||||
public:
|
||||
ViewDraw(Ctrl *ctrl);
|
||||
~ViewDraw();
|
||||
};
|
||||
|
||||
void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f);
|
||||
|
||||
class DHCtrl : Ctrl {};
|
||||
|
||||
void InitGtkApp(int argc, char **argv, const char **envptr);
|
||||
|
||||
#define GUI_APP_MAIN \
|
||||
void GuiMainFn_(); \
|
||||
\
|
||||
int main(int argc, char **argv, const char **envptr) { \
|
||||
UPP::AppInit__(argc, (const char **)argv, envptr); \
|
||||
UPP::InitGtkApp(argc, argv, envptr); \
|
||||
GuiMainFn_(); \
|
||||
UPP::Ctrl::CloseTopCtrls(); \
|
||||
UPP::AppExit__(); \
|
||||
return UPP::GetExitCode(); \
|
||||
} \
|
||||
\
|
||||
void GuiMainFn_()
|
||||
43
rainbow/Gtk/GtkApp.cpp
Normal file
43
rainbow/Gtk/GtkApp.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void _DBG_Ungrab(void)
|
||||
{
|
||||
gdk_pointer_ungrab(GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
void Ctrl::PanicMsgBox(const char *title, const char *text)
|
||||
{
|
||||
LLOG("PanicMsgBox " << title << ": " << text);
|
||||
_DBG_Ungrab();
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE, "%s: %s", title, text);
|
||||
gtk_dialog_run(GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
__BREAK__;
|
||||
}
|
||||
|
||||
void InitGtkApp(int argc, char **argv, const char **envptr)
|
||||
{
|
||||
gtk_init(&argc, &argv); // TODO?
|
||||
Ctrl::GlobalBackBuffer();
|
||||
Ctrl::ReSkin();
|
||||
g_timeout_add(20, (GSourceFunc) Ctrl::TimeHandler, NULL);
|
||||
InstallPanicMessageBox(Ctrl::PanicMsgBox);
|
||||
}
|
||||
/*
|
||||
void ChSysInit()
|
||||
{
|
||||
CtrlImg::Reset();
|
||||
CtrlsImg::Reset();
|
||||
ChReset();
|
||||
}
|
||||
*/
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
77
rainbow/Gtk/GtkCapture.cpp
Normal file
77
rainbow/Gtk/GtkCapture.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
Ptr<Ctrl> Ctrl::grabwindow;
|
||||
Ptr<Ctrl> Ctrl::grabpopup;
|
||||
|
||||
void Ctrl::StopGrabPopup()
|
||||
{
|
||||
if(grabpopup && gdk_pointer_is_grabbed()) {
|
||||
gdk_pointer_ungrab(CurrentTime);
|
||||
grabpopup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::StartGrabPopup()
|
||||
{
|
||||
if(activePopup.GetCount() && !grabpopup) {
|
||||
Ctrl *w = activePopup[0];
|
||||
if(w) {
|
||||
ReleaseWndCapture0();
|
||||
if(gdk_pointer_grab(w->gdk(), FALSE,
|
||||
GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK),
|
||||
NULL, NULL, CurrentTime) == GDK_GRAB_SUCCESS)
|
||||
grabpopup = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndCapture()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
LLOG("SetWndCapture " << Name());
|
||||
StopGrabPopup();
|
||||
ReleaseWndCapture();
|
||||
if(gdk_pointer_grab(gdk(), FALSE,
|
||||
GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK),
|
||||
NULL, NULL, CurrentTime) == GDK_GRAB_SUCCESS) {
|
||||
grabwindow = this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::ReleaseWndCapture0()
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
LLOG("ReleaseWndCapture");
|
||||
if(grabwindow) {
|
||||
gdk_pointer_ungrab(CurrentTime);
|
||||
grabwindow = NULL;
|
||||
StartGrabPopup();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::ReleaseWndCapture()
|
||||
{
|
||||
return ReleaseWndCapture0();
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndCapture() const
|
||||
{
|
||||
GuiLock __;
|
||||
return this == grabwindow && gdk_pointer_is_grabbed();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
376
rainbow/Gtk/GtkClip.cpp
Normal file
376
rainbow/Gtk/GtkClip.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
#include <plugin/bmp/bmp.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void Ctrl::GtkSelectionDataSet(GtkSelectionData *selection_data, const String& fmt, const String& data)
|
||||
{
|
||||
if(fmt == "text") {
|
||||
String s = data;
|
||||
gtk_selection_data_set_text(selection_data, (const gchar*)~s, s.GetCount());
|
||||
}
|
||||
else
|
||||
if(fmt == "image") {
|
||||
Image img;
|
||||
if(IsString(data))
|
||||
LoadFromString(img, data);
|
||||
if(!IsNull(img)) {
|
||||
ImageGdk m(img);
|
||||
gtk_selection_data_set_pixbuf(selection_data, m);
|
||||
}
|
||||
}
|
||||
else {
|
||||
String s = data;
|
||||
gtk_selection_data_set(selection_data, GAtom(fmt), 8, (const guchar*)~s, s.GetCount());
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::GtkGetClipData(GtkClipboard *clipboard, GtkSelectionData *selection_data,
|
||||
guint info, gpointer user_data)
|
||||
{
|
||||
ArrayMap<String, ClipData>& target = *(ArrayMap<String, ClipData> *)user_data;
|
||||
LLOG("GtkGetClipData for " << target.GetKey(info));
|
||||
GtkSelectionDataSet(selection_data, target.GetKey(info), target[info].Render());
|
||||
}
|
||||
|
||||
void ClearClipData(GtkClipboard *clipboard, gpointer) {}
|
||||
|
||||
Ctrl::Gclipboard::Gclipboard(GdkAtom type)
|
||||
{
|
||||
clipboard = gtk_clipboard_get(type);
|
||||
}
|
||||
|
||||
void Ctrl::AddFmt(GtkTargetList *list, const String& fmt, int info)
|
||||
{
|
||||
if(fmt == "text")
|
||||
gtk_target_list_add_text_targets(list, info);
|
||||
else
|
||||
if(fmt == "image")
|
||||
gtk_target_list_add_image_targets(list, info, TRUE);
|
||||
else
|
||||
gtk_target_list_add(list, GAtom(fmt), 0, info);
|
||||
}
|
||||
|
||||
GtkTargetList *Ctrl::CreateTargetList(const VectorMap<String, ClipData>& target)
|
||||
{
|
||||
GtkTargetList *list = gtk_target_list_new(NULL, 0);
|
||||
for(int i = 0; i < target.GetCount(); i++)
|
||||
AddFmt(list, target.GetKey(i), i);
|
||||
return list;
|
||||
}
|
||||
|
||||
void Ctrl::Gclipboard::Put(const String& fmt, const ClipData& data)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("Gclipboard::Put " << fmt);
|
||||
|
||||
target.GetAdd(fmt) = data;
|
||||
|
||||
GtkTargetList *list = CreateTargetList(target);
|
||||
|
||||
gint n;
|
||||
GtkTargetEntry *targets = gtk_target_table_new_from_list(list, &n);
|
||||
|
||||
gtk_clipboard_set_with_data(clipboard, targets, n, GtkGetClipData, ClearClipData, &target);
|
||||
gtk_clipboard_set_can_store(clipboard, NULL, 0);
|
||||
|
||||
gtk_target_table_free(targets, n);
|
||||
gtk_target_list_unref(list);
|
||||
}
|
||||
|
||||
String Ctrl::GtkDataGet(GtkSelectionData *s)
|
||||
{
|
||||
if(!s)
|
||||
return Null;
|
||||
const guchar *b = gtk_selection_data_get_data(s);
|
||||
int n = gtk_selection_data_get_length(s);
|
||||
return n >= 0 && b ? String(b, n) : String();
|
||||
}
|
||||
|
||||
String Ctrl::Gclipboard::Get(const String& fmt)
|
||||
{
|
||||
if(fmt == "text") {
|
||||
gchar *s = gtk_clipboard_wait_for_text(clipboard);
|
||||
if(s) {
|
||||
String h = s;
|
||||
g_free(s);
|
||||
return h;
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
else
|
||||
if(fmt == "image") {
|
||||
Image img = ImageFromPixbufUnref(gtk_clipboard_wait_for_image(clipboard));
|
||||
return StoreAsString(img); // Not very optimal...
|
||||
}
|
||||
else
|
||||
return GtkDataGet(gtk_clipboard_wait_for_contents(clipboard, GAtom(fmt)));
|
||||
}
|
||||
|
||||
bool Ctrl::Gclipboard::IsAvailable(const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return gtk_clipboard_wait_is_text_available(clipboard);
|
||||
if(fmt == "image")
|
||||
return gtk_clipboard_wait_is_image_available(clipboard);
|
||||
return gtk_clipboard_wait_is_target_available(clipboard, GAtom(fmt));
|
||||
}
|
||||
|
||||
bool PasteClip::IsAvailable(const char *fmt) const
|
||||
{
|
||||
LLOG("PasteClip::IsAvailable " << fmt << ", type: " << type);
|
||||
if(type == 1)
|
||||
return Ctrl::IsDragAvailable(fmt);
|
||||
return (type == 0 ? Ctrl::gclipboard() : Ctrl::gselection()).IsAvailable(fmt);
|
||||
}
|
||||
|
||||
String PasteClip::Get(const char *fmt) const
|
||||
{
|
||||
LLOG("PasteClip::Get " << fmt << ", type: " << type);
|
||||
if(type == 1)
|
||||
return Ctrl::DragGet(fmt);
|
||||
return (type == 0 ? Ctrl::gclipboard() : Ctrl::gselection()).Get(fmt);
|
||||
}
|
||||
|
||||
void PasteClip::GuiPlatformConstruct()
|
||||
{
|
||||
type = 0;
|
||||
}
|
||||
|
||||
void Ctrl::Gclipboard::Clear()
|
||||
{
|
||||
gtk_clipboard_clear(clipboard);
|
||||
target.Clear();
|
||||
}
|
||||
|
||||
void ClearClipboard()
|
||||
{
|
||||
Ctrl::gclipboard().Clear();
|
||||
}
|
||||
|
||||
Ctrl::Gclipboard& Ctrl::gclipboard()
|
||||
{
|
||||
GuiLock __;
|
||||
static Gclipboard c(GDK_SELECTION_CLIPBOARD);
|
||||
return c;
|
||||
}
|
||||
|
||||
Ctrl::Gclipboard& Ctrl::gselection()
|
||||
{
|
||||
GuiLock __;
|
||||
static Gclipboard c(GDK_SELECTION_PRIMARY);
|
||||
return c;
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value& data))
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("AppendClipboard " << format);
|
||||
Vector<String> s = Split(format, ';');
|
||||
for(int i = 0; i < s.GetCount(); i++)
|
||||
Ctrl::gclipboard().Put(s[i], ClipData(data, render));
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const byte *data, int length)
|
||||
{
|
||||
GuiLock __;
|
||||
AppendClipboard(format, String(data, length));
|
||||
}
|
||||
|
||||
void AppendClipboard(const char *format, const String& data)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("AppendClipboard " << format);
|
||||
Vector<String> s = Split(format, ';');
|
||||
for(int i = 0; i < s.GetCount(); i++)
|
||||
Ctrl::gclipboard().Put(s[i], ClipData(data));
|
||||
}
|
||||
|
||||
String ReadClipboard(const char *format)
|
||||
{
|
||||
GuiLock __;
|
||||
return Null;
|
||||
}
|
||||
|
||||
const char *ClipFmtsText()
|
||||
{
|
||||
GuiLock __;
|
||||
return "text";
|
||||
}
|
||||
|
||||
void AppendClipboardUnicodeText(const WString& s)
|
||||
{
|
||||
AppendClipboard(ClipFmtsText(), Value(ToUtf8(s)), NULL);
|
||||
}
|
||||
|
||||
void AppendClipboardText(const String& s)
|
||||
{
|
||||
AppendClipboard(ClipFmtsText(), Value(ToCharset(CHARSET_UTF8, s)), NULL);
|
||||
}
|
||||
|
||||
String GetString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.IsAvailable("text"))
|
||||
return ToCharset(CHARSET_DEFAULT, clip.Get("text"), CHARSET_UTF8);
|
||||
return Null;
|
||||
}
|
||||
|
||||
WString GetWString(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
if(clip.IsAvailable("text"))
|
||||
return FromUtf8(clip.Get("text"));
|
||||
return Null;
|
||||
}
|
||||
|
||||
|
||||
bool AcceptText(PasteClip& clip)
|
||||
{
|
||||
return clip.Accept(ClipFmtsText());
|
||||
}
|
||||
|
||||
static String sText(const Value& data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const String& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(ToCharset(CHARSET_UTF8, text), sText));
|
||||
}
|
||||
|
||||
void Append(VectorMap<String, ClipData>& data, const WString& text)
|
||||
{
|
||||
data.GetAdd("text", ClipData(ToUtf8(text), sText));
|
||||
}
|
||||
|
||||
String GetTextClip(const WString& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return ToUtf8(text);
|
||||
return Null;
|
||||
}
|
||||
|
||||
String GetTextClip(const String& text, const String& fmt)
|
||||
{
|
||||
if(fmt == "text")
|
||||
return ToCharset(CHARSET_UTF8, text);
|
||||
return Null;
|
||||
}
|
||||
|
||||
String ReadClipboardText()
|
||||
{
|
||||
return ToCharset(CHARSET_DEFAULT, Ctrl::gclipboard().Get("text"), CHARSET_UTF8);
|
||||
}
|
||||
|
||||
WString ReadClipboardUnicodeText()
|
||||
{
|
||||
return FromUtf8(Ctrl::gclipboard().Get("text"));
|
||||
}
|
||||
|
||||
bool IsClipboardAvailable(const char *id)
|
||||
{
|
||||
return Ctrl::gclipboard().IsAvailable(id);
|
||||
}
|
||||
|
||||
bool IsClipboardAvailableText()
|
||||
{
|
||||
return Ctrl::gclipboard().IsAvailable("text");
|
||||
}
|
||||
|
||||
const char *ClipFmtsImage()
|
||||
{
|
||||
return "image";
|
||||
}
|
||||
|
||||
bool AcceptImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
return clip.Accept("image");
|
||||
}
|
||||
|
||||
Image GetImage(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Image m;
|
||||
LoadFromString(m, clip.Get("image"));
|
||||
return m;
|
||||
}
|
||||
|
||||
Image ReadClipboardImage()
|
||||
{
|
||||
GuiLock __;
|
||||
Image m;
|
||||
LoadFromString(m, Ctrl::gclipboard().Get("image"));
|
||||
return m;
|
||||
}
|
||||
|
||||
String GetImageClip(const Image& m, const String& fmt)
|
||||
{
|
||||
Image h = m;
|
||||
if(fmt == "image")
|
||||
return StoreAsString(h);
|
||||
return Null;
|
||||
}
|
||||
|
||||
void AppendClipboardImage(const Image& img)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.IsEmpty()) return;
|
||||
Image h = img;
|
||||
AppendClipboard("image", StoreAsString(h));
|
||||
}
|
||||
|
||||
bool AcceptFiles(PasteClip& clip)
|
||||
{
|
||||
if(clip.Accept("files")) {
|
||||
clip.SetAction(DND_COPY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAvailableFiles(PasteClip& clip)
|
||||
{
|
||||
return clip.IsAvailable("files");
|
||||
}
|
||||
|
||||
// TODO:
|
||||
Vector<String> GetFiles(PasteClip& clip)
|
||||
{
|
||||
GuiLock __;
|
||||
Vector<String> f;
|
||||
return f;
|
||||
}
|
||||
|
||||
Ptr<Ctrl> Ctrl::sel_ctrl;
|
||||
|
||||
void Ctrl::GuiPlatformSelection(PasteClip& d)
|
||||
{
|
||||
d.fmt.Clear();
|
||||
d.type = 2;
|
||||
}
|
||||
|
||||
String Ctrl::RenderPrimarySelection(const Value& fmt)
|
||||
{
|
||||
return sel_ctrl->GetSelectionData(fmt);
|
||||
}
|
||||
|
||||
void Ctrl::SetSelectionSource(const char *fmts)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetSelectionSource " << UPP::Name(this) << ": " << fmts);
|
||||
Vector<String> s = Split(fmts, ';');
|
||||
sel_ctrl = this;
|
||||
for(int i = 0; i < s.GetCount(); i++)
|
||||
gselection().Put(s[i], ClipData(s[i], RenderPrimarySelection));
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
119
rainbow/Gtk/GtkCreate.cpp
Normal file
119
rainbow/Gtk/GtkCreate.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void Ctrl::Create(Ctrl *owner, bool popup)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
LLOG("Create " << Name() << " " << GetRect());
|
||||
ASSERT(!IsChild() && !IsOpen());
|
||||
LLOG("Ungrab1");
|
||||
|
||||
top = new Top;
|
||||
top->window = gtk_window_new(popup ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
|
||||
top->owner = owner;
|
||||
|
||||
static int id;
|
||||
top->id = ++id;
|
||||
|
||||
Win& w = wins.Add();
|
||||
w.id = top->id;
|
||||
w.ctrl = this;
|
||||
w.gtk = top->window;
|
||||
w.gdk = top->window->window;
|
||||
|
||||
TopWindow *tw = dynamic_cast<TopWindow *>(this);
|
||||
gtk_window_set_type_hint(gtk(), popup ? GDK_WINDOW_TYPE_HINT_COMBO
|
||||
: tw && tw->tool ? GDK_WINDOW_TYPE_HINT_UTILITY
|
||||
: owner ? GDK_WINDOW_TYPE_HINT_DIALOG
|
||||
: GDK_WINDOW_TYPE_HINT_NORMAL);
|
||||
|
||||
top->cursor_id = -1;
|
||||
|
||||
gtk_widget_set_events(top->window, 0xffffffff);
|
||||
g_signal_connect(top->window, "event", G_CALLBACK(GtkEvent), (gpointer)(uintptr_t)top->id);
|
||||
|
||||
gtk_widget_realize(top->window);
|
||||
|
||||
Rect r = GetRect();
|
||||
gtk_window_move(gtk(), r.left, r.top);
|
||||
gtk_window_resize(gtk(), r.GetWidth(), r.GetHeight());
|
||||
|
||||
if(owner && owner->top)
|
||||
gtk_window_set_transient_for(gtk(), owner->gtk());
|
||||
gtk_widget_set_app_paintable(top->window, TRUE);
|
||||
gtk_widget_set_can_focus(top->window, TRUE);
|
||||
isopen = true;
|
||||
|
||||
top->im_context = gtk_im_multicontext_new();
|
||||
gtk_im_context_set_client_window(top->im_context, gdk());
|
||||
gtk_im_context_set_use_preedit(top->im_context, false);
|
||||
g_signal_connect(top->im_context, "commit", G_CALLBACK(IMCommit), (gpointer)(uintptr_t)top->id);
|
||||
|
||||
WndShow(IsShown());
|
||||
|
||||
FocusSync();
|
||||
if(!popup)
|
||||
SetWndFocus();
|
||||
|
||||
DndInit();
|
||||
|
||||
StateH(OPEN);
|
||||
}
|
||||
|
||||
void Ctrl::WndDestroy0()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndDestroy " << Name());
|
||||
DndExit();
|
||||
gtk_widget_destroy(top->window);
|
||||
g_object_unref(top->im_context);
|
||||
isopen = false;
|
||||
popup = false;
|
||||
delete top;
|
||||
top = NULL;
|
||||
int q = FindCtrl(this);
|
||||
if(q >= 0)
|
||||
wins.Remove(q);
|
||||
}
|
||||
|
||||
Vector< Ptr<Ctrl> > Ctrl::activePopup;
|
||||
|
||||
void Ctrl::GuiPlatformRemove()
|
||||
{
|
||||
for(int i = 0; i < activePopup.GetCount();)
|
||||
if(activePopup[i] == this) {
|
||||
if(this == grabpopup && gdk_pointer_is_grabbed())
|
||||
StopGrabPopup();
|
||||
activePopup.Remove(i);
|
||||
StartGrabPopup();
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("POPUP " << Name() << ", " << GetRect() << ", activate " << activate);
|
||||
Create(owner, true);
|
||||
popup = true;
|
||||
if(activate) {
|
||||
Ptr<Ctrl> _this = this;
|
||||
SetFocus();
|
||||
if(_this) {
|
||||
activePopup.Add(this);
|
||||
StartGrabPopup();
|
||||
CheckMouseCtrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
81
rainbow/Gtk/GtkCtrl.cpp
Normal file
81
rainbow/Gtk/GtkCtrl.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Ctrl::GuiPlatformConstruct()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformDestruct()
|
||||
{
|
||||
}
|
||||
|
||||
void Ctrl::GuiPlatformGetTopRect(Rect& r) const
|
||||
{
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::GuiPlatformSetFullRefreshSpecial()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String GuiPlatformGetKeyDesc(dword key)
|
||||
{
|
||||
return Null;
|
||||
}
|
||||
|
||||
void GuiPlatformAdjustDragImage(ImageBuffer&)
|
||||
{
|
||||
}
|
||||
|
||||
bool GuiPlatformHasSizeGrip()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiPlatformGripResize(TopWindow *q)
|
||||
{
|
||||
if(q->top) {
|
||||
Point p = GetMousePos();
|
||||
gtk_window_begin_resize_drag(q->gtk(), GDK_WINDOW_EDGE_SOUTH_EAST,
|
||||
1, p.x, p.y, Ctrl::CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
Color GuiPlatformGetScreenPixel(int x, int y)
|
||||
{
|
||||
return Black;
|
||||
}
|
||||
|
||||
void GuiPlatformAfterMenuPopUp()
|
||||
{
|
||||
}
|
||||
|
||||
String Ctrl::Name() const {
|
||||
GuiLock __;
|
||||
#ifdef CPU_64
|
||||
String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this);
|
||||
#else
|
||||
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
|
||||
#endif
|
||||
if(IsChild())
|
||||
s << "(parent " << String(typeid(*parent).name()) << ")";
|
||||
return s;
|
||||
}
|
||||
|
||||
void Ctrl::InstallPanicBox()
|
||||
{
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
167
rainbow/Gtk/GtkCtrl.h
Normal file
167
rainbow/Gtk/GtkCtrl.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
//$ class Ctrl {
|
||||
void Create(Ctrl *owner, bool popup);
|
||||
|
||||
static gboolean GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data);
|
||||
static void IMCommit(GtkIMContext *context, gchar *str, gpointer user_data);
|
||||
|
||||
static void DoMouseEvent(int state, Point pos);
|
||||
static int DoButtonEvent(GdkEvent *event, bool press);
|
||||
static void AddEvent(gpointer user_data, int type, const Value& value);
|
||||
static void FetchEvents(bool may_block);
|
||||
|
||||
bool DispatchMouseIn(int act, int zd);
|
||||
void GtkMouseEvent(int action, int act, int zd);
|
||||
void GtkButtonEvent(int action);
|
||||
|
||||
static bool IsWaitingEvent0(bool fetch);
|
||||
static bool ProcessEvent0(bool *quit, bool fetch);
|
||||
static bool ProcessEvents0(bool *quit, bool fetch);
|
||||
|
||||
void Proc();
|
||||
bool SweepConfigure(bool wait);
|
||||
|
||||
static gboolean GtkEvent(GtkWidget *widget, GdkEvent *key, gpointer user_data);
|
||||
|
||||
enum {
|
||||
EVENT_NONE = -15321,
|
||||
EVENT_TEXT,
|
||||
};
|
||||
|
||||
struct Event0 {
|
||||
int time;
|
||||
int windowid;
|
||||
int type;
|
||||
Value value;
|
||||
Point mousepos;
|
||||
guint state;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct Event : Moveable<Event, Event0> {
|
||||
GdkEvent *event;
|
||||
|
||||
void Free();
|
||||
void Set(const Event& e);
|
||||
Event(const Event& e);
|
||||
void operator=(const Event& e);
|
||||
|
||||
Event();
|
||||
~Event();
|
||||
};
|
||||
|
||||
struct Win : Moveable<Win> {
|
||||
int id;
|
||||
GtkWidget *gtk;
|
||||
GdkWindow *gdk;
|
||||
Ptr<Ctrl> ctrl;
|
||||
};
|
||||
|
||||
static bool EventMouseValid;
|
||||
static Point EventMousePos;
|
||||
static guint EventState;
|
||||
static BiVector<Event> Events;
|
||||
static Vector< Ptr<Ctrl> > activePopup;
|
||||
static Vector<Win> wins;
|
||||
static int WndCaretTime;
|
||||
static bool WndCaretVisible;
|
||||
static Ptr<Ctrl> grabwindow;
|
||||
static Ptr<Ctrl> grabpopup;
|
||||
static Ptr<Ctrl> sel_ctrl;
|
||||
|
||||
static int FindId(int id);
|
||||
static int FindCtrl(Ctrl *ctrl);
|
||||
static int FindGtkWindow(GtkWidget *gtk);
|
||||
static int FindGdkWindow(GdkWindow *gdk);
|
||||
|
||||
static Ctrl *GetTopCtrlFromId(int id);
|
||||
static Ctrl *GetTopCtrlFromId(gpointer user_data) { return GetTopCtrlFromId((uint32)(uintptr_t)user_data); }
|
||||
|
||||
static void SyncPopupCapture();
|
||||
void ReleasePopupCapture();
|
||||
|
||||
static void FocusSync();
|
||||
static void AnimateCaret();
|
||||
static gboolean TimeHandler(GtkWidget *);
|
||||
static void InvalidateMousePos();
|
||||
static void StopGrabPopup();
|
||||
static void StartGrabPopup();
|
||||
static bool ReleaseWndCapture0();
|
||||
|
||||
static Index<String> dnd_targets;
|
||||
static String dnd_text_target;
|
||||
static String dnd_image_target;
|
||||
static String dnd_data;
|
||||
static String dnd_data_fmt;
|
||||
static bool dnd_data_wait;
|
||||
static GtkWidget *dnd_widget;
|
||||
static GdkDragContext *dnd_context;
|
||||
static guint dnd_time;
|
||||
|
||||
static Ptr<Ctrl> dnd_source;
|
||||
static const VectorMap<String, ClipData> *dnd_source_data;
|
||||
static Vector<String> dnd_fmts;
|
||||
static int dnd_result;
|
||||
static Image dnd_icon;
|
||||
|
||||
static void GtkSelectionDataSet(GtkSelectionData *selection_data, const String& fmt, const String& data);
|
||||
static void GtkGetClipData(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer user_data);
|
||||
static void AddFmt(GtkTargetList *list, const String& fmt, int info);
|
||||
static GtkTargetList *CreateTargetList(const VectorMap<String, ClipData>& target);
|
||||
static String GtkDataGet(GtkSelectionData *s);
|
||||
|
||||
void DndInit();
|
||||
void DndExit();
|
||||
|
||||
static void GtkDragBegin(GtkWidget *widget, GdkDragContext *context, gpointer user_data);
|
||||
static void GtkDragDelete(GtkWidget *widget, GdkDragContext *context, gpointer user_data);
|
||||
static void GtkDragGetData(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *data, guint info, guint time, gpointer user_data);
|
||||
static void GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data);
|
||||
static gboolean GtkDragDrop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data);
|
||||
static void GtkDragEnd(GtkWidget *widget, GdkDragContext *context, gpointer user_data);
|
||||
static gboolean GtkDragFailed(GtkWidget *widget, GdkDragContext *context, GtkDragResult result, gpointer user_data);
|
||||
static void GtkDragLeave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer user_data);
|
||||
static gboolean GtkDragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data);
|
||||
|
||||
static Ctrl *DragWnd(gpointer user_data);
|
||||
static void DndTargets(GdkDragContext *context);
|
||||
static bool IsDragAvailable(const char *fmt);
|
||||
static String DragGet(const char *fmt);
|
||||
static PasteClip GtkDnd(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer user_data, bool paste);
|
||||
|
||||
friend void InitGtkApp(int argc, char **argv, const char **envptr);
|
||||
friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation);
|
||||
friend void FinishDragRect(Ctrl& q);
|
||||
friend void GuiPlatformGripResize(TopWindow *q);
|
||||
|
||||
public: // really private:
|
||||
struct Gclipboard {
|
||||
VectorMap<String, ClipData> target;
|
||||
GtkClipboard *clipboard;
|
||||
|
||||
String Get(const String& fmt);
|
||||
void Put(const String& fmt, const ClipData& data);
|
||||
bool IsAvailable(const String& fmt);
|
||||
void Clear();
|
||||
|
||||
Gclipboard(GdkAtom type);
|
||||
};
|
||||
|
||||
static Gclipboard& gclipboard();
|
||||
static Gclipboard& gselection();
|
||||
static String RenderPrimarySelection(const Value& fmt);
|
||||
|
||||
public:
|
||||
static void EndSession() {}
|
||||
static bool IsEndSession() { return false; }
|
||||
static void PanicMsgBox(const char *title, const char *text);
|
||||
|
||||
static Point CurrentMousePos;
|
||||
static guint CurrentState;
|
||||
static guint32 CurrentTime;
|
||||
static Event CurrentEvent;
|
||||
|
||||
GdkWindow *gdk() const { return top ? top->window->window : NULL; }
|
||||
GtkWindow *gtk() const { return top ? (GtkWindow *)top->window : NULL; }
|
||||
//$ };
|
||||
329
rainbow/Gtk/GtkDnD.cpp
Normal file
329
rainbow/Gtk/GtkDnD.cpp
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
Ptr<Ctrl> Ctrl::dnd_source;
|
||||
const VectorMap<String, ClipData> *Ctrl::dnd_source_data;
|
||||
Vector<String> Ctrl::dnd_fmts;
|
||||
int Ctrl::dnd_result;
|
||||
Image Ctrl::dnd_icon;
|
||||
|
||||
Ctrl *Ctrl::GetDragAndDropSource()
|
||||
{
|
||||
return dnd_source;
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragBegin(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
|
||||
{
|
||||
if(IsNull(dnd_icon))
|
||||
gtk_drag_set_icon_default(context);
|
||||
else {
|
||||
ImageGdk m(dnd_icon);
|
||||
gtk_drag_set_icon_pixbuf(context, m, 0, 0);
|
||||
}
|
||||
LLOG("GtkDragBegin");
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragDelete(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragDelete");
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragGetData(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *data,
|
||||
guint info, guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragGetData");
|
||||
if(info < (guint)dnd_source_data->GetCount())
|
||||
GtkSelectionDataSet(data, dnd_source_data->GetKey(info), (*dnd_source_data)[info].Render());
|
||||
else {
|
||||
info -= dnd_source_data->GetCount();
|
||||
if(info < (guint)dnd_fmts.GetCount()) {
|
||||
String fmt = dnd_fmts[info];
|
||||
GtkSelectionDataSet(data, fmt, dnd_source->GetDropData(fmt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragEnd(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragEnd");
|
||||
dnd_result = DND_NONE;
|
||||
GdkDragAction a = gdk_drag_context_get_selected_action(context);
|
||||
dnd_result = a == GDK_ACTION_MOVE ? DND_MOVE : a == GDK_ACTION_COPY ? DND_COPY : DND_NONE;
|
||||
dnd_source = NULL;
|
||||
}
|
||||
|
||||
gboolean Ctrl::GtkDragFailed(GtkWidget *widget, GdkDragContext *context, GtkDragResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragFailed");
|
||||
dnd_source = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Image MakeDragImage(const Image& arrow, Image sample);
|
||||
|
||||
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
if(IsWin2K())
|
||||
return MakeDragImage(arrow, sample);
|
||||
else
|
||||
#endif
|
||||
return arrow98;
|
||||
}
|
||||
|
||||
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
|
||||
const VectorMap<String, ClipData>& data)
|
||||
{
|
||||
LLOG("DoDragAndDrop");
|
||||
TopWindow *w = GetTopWindow();
|
||||
if(!w || !w->top)
|
||||
return DND_NONE;
|
||||
int gdk_actions = 0;
|
||||
if(actions & DND_MOVE)
|
||||
gdk_actions |= GDK_ACTION_MOVE;
|
||||
if(actions & DND_COPY)
|
||||
gdk_actions |= GDK_ACTION_COPY;
|
||||
GtkTargetList *list = CreateTargetList(data);
|
||||
Vector<String> f = Split(fmts, ';');
|
||||
dnd_fmts.Clear();
|
||||
for(int i = 0; i < f.GetCount(); i++) {
|
||||
AddFmt(list, f[i], data.GetCount() + i);
|
||||
dnd_fmts.Add(f[i]);
|
||||
}
|
||||
dnd_source_data = &data;
|
||||
dnd_result = DND_NONE;
|
||||
dnd_source = this;
|
||||
if(IsNull(sample))
|
||||
dnd_icon = Null;
|
||||
else {
|
||||
Size sz = sample.GetSize();
|
||||
if(sz.cx > 128)
|
||||
sz.cx = 128;
|
||||
if(sz.cy > 128)
|
||||
sz.cy = 128;
|
||||
sz += 2;
|
||||
ImageDraw iw(sz);
|
||||
iw.DrawRect(sz, White());
|
||||
DrawFrame(iw, sz, Black());
|
||||
iw.DrawImage(1, 1, sz.cx, sz.cy, sample);
|
||||
ImageBuffer b(128, 128);
|
||||
dnd_icon = iw;
|
||||
}
|
||||
gtk_drag_begin(w->top->window, list, GdkDragAction(gdk_actions),
|
||||
GetMouseLeft() ? 1 : GetMouseMiddle() ? 2 : 3, CurrentEvent.event);
|
||||
while(dnd_source && GetTopCtrls().GetCount())
|
||||
ProcessEvents();
|
||||
dnd_source_data = NULL;
|
||||
gtk_target_list_unref (list);
|
||||
LLOG("--DoDragAndDrop");
|
||||
return dnd_result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
Index<String> Ctrl::dnd_targets;
|
||||
String Ctrl::dnd_text_target;
|
||||
String Ctrl::dnd_image_target;
|
||||
GtkWidget *Ctrl::dnd_widget;
|
||||
GdkDragContext *Ctrl::dnd_context;
|
||||
guint Ctrl::dnd_time;
|
||||
String Ctrl::dnd_data;
|
||||
String Ctrl::dnd_data_fmt;
|
||||
bool Ctrl::dnd_data_wait;
|
||||
|
||||
Ctrl *Ctrl::DragWnd(gpointer user_data)
|
||||
{
|
||||
if(dnd_data_wait) // Do nothing if waiting for data
|
||||
return NULL;
|
||||
ProcessEvents0(NULL, false); // process any events that are already fetched
|
||||
return GetTopCtrlFromId(user_data);
|
||||
}
|
||||
|
||||
void ToIndex(GtkTargetList *target_list, Index<String>& ndx)
|
||||
{
|
||||
gint n;
|
||||
GtkTargetEntry *t = gtk_target_table_new_from_list(target_list, &n);
|
||||
for(int i = 0; i < n; i++)
|
||||
ndx.Add(t[i].target);
|
||||
gtk_target_table_free(t, n);
|
||||
gtk_target_list_unref(target_list);
|
||||
}
|
||||
|
||||
void Ctrl::DndTargets(GdkDragContext *context)
|
||||
{
|
||||
static Index<String> text_targets;
|
||||
static Index<String> image_targets;
|
||||
ONCELOCK {
|
||||
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
||||
gtk_target_list_add_text_targets (target_list, 0);
|
||||
ToIndex(target_list, text_targets);
|
||||
GtkTargetList *target_list2 = gtk_target_list_new (NULL, 0);
|
||||
gtk_target_list_add_image_targets (target_list2, 0, TRUE);
|
||||
ToIndex(target_list2, image_targets);
|
||||
}
|
||||
dnd_targets.Clear();
|
||||
dnd_text_target.Clear();
|
||||
for(GList *list = gdk_drag_context_list_targets(context); list; list = g_list_next (list)) {
|
||||
String g = gdk_atom_name((GdkAtom)list->data);
|
||||
if(text_targets.Find(g) >= 0) {
|
||||
dnd_targets.Add("text");
|
||||
if(dnd_text_target.IsEmpty())
|
||||
dnd_text_target = g;
|
||||
}
|
||||
else
|
||||
if(image_targets.Find(g) >= 0) {
|
||||
dnd_targets.Add("image");
|
||||
if(dnd_image_target.IsEmpty())
|
||||
dnd_image_target = g;
|
||||
}
|
||||
else
|
||||
dnd_targets.Add(g);
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context,
|
||||
gint x, gint y, GtkSelectionData *data,
|
||||
guint info, guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragDataReceived");
|
||||
dnd_data_wait = false;
|
||||
if(dnd_data_fmt == "text") {
|
||||
guchar *s = gtk_selection_data_get_text(data);
|
||||
if(s) {
|
||||
dnd_data = (const char *)s;
|
||||
g_free(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(dnd_data_fmt == "image") {
|
||||
Image img = ImageFromPixbufUnref(gtk_selection_data_get_pixbuf(data));
|
||||
dnd_data = StoreAsString(img); // Not very optimal...
|
||||
}
|
||||
else
|
||||
dnd_data = GtkDataGet(data);
|
||||
}
|
||||
|
||||
bool Ctrl::IsDragAvailable(const char *fmt)
|
||||
{
|
||||
LLOG("IsDragAvailable " << fmt << " " << (Ctrl::dnd_targets.Find(fmt) >= 0));
|
||||
return dnd_targets.Find(fmt) >= 0;
|
||||
}
|
||||
|
||||
String Ctrl::DragGet(const char *fmt)
|
||||
{
|
||||
LLOG("DragGet " << fmt << " " << (Ctrl::dnd_targets.Find(fmt) >= 0));
|
||||
if(Ctrl::dnd_targets.Find(fmt) < 0)
|
||||
return Null;
|
||||
dnd_data.Clear();
|
||||
dnd_data_wait = true;
|
||||
dnd_data_fmt = fmt;
|
||||
int t0 = msecs();
|
||||
gtk_drag_get_data(dnd_widget, dnd_context,
|
||||
GAtom(strcmp(fmt, "image") == 0 ? ~dnd_image_target
|
||||
: strcmp(fmt, "text") == 0 ? ~dnd_text_target
|
||||
: fmt),
|
||||
dnd_time);
|
||||
while(msecs() - t0 < 1000 && dnd_data_wait)
|
||||
FetchEvents(true);
|
||||
LLOG("DragGet data length " << dnd_data.GetLength());
|
||||
return dnd_data;
|
||||
}
|
||||
|
||||
PasteClip Ctrl::GtkDnd(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer user_data, bool paste)
|
||||
{
|
||||
DndTargets(context);
|
||||
g_object_ref(context); // make sure these always survive the action...
|
||||
g_object_ref(widget);
|
||||
dnd_context = context;
|
||||
dnd_widget = widget;
|
||||
dnd_time = time;
|
||||
PasteClip clip;
|
||||
clip.type = 1;
|
||||
clip.paste = paste;
|
||||
clip.accepted = false;
|
||||
clip.allowed = DND_MOVE|DND_COPY;
|
||||
gint dummy;
|
||||
GdkModifierType mod;
|
||||
gdk_window_get_pointer(gdk_get_default_root_window(), &dummy, &dummy, &mod);
|
||||
clip.action = mod & GDK_CONTROL_MASK ? DND_COPY : DND_MOVE;
|
||||
Ctrl *w = DragWnd(user_data);
|
||||
if(w) {
|
||||
gint mx, my;
|
||||
GdkModifierType mod;
|
||||
gdk_window_get_pointer(gdk_get_default_root_window(), &mx, &my, &mod);
|
||||
CurrentState = mod;
|
||||
CurrentMousePos = Point(x, y) + w->GetScreenRect().TopLeft();
|
||||
w->DnD(CurrentMousePos, clip);
|
||||
}
|
||||
gdk_drag_status(context, clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? GDK_ACTION_MOVE
|
||||
: GDK_ACTION_COPY
|
||||
: GdkDragAction(0), time);
|
||||
return clip;
|
||||
}
|
||||
|
||||
gboolean Ctrl::GtkDragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragMotion");
|
||||
|
||||
PasteClip clip = GtkDnd(widget, context, x, y, time, user_data, false);
|
||||
g_object_unref(widget);
|
||||
g_object_unref(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Ctrl::GtkDragLeave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragLeave");
|
||||
DnDLeave();
|
||||
}
|
||||
|
||||
gboolean Ctrl::GtkDragDrop(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragDrop");
|
||||
|
||||
PasteClip clip = GtkDnd(widget, context, x, y, time, user_data, true);
|
||||
gtk_drag_finish(context, clip.IsAccepted(), clip.IsAccepted() && clip.GetAction() == DND_MOVE, time);
|
||||
g_object_unref(widget);
|
||||
g_object_unref(context);
|
||||
DnDLeave();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
void Ctrl::DndInit()
|
||||
{
|
||||
GtkWidget *w = top->window;
|
||||
gpointer id = (gpointer)(uintptr_t)top->id;
|
||||
g_signal_connect(w, "drag-begin", G_CALLBACK(GtkDragBegin), id);
|
||||
g_signal_connect(w, "drag-data-delete", G_CALLBACK(GtkDragDelete), id);
|
||||
g_signal_connect(w, "drag-data-get", G_CALLBACK(GtkDragGetData), id);
|
||||
g_signal_connect(w, "drag-data-received", G_CALLBACK(GtkDragDataReceived), id);
|
||||
g_signal_connect(w, "drag-drop", G_CALLBACK(GtkDragDrop), id);
|
||||
g_signal_connect(w, "drag-end", G_CALLBACK(GtkDragEnd), id);
|
||||
g_signal_connect(w, "drag-failed", G_CALLBACK(GtkDragFailed), id);
|
||||
g_signal_connect(w, "drag-leave", G_CALLBACK(GtkDragLeave), id);
|
||||
g_signal_connect(w, "drag-motion", G_CALLBACK(GtkDragMotion), id);
|
||||
gtk_drag_dest_set(w, GtkDestDefaults(0), NULL, 0, GdkDragAction(GDK_ACTION_COPY|GDK_ACTION_MOVE));
|
||||
}
|
||||
|
||||
void Ctrl::DndExit()
|
||||
{
|
||||
if(top)
|
||||
gtk_drag_dest_unset(top->window);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
208
rainbow/Gtk/GtkDrawImage.cpp
Normal file
208
rainbow/Gtk/GtkDrawImage.cpp
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
//#include <shellapi.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
#define LLOG(x)
|
||||
|
||||
void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels);
|
||||
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff);
|
||||
|
||||
struct ImageSysData {
|
||||
Image img;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
void Init(const Image& img);
|
||||
~ImageSysData();
|
||||
};
|
||||
|
||||
void ImageSysData::Init(const Image& m)
|
||||
{
|
||||
img = m;
|
||||
Size isz = img.GetSize();
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, isz.cx, isz.cy);
|
||||
cairo_surface_flush(surface);
|
||||
byte *a = (byte *)cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, isz.cx);
|
||||
for(int yy = 0; yy < isz.cy; yy++) {
|
||||
Copy((RGBA *)a, img[yy], isz.cx);
|
||||
a += stride;
|
||||
}
|
||||
cairo_surface_mark_dirty(surface);
|
||||
SysImageRealized(img);
|
||||
}
|
||||
|
||||
ImageSysData::~ImageSysData()
|
||||
{
|
||||
SysImageReleased(img);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
struct ImageSysDataMaker : LRUCache<ImageSysData, int64>::Maker {
|
||||
Image img;
|
||||
|
||||
virtual int64 Key() const { return img.GetSerialId(); }
|
||||
virtual int Make(ImageSysData& object) const { object.Init(img); return img.GetLength(); }
|
||||
};
|
||||
|
||||
void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
|
||||
{
|
||||
GuiLock __;
|
||||
if(img.GetLength() == 0)
|
||||
return;
|
||||
LLOG("SysDrawImageOp " << img.GetSerialId() << ' ' << x << ", " << y << ", "<< img.GetSize());
|
||||
ImageSysDataMaker m;
|
||||
static LRUCache<ImageSysData, int64> cache;
|
||||
LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount());
|
||||
m.img = img;
|
||||
ImageSysData& sd = cache.Get(m);
|
||||
if(!IsNull(color)) {
|
||||
SetColor(color);
|
||||
cairo_mask_surface(cr, sd.surface, x, y);
|
||||
}
|
||||
else {
|
||||
cairo_set_source_surface(cr, sd.surface, x, y);
|
||||
cairo_paint(cr);
|
||||
}
|
||||
cache.Shrink(4 * 1024 * 768, 1000); // Cache must be after Paint because of PaintOnly!
|
||||
}
|
||||
|
||||
Draw& ImageDraw::Alpha()
|
||||
{
|
||||
if(!alpha_surface) {
|
||||
alpha_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, isz.cx, isz.cy);
|
||||
alpha.cr = cairo_create(alpha_surface);
|
||||
}
|
||||
return alpha;
|
||||
}
|
||||
|
||||
void CairoGet(ImageBuffer& b, Size isz, cairo_surface_t *surface, cairo_surface_t *alpha_surface)
|
||||
{
|
||||
cairo_surface_flush(surface);
|
||||
byte *a = (byte *)cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, isz.cx);
|
||||
RGBA *t = b;
|
||||
byte *aa = NULL;
|
||||
if(alpha_surface) {
|
||||
cairo_surface_flush(alpha_surface);
|
||||
aa = (byte *)cairo_image_surface_get_data(alpha_surface);
|
||||
}
|
||||
for(int yy = 0; yy < isz.cy; yy++) {
|
||||
RGBA *s = (RGBA *)a;
|
||||
RGBA *e = s + isz.cx;
|
||||
if(aa) {
|
||||
RGBA *ss = (RGBA *)aa;
|
||||
while(s < e) {
|
||||
*t = *s++;
|
||||
(t++)->a = (ss++)->r;
|
||||
}
|
||||
aa += stride;
|
||||
}
|
||||
else
|
||||
while(s < e) {
|
||||
*t = *s++;
|
||||
(t++)->a = 255;
|
||||
}
|
||||
a += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageDraw::FetchStraight(ImageBuffer& b) const
|
||||
{
|
||||
CairoGet(b, isz, surface, alpha_surface);
|
||||
}
|
||||
|
||||
ImageDraw::operator Image() const
|
||||
{
|
||||
ImageBuffer img(isz);
|
||||
FetchStraight(img);
|
||||
Premultiply(img);
|
||||
return img;
|
||||
}
|
||||
|
||||
Image ImageDraw::GetStraight() const
|
||||
{
|
||||
ImageBuffer img(isz);
|
||||
FetchStraight(img);
|
||||
return img;
|
||||
}
|
||||
|
||||
void ImageDraw::Init(Size sz)
|
||||
{
|
||||
isz = sz;
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, isz.cx, isz.cy);
|
||||
cr = cairo_create(surface);
|
||||
alpha_surface = NULL;
|
||||
del = true;
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(Size sz)
|
||||
{
|
||||
Init(sz);
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(int cx, int cy)
|
||||
{
|
||||
Init(Size(cx, cy));
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(cairo_t *cr_, Size sz)
|
||||
{
|
||||
isz = sz;
|
||||
cr = cr_;
|
||||
surface = cairo_get_target(cr);
|
||||
alpha_surface = NULL;
|
||||
del = false;
|
||||
}
|
||||
|
||||
ImageDraw::~ImageDraw()
|
||||
{
|
||||
if(del) {
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(surface);
|
||||
if(alpha_surface) {
|
||||
cairo_destroy(alpha.cr);
|
||||
cairo_surface_destroy(alpha_surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BackDraw::Put(SystemDraw& w, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void BackDraw::Create(SystemDraw& w, int cx, int cy)
|
||||
{
|
||||
}
|
||||
|
||||
void BackDraw::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
#define FCURSOR_(x) { static Image h; ONCELOCK { h = CreateImage(Size(1, 1), Black); h.SetAuxData(x + 1); } return h; }
|
||||
|
||||
Image Image::Arrow() FCURSOR_(GDK_LEFT_PTR)
|
||||
Image Image::Wait() FCURSOR_(GDK_WATCH)
|
||||
Image Image::IBeam() FCURSOR_(GDK_XTERM)
|
||||
Image Image::No() FCURSOR_(GDK_CIRCLE)
|
||||
Image Image::SizeAll() FCURSOR_(GDK_FLEUR)
|
||||
Image Image::SizeHorz() FCURSOR_(GDK_SB_H_DOUBLE_ARROW)
|
||||
Image Image::SizeVert() FCURSOR_(GDK_DOUBLE_ARROW)
|
||||
Image Image::SizeTopLeft() FCURSOR_(GDK_TOP_LEFT_CORNER)
|
||||
Image Image::SizeTop() FCURSOR_(GDK_TOP_SIDE)
|
||||
Image Image::SizeTopRight() FCURSOR_(GDK_TOP_RIGHT_CORNER)
|
||||
Image Image::SizeLeft() FCURSOR_(GDK_LEFT_SIDE)
|
||||
Image Image::SizeRight() FCURSOR_(GDK_RIGHT_SIDE)
|
||||
Image Image::SizeBottomLeft() FCURSOR_(GDK_BOTTOM_LEFT_CORNER)
|
||||
Image Image::SizeBottom() FCURSOR_(GDK_BOTTOM_SIDE)
|
||||
Image Image::SizeBottomRight() FCURSOR_(GDK_BOTTOM_RIGHT_CORNER)
|
||||
Image Image::Cross() FCURSOR_(GDK_CROSSHAIR)
|
||||
Image Image::Hand() FCURSOR_(GDK_HAND1)
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
148
rainbow/Gtk/GtkDrawOp.cpp
Normal file
148
rainbow/Gtk/GtkDrawOp.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
void SystemDraw::SetColor(Color c)
|
||||
{
|
||||
cairo_set_source_rgb(cr, c.GetR() / 255.0, c.GetG() / 255.0, c.GetB() / 255.0);
|
||||
}
|
||||
|
||||
dword SystemDraw::GetInfo() const
|
||||
{
|
||||
return DRAWTEXTLINES;
|
||||
}
|
||||
|
||||
Point SystemDraw::GetOffset() const
|
||||
{
|
||||
return offset.GetCount() ? offset.Top() : Point(0, 0);
|
||||
}
|
||||
|
||||
void SystemDraw::Push()
|
||||
{
|
||||
cairo_save(cr);
|
||||
offset.Add(GetOffset());
|
||||
}
|
||||
|
||||
void SystemDraw::Pop()
|
||||
{
|
||||
if(offset.GetCount())
|
||||
offset.Drop();
|
||||
cairo_restore(cr);
|
||||
}
|
||||
|
||||
void SystemDraw::BeginOp()
|
||||
{
|
||||
Push();
|
||||
}
|
||||
|
||||
void SystemDraw::EndOp()
|
||||
{
|
||||
Pop();
|
||||
}
|
||||
|
||||
void SystemDraw::OffsetOp(Point p)
|
||||
{
|
||||
Push();
|
||||
offset.Top() += p;
|
||||
cairo_translate(cr, p.x, p.y);
|
||||
}
|
||||
|
||||
void SystemDraw::RectPath(const Rect& r)
|
||||
{
|
||||
cairo_rectangle(cr, r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipOp(const Rect& r)
|
||||
{
|
||||
Push();
|
||||
RectPath(r);
|
||||
cairo_clip(cr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
Push();
|
||||
offset.Top() += r.TopLeft();
|
||||
RectPath(r);
|
||||
cairo_clip(cr);
|
||||
cairo_translate(cr, r.left, r.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
RectPath(Rect(-99999, -99999, 99999, r.top));
|
||||
RectPath(Rect(-99999, r.top, r.left, 99999));
|
||||
RectPath(Rect(r.right, r.top, 99999, 99999));
|
||||
RectPath(Rect(r.left, r.bottom, r.right, 99999));
|
||||
cairo_clip(cr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
RectPath(r);
|
||||
cairo_clip(cr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect SystemDraw::GetPaintRect() const
|
||||
{
|
||||
return Rect(0, 0, INT_MAX, INT_MAX);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
if(IsNull(color))
|
||||
return;
|
||||
cairo_rectangle(cr, x, y, cx, cy);
|
||||
if(color == InvertColor()) {
|
||||
SetColor(White());
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
|
||||
cairo_fill(cr);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
}
|
||||
else {
|
||||
SetColor(color);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
SetColor(color);
|
||||
cairo_move_to(cr, x1, y1);
|
||||
cairo_line_to(cr, x2, y2);
|
||||
cairo_set_line_width (cr, width);
|
||||
cairo_stroke(cr);
|
||||
}
|
||||
|
||||
void SystemDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor)
|
||||
{
|
||||
}
|
||||
|
||||
void SystemDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
}
|
||||
|
||||
void SystemDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
}
|
||||
|
||||
void SystemDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
88
rainbow/Gtk/GtkDrawText.cpp
Normal file
88
rainbow/Gtk/GtkDrawText.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
#include <cairo/cairo-ft.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
FcPattern *CreateFcPattern(Font font);
|
||||
FT_Face FTFace(Font fnt, String *rpath = NULL);
|
||||
|
||||
struct FontSysData {
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
|
||||
void Init(Font font, int angle);
|
||||
~FontSysData() { cairo_scaled_font_destroy(scaled_font); }
|
||||
};
|
||||
|
||||
void FontSysData::Init(Font font, int angle)
|
||||
{
|
||||
LLOG("FontSysData::Init " << font << ", " << angle);
|
||||
FcPattern *p = CreateFcPattern(font);
|
||||
cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(p);
|
||||
FcPatternDestroy(p);
|
||||
|
||||
cairo_matrix_t font_matrix[1], ctm[1];
|
||||
cairo_matrix_init_identity(ctm);
|
||||
cairo_matrix_init_scale(font_matrix, font.GetHeight(), font.GetHeight());
|
||||
if(angle)
|
||||
cairo_matrix_rotate(font_matrix, -angle * M_2PI / 3600);
|
||||
cairo_font_options_t *opt = cairo_font_options_create();
|
||||
scaled_font = cairo_scaled_font_create(font_face, font_matrix, ctm, opt);
|
||||
|
||||
cairo_font_options_destroy(opt);
|
||||
cairo_font_face_destroy(font_face);
|
||||
}
|
||||
|
||||
struct FontDataSysMaker : LRUCache<FontSysData, Tuple2<Font, int> >::Maker {
|
||||
Font font;
|
||||
int angle;
|
||||
|
||||
virtual Tuple2<Font, int> Key() const { return MakeTuple(font, angle); }
|
||||
virtual int Make(FontSysData& object) const { object.Init(font, angle); return 1; }
|
||||
};
|
||||
|
||||
int gtk_antialias = -1;
|
||||
int gtk_hinting = -1;
|
||||
String gtk_hintstyle;
|
||||
String gtk_rgba;
|
||||
|
||||
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
||||
{
|
||||
GuiLock __;
|
||||
|
||||
int ascent = font.GetAscent();
|
||||
double sina = 0;
|
||||
double cosa = 1;
|
||||
if(angle)
|
||||
Draw::SinCos(angle, sina, cosa);
|
||||
int xpos = 0;
|
||||
Buffer<cairo_glyph_t> gs(n);
|
||||
for(int i = 0; i < n; i++) {
|
||||
cairo_glyph_t& g = gs[i];
|
||||
g.index = GetGlyphInfo(font, text[i]).glyphi;
|
||||
g.x = fround(x + cosa * xpos + sina * ascent);
|
||||
g.y = fround(y + cosa * ascent - sina * xpos);
|
||||
xpos += dx ? dx[i] : font[text[i]];
|
||||
}
|
||||
|
||||
static LRUCache<FontSysData, Tuple2<Font, int> > cache;
|
||||
FontDataSysMaker m;
|
||||
m.font = font;
|
||||
m.angle = angle;
|
||||
FontSysData& sf = cache.Get(m);
|
||||
|
||||
cairo_set_scaled_font(cr, sf.scaled_font);
|
||||
|
||||
SetColor(ink);
|
||||
cairo_show_glyphs(cr, gs, n);
|
||||
|
||||
cache.Shrink(64);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
584
rainbow/Gtk/GtkEvent.cpp
Normal file
584
rainbow/Gtk/GtkEvent.cpp
Normal file
|
|
@ -0,0 +1,584 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
//#include <winnls.h>
|
||||
|
||||
//#include "imm.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) LOG(x)
|
||||
#define LOG_EVENTS
|
||||
|
||||
bool Ctrl::EventMouseValid;
|
||||
Point Ctrl::EventMousePos;
|
||||
guint Ctrl::EventState;
|
||||
|
||||
BiVector<Ctrl::Event> Ctrl::Events;
|
||||
|
||||
Point Ctrl::CurrentMousePos;
|
||||
guint Ctrl::CurrentState;
|
||||
guint32 Ctrl::CurrentTime;
|
||||
Ctrl::Event Ctrl::CurrentEvent;
|
||||
|
||||
bool GetShift() { return Ctrl::CurrentState & GDK_SHIFT_MASK; }
|
||||
bool GetCtrl() { return Ctrl::CurrentState & GDK_CONTROL_MASK ; }
|
||||
bool GetAlt() { return Ctrl::CurrentState & GDK_MOD1_MASK; }
|
||||
bool GetCapsLock() { return Ctrl::CurrentState & GDK_LOCK_MASK; }
|
||||
bool GetMouseLeft() { return Ctrl::CurrentState & GDK_BUTTON1_MASK; }
|
||||
bool GetMouseRight() { return Ctrl::CurrentState & GDK_BUTTON3_MASK; }
|
||||
bool GetMouseMiddle() { return Ctrl::CurrentState & GDK_BUTTON2_MASK; }
|
||||
Point GetMousePos() { return Ctrl::CurrentMousePos; }
|
||||
|
||||
#ifdef LOG_EVENTS
|
||||
Tuple2<int, const char *> xEvent[] = {
|
||||
{ GDK_NOTHING, "GDK_NOTHING" },
|
||||
{ GDK_DELETE, "GDK_DELETE" },
|
||||
{ GDK_DESTROY, "GDK_DESTROY" },
|
||||
{ GDK_EXPOSE, "GDK_EXPOSE" },
|
||||
{ GDK_MOTION_NOTIFY, "GDK_MOTION_NOTIFY" },
|
||||
{ GDK_BUTTON_PRESS, "GDK_BUTTON_PRESS" },
|
||||
{ GDK_2BUTTON_PRESS, "GDK_2BUTTON_PRESS" },
|
||||
{ GDK_3BUTTON_PRESS, "GDK_3BUTTON_PRESS" },
|
||||
{ GDK_BUTTON_RELEASE, "GDK_BUTTON_RELEASE" },
|
||||
{ GDK_KEY_PRESS, "GDK_KEY_PRESS" },
|
||||
{ GDK_KEY_RELEASE, "GDK_KEY_RELEASE" },
|
||||
{ GDK_ENTER_NOTIFY, "GDK_ENTER_NOTIFY" },
|
||||
{ GDK_LEAVE_NOTIFY, "GDK_LEAVE_NOTIFY" },
|
||||
{ GDK_FOCUS_CHANGE, "GDK_FOCUS_CHANGE" },
|
||||
{ GDK_CONFIGURE, "GDK_CONFIGURE" },
|
||||
{ GDK_MAP, "GDK_MAP" },
|
||||
{ GDK_UNMAP, "GDK_UNMAP" },
|
||||
{ GDK_PROPERTY_NOTIFY, "GDK_PROPERTY_NOTIFY" },
|
||||
{ GDK_SELECTION_CLEAR, "GDK_SELECTION_CLEAR" },
|
||||
{ GDK_SELECTION_REQUEST, "GDK_SELECTION_REQUEST" },
|
||||
{ GDK_SELECTION_NOTIFY, "GDK_SELECTION_NOTIFY" },
|
||||
{ GDK_PROXIMITY_IN, "GDK_PROXIMITY_IN" },
|
||||
{ GDK_PROXIMITY_OUT, "GDK_PROXIMITY_OUT" },
|
||||
{ GDK_DRAG_ENTER, "GDK_DRAG_ENTER" },
|
||||
{ GDK_DRAG_LEAVE, "GDK_DRAG_LEAVE" },
|
||||
{ GDK_DRAG_MOTION, "GDK_DRAG_MOTION" },
|
||||
{ GDK_DRAG_STATUS, "GDK_DRAG_STATUS" },
|
||||
{ GDK_DROP_START, "GDK_DROP_START" },
|
||||
{ GDK_DROP_FINISHED, "GDK_DROP_FINISHED" },
|
||||
{ GDK_CLIENT_EVENT, "GDK_CLIENT_EVENT" },
|
||||
{ GDK_VISIBILITY_NOTIFY, "GDK_VISIBILITY_NOTIFY" },
|
||||
{ GDK_NO_EXPOSE, "GDK_NO_EXPOSE" },
|
||||
{ GDK_SCROLL, "GDK_SCROLL" },
|
||||
{ GDK_WINDOW_STATE, "GDK_WINDOW_STATE" },
|
||||
{ GDK_SETTING, "GDK_SETTING" },
|
||||
{ GDK_OWNER_CHANGE, "GDK_OWNER_CHANGE" },
|
||||
{ GDK_GRAB_BROKEN, "GDK_GRAB_BROKEN" },
|
||||
{ GDK_DAMAGE, "GDK_DAMAGE" },
|
||||
{ GDK_EVENT_LAST, "GDK_EVENT_LAST" },
|
||||
};
|
||||
#endif
|
||||
|
||||
Ctrl *Ctrl::GetTopCtrlFromId(int id)
|
||||
{
|
||||
int q = FindId(id);
|
||||
if(q >= 0) {
|
||||
Ctrl *p = wins[q].ctrl;
|
||||
if(p && p->top)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
||||
{
|
||||
#ifdef LOG_EVENTS
|
||||
String ev = "?";
|
||||
Tuple2<int, const char *> *f = FindTuple(xEvent, __countof(xEvent), event->type);
|
||||
if(f)
|
||||
ev = f->b;
|
||||
LOG(rmsecs() << " FETCH EVENT " << ev);
|
||||
#endif
|
||||
GdkEventKey *key;
|
||||
bool pressed = false;
|
||||
bool retval = true;
|
||||
Value value;
|
||||
Ctrl *p;
|
||||
|
||||
switch(event->type) {
|
||||
case GDK_EXPOSE:
|
||||
case GDK_DAMAGE:
|
||||
p = GetTopCtrlFromId(user_data);
|
||||
if(p) {
|
||||
#ifdef LOG_EVENTS
|
||||
TimeStop tm;
|
||||
#endif
|
||||
p->fullrefresh = false;
|
||||
GdkEventExpose *e = (GdkEventExpose *)event;
|
||||
SystemDraw w(gdk_cairo_create(p->gdk()));
|
||||
painting = true;
|
||||
Rect r = RectC(e->area.x, e->area.y, e->area.width, e->area.height);
|
||||
w.Clip(r);
|
||||
p->UpdateArea(w, r);
|
||||
w.End();
|
||||
cairo_destroy(w);
|
||||
if(p->top->dr)
|
||||
DrawDragRect(*p, *p->top->dr);
|
||||
painting = false;
|
||||
#ifdef LOG_EVENTS
|
||||
LOG("* " << ev << " elapsed " << tm);
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
case GDK_DELETE:
|
||||
break;
|
||||
case GDK_FOCUS_CHANGE:
|
||||
retval = false;
|
||||
value = ((GdkEventFocus *)event)->in;
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
EventMouseValid = false;
|
||||
return false;
|
||||
case GDK_MOTION_NOTIFY: {
|
||||
GdkEventMotion *e = (GdkEventMotion *)event;
|
||||
DoMouseEvent(e->state, Point((int)e->x_root, (int)e->y_root));
|
||||
break;
|
||||
}
|
||||
case GDK_BUTTON_PRESS:
|
||||
value = DoButtonEvent(event, true);
|
||||
if(IsNull(value))
|
||||
return false;
|
||||
break;
|
||||
case GDK_2BUTTON_PRESS:
|
||||
value = DoButtonEvent(event, true);
|
||||
if(IsNull(value))
|
||||
return false;
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
value = DoButtonEvent(event, false);
|
||||
if(IsNull(value))
|
||||
return false;
|
||||
break;
|
||||
case GDK_SCROLL: {
|
||||
GdkEventScroll *e = (GdkEventScroll *)event;
|
||||
value = findarg(e->direction, GDK_SCROLL_UP, GDK_SCROLL_LEFT) < 0 ? -120 : 120;
|
||||
DoMouseEvent(e->state, Point((int)e->x_root, (int)e->y_root));
|
||||
break;
|
||||
}
|
||||
case GDK_KEY_PRESS:
|
||||
pressed = true;
|
||||
case GDK_KEY_RELEASE:
|
||||
key = (GdkEventKey *)event;
|
||||
EventState = key->state;
|
||||
value = (int) key->keyval;
|
||||
if(pressed) {
|
||||
p = GetTopCtrlFromId(user_data);
|
||||
if(p && gtk_im_context_filter_keypress(p->top->im_context, key))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case GDK_CONFIGURE: {
|
||||
retval = false;
|
||||
GdkEventConfigure *e = (GdkEventConfigure *)event;
|
||||
value = RectC(e->x, e->y, e->width, e->height);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
AddEvent(user_data, event->type, value);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void Ctrl::DoMouseEvent(int state, Point pos)
|
||||
{
|
||||
EventMousePos = pos;
|
||||
EventState = state;
|
||||
EventMouseValid = true;
|
||||
}
|
||||
|
||||
int Ctrl::DoButtonEvent(GdkEvent *event, bool press)
|
||||
{
|
||||
GdkEventButton *e = (GdkEventButton *)event;
|
||||
static int mask[] = { GDK_BUTTON1_MASK, GDK_BUTTON2_MASK, GDK_BUTTON3_MASK };
|
||||
if(e->button >= 1 && e->button <= 3) {
|
||||
int m = mask[e->button - 1];
|
||||
int state = e->state;
|
||||
if(press) // gtk seems to provide state "before" the event, so buttons are wrong
|
||||
state |= m;
|
||||
else
|
||||
state &= ~m;
|
||||
DoMouseEvent(state, Point((int)e->x_root, (int)e->y_root));
|
||||
return e->button;
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
Ctrl::Event::Event()
|
||||
{
|
||||
event = NULL;
|
||||
}
|
||||
|
||||
void Ctrl::Event::Free()
|
||||
{
|
||||
if(event) {
|
||||
gdk_event_free(event);
|
||||
event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::Event::Set(const Event& e)
|
||||
{
|
||||
*(Event0 *)this = e;
|
||||
event = gdk_event_copy(e.event);
|
||||
}
|
||||
|
||||
Ctrl::Event::~Event()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
Ctrl::Event::Event(const Event& e)
|
||||
{
|
||||
Set(e);
|
||||
}
|
||||
|
||||
void Ctrl::Event::operator=(const Event& e)
|
||||
{
|
||||
if(this == &e)
|
||||
return;
|
||||
Free();
|
||||
Set(e);
|
||||
}
|
||||
|
||||
void Ctrl::AddEvent(gpointer user_data, int type, const Value& value)
|
||||
{
|
||||
if(Events.GetCount() > 50000)
|
||||
return;
|
||||
Event& e = Events.AddTail();
|
||||
e.time = gtk_get_current_event_time();
|
||||
e.windowid = (uint32)(uintptr_t)user_data;
|
||||
e.type = type;
|
||||
e.value = value;
|
||||
if(!EventMouseValid) {
|
||||
gint x, y;
|
||||
GdkModifierType mod;
|
||||
gdk_window_get_pointer(gdk_get_default_root_window(), &x, &y, &mod);
|
||||
EventState = mod;
|
||||
EventMousePos = Point(x, y);
|
||||
EventMouseValid = true;
|
||||
}
|
||||
e.mousepos = EventMousePos;
|
||||
e.state = EventState;
|
||||
e.count = 1;
|
||||
e.event = gtk_get_current_event();
|
||||
}
|
||||
|
||||
void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data)
|
||||
{
|
||||
AddEvent(user_data, EVENT_TEXT, FromUtf8(str));
|
||||
}
|
||||
|
||||
void Ctrl::FetchEvents(bool may_block)
|
||||
{
|
||||
while(g_main_context_iteration(NULL, may_block))
|
||||
may_block = false;
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent0(bool fetch)
|
||||
{
|
||||
if(fetch)
|
||||
FetchEvents(FALSE);
|
||||
return Events.GetCount();
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent()
|
||||
{
|
||||
return IsWaitingEvent0(true);
|
||||
}
|
||||
|
||||
struct ProcStop {
|
||||
TimeStop tm;
|
||||
String ev;
|
||||
|
||||
~ProcStop() { LOG("* " << ev << " elapsed " << tm); }
|
||||
};
|
||||
|
||||
bool Ctrl::DispatchMouseIn(int act, int zd)
|
||||
{
|
||||
Point p = GetMousePos();
|
||||
Rect r = GetScreenRect();
|
||||
if(r.Contains(p)) {
|
||||
p -= r.TopLeft();
|
||||
DispatchMouse(act, p, zd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::GtkMouseEvent(int action, int act, int zd)
|
||||
{
|
||||
if(grabpopup && activePopup.GetCount()) {
|
||||
for(int i = activePopup.GetCount(); --i >= 0;)
|
||||
if(activePopup[i] && activePopup[i]->DispatchMouseIn(act, zd))
|
||||
return;
|
||||
if(action == DOWN) { // Deactivate active popup(s) if clicked outside of active popups
|
||||
IgnoreMouseUp();
|
||||
if(activePopup.Top())
|
||||
activePopup.Top()->GetTopWindow()->ActivateWnd();
|
||||
}
|
||||
else
|
||||
if(activePopup[0]) { // Redirect other events to TopWindow that spawned first popup
|
||||
Ptr<TopWindow> w = activePopup[0]->GetTopWindow();
|
||||
if(w)
|
||||
w->DispatchMouseIn(act, zd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
DispatchMouse(act, GetMousePos() - GetScreenRect().TopLeft(), zd);
|
||||
}
|
||||
|
||||
void Ctrl::GtkButtonEvent(int action)
|
||||
{
|
||||
int act = action;
|
||||
int button = CurrentEvent.value;
|
||||
if(action != MOUSEMOVE)
|
||||
act |= button == 2 ? MIDDLE : button == 3 ? RIGHT : LEFT;
|
||||
GtkMouseEvent(action, act, 0);
|
||||
}
|
||||
|
||||
void Ctrl::Proc()
|
||||
{
|
||||
#ifdef LOG_EVENTS
|
||||
String ev = "?";
|
||||
Tuple2<int, const char *> *f = FindTuple(xEvent, __countof(xEvent), CurrentEvent.type);
|
||||
if(f)
|
||||
ev = f->b;
|
||||
LOG(rmsecs() << "PROCESS EVENT " << Upp::Name(this) << " " << ev);
|
||||
ProcStop tm;
|
||||
tm.ev = ev;
|
||||
#endif
|
||||
if(!top)
|
||||
return;
|
||||
Ptr<Ctrl> _this = this;
|
||||
bool pressed = false;
|
||||
int kv;
|
||||
switch(CurrentEvent.type) {
|
||||
case GDK_DELETE: {
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(this);
|
||||
if(w) {
|
||||
if(IsEnabled()) {
|
||||
IgnoreMouseUp();
|
||||
w->WhenClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
case GDK_FOCUS_CHANGE:
|
||||
LLOG("FocusChange in: " << (bool)CurrentEvent.value << ", focusCtrlWnd " << focusCtrlWnd);
|
||||
if((bool)CurrentEvent.value) {
|
||||
gtk_im_context_focus_in(top->im_context);
|
||||
if(this != focusCtrlWnd) {
|
||||
LLOG("Activate " << Name());
|
||||
SetFocusWnd();
|
||||
}
|
||||
}
|
||||
else {
|
||||
gtk_im_context_focus_out(top->im_context);
|
||||
KillFocusWnd();
|
||||
}
|
||||
return;
|
||||
case GDK_MOTION_NOTIFY: {
|
||||
GtkMouseEvent(MOUSEMOVE, MOUSEMOVE, 0);
|
||||
DoCursorShape();
|
||||
break;
|
||||
}
|
||||
case GDK_BUTTON_PRESS:
|
||||
if(!HasWndFocus() && !popup)
|
||||
SetWndFocus();
|
||||
ClickActivateWnd();
|
||||
GtkButtonEvent(DOWN);
|
||||
break;
|
||||
case GDK_2BUTTON_PRESS:
|
||||
GtkButtonEvent(DOUBLE);
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
if(ignoreclick)
|
||||
EndIgnore();
|
||||
else
|
||||
GtkButtonEvent(UP);
|
||||
break;
|
||||
case GDK_SCROLL: {
|
||||
GtkMouseEvent(MOUSEWHEEL, MOUSEWHEEL, CurrentEvent.value);
|
||||
break;
|
||||
}
|
||||
case GDK_KEY_PRESS:
|
||||
pressed = true;
|
||||
case GDK_KEY_RELEASE:
|
||||
kv = CurrentEvent.value;
|
||||
if(kv >= 0 && kv < 65536) {
|
||||
LOG(FormatIntHex(kv) << ' ' << (char)kv);
|
||||
if(kv >= 'a' && kv <= 'z')
|
||||
kv = kv - 'a' + 'A';
|
||||
static Tuple2<int, int> cv[] = {
|
||||
{ GDK_KEY_BackSpace, K_BACKSPACE },
|
||||
{ GDK_KEY_Tab, K_TAB },
|
||||
{ GDK_KEY_Return, K_ENTER },
|
||||
{ GDK_KEY_Escape, K_ESCAPE },
|
||||
};
|
||||
Tuple2<int, int> *x = FindTuple(cv, __countof(cv), kv);
|
||||
if(x)
|
||||
kv = x->b;
|
||||
else
|
||||
kv += K_DELTA;
|
||||
if(GetShift())
|
||||
kv |= K_SHIFT;
|
||||
if(GetCtrl())
|
||||
kv |= K_CTRL;
|
||||
if(GetAlt())
|
||||
kv |= K_ALT;
|
||||
LLOG(GetKeyDesc(kv) << ", pressed: " << pressed << ", count: " << CurrentEvent.count);
|
||||
DispatchKey(!pressed * K_KEYUP + kv, CurrentEvent.count);
|
||||
}
|
||||
break;
|
||||
case EVENT_TEXT: {
|
||||
WString h = CurrentEvent.value;
|
||||
for(int i = 0; i < h.GetCount(); i++) // TODO: Add compression
|
||||
DispatchKey(h[i], 1);
|
||||
break;
|
||||
}
|
||||
case GDK_CONFIGURE: {
|
||||
Rect rect = CurrentEvent.value;
|
||||
if(GetRect() != rect)
|
||||
SetWndRect(rect);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(_this)
|
||||
_this->PostInput();
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvent0(bool *quit, bool fetch)
|
||||
{
|
||||
ASSERT(IsMainThread());
|
||||
bool r = false;
|
||||
if(IsWaitingEvent0(fetch)) {
|
||||
while(Events.GetCount() > 1) { // Event compression (coalesce autorepeat, mouse moves/wheel, configure)
|
||||
Event& a = Events[0];
|
||||
Event& b = Events[1];
|
||||
if(b.type == a.type && a.windowid == b.windowid && a.state == b.state) {
|
||||
if(a.type == GDK_KEY_PRESS && a.value == b.value)
|
||||
b.count += a.count;
|
||||
else
|
||||
if(a.type == GDK_SCROLL)
|
||||
b.value = (int)b.value + (int)a.value;
|
||||
else
|
||||
if(findarg(a.type, GDK_MOTION_NOTIFY, GDK_CONFIGURE) < 0)
|
||||
break;
|
||||
Events.DropHead();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
Event& e = Events.Head();
|
||||
CurrentTime = e.time;
|
||||
CurrentMousePos = e.mousepos;
|
||||
CurrentState = e.state;
|
||||
CurrentEvent = e;
|
||||
Value val = e.value;
|
||||
Events.DropHead();
|
||||
Ctrl *w = GetTopCtrlFromId(e.windowid);
|
||||
if(w)
|
||||
w->Proc();
|
||||
r = true;
|
||||
}
|
||||
if(quit)
|
||||
*quit = IsEndSession();
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvent(bool *quit)
|
||||
{
|
||||
return ProcessEvent0(quit, true);
|
||||
}
|
||||
|
||||
gboolean Ctrl::TimeHandler(GtkWidget *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SweepMkImageCache();
|
||||
|
||||
bool Ctrl::ProcessEvents0(bool *quit, bool fetch)
|
||||
{
|
||||
bool r = false;
|
||||
while(IsWaitingEvent0(fetch) && (!LoopCtrl || LoopCtrl->InLoop()))
|
||||
r = ProcessEvent0(quit, fetch) || r;
|
||||
TimerProc(GetTickCount());
|
||||
AnimateCaret();
|
||||
if(quit)
|
||||
*quit = IsEndSession();
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(wins[i].ctrl)
|
||||
wins[i].ctrl->SyncScroll();
|
||||
gdk_window_process_all_updates();
|
||||
FetchEvents(FALSE); // To perform any pending GDK_EXPOSE
|
||||
gdk_flush();
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvents(bool *quit)
|
||||
{
|
||||
return ProcessEvents0(quit, true);
|
||||
}
|
||||
|
||||
void Ctrl::SysEndLoop()
|
||||
{
|
||||
}
|
||||
|
||||
void WakeUpGuiThread()
|
||||
{
|
||||
g_main_context_wakeup(g_main_context_default());
|
||||
}
|
||||
|
||||
void Ctrl::EventLoop0(Ctrl *ctrl)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT(LoopLevel == 0 || ctrl);
|
||||
LoopLevel++;
|
||||
LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
|
||||
if(!GetMouseRight() && !GetMouseMiddle() && !GetMouseLeft())
|
||||
ReleaseCtrlCapture();
|
||||
Ptr<Ctrl> ploop;
|
||||
if(ctrl) {
|
||||
ploop = LoopCtrl;
|
||||
LoopCtrl = ctrl;
|
||||
ctrl->inloop = true;
|
||||
}
|
||||
|
||||
while(!IsEndSession() && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()))
|
||||
{
|
||||
FetchEvents(TRUE);
|
||||
ProcessEvents();
|
||||
}
|
||||
|
||||
if(ctrl)
|
||||
LoopCtrl = ploop;
|
||||
LoopLevel--;
|
||||
LLOG(LOG_END << "Leaving event loop ");
|
||||
}
|
||||
|
||||
gboolean sOnce(GtkWidget *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::GuiSleep0(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
if(ms < 20) // Periodic timer is each 20ms, so that is the longest possible wait
|
||||
g_timeout_add(ms, (GSourceFunc) sOnce, NULL); // otherwise setup shorter timer
|
||||
FetchEvents(TRUE);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
111
rainbow/Gtk/GtkKeys.h
Normal file
111
rainbow/Gtk/GtkKeys.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
K_BACK = 8,
|
||||
K_BACKSPACE = 8,
|
||||
|
||||
K_TAB = 9,
|
||||
|
||||
K_RETURN = 13,
|
||||
K_ENTER = 13,
|
||||
K_ESCAPE = 27,
|
||||
|
||||
K_SPACE = 32,
|
||||
|
||||
K_DELETE = GDK_KEY_Delete|K_DELTA,
|
||||
|
||||
K_SHIFT_KEY = GDK_KEY_Shift_L|K_DELTA,
|
||||
K_CTRL_KEY = GDK_KEY_Control_L|K_DELTA,
|
||||
K_ALT_KEY = GDK_KEY_Meta_L|K_DELTA,
|
||||
K_CAPSLOCK = GDK_KEY_Caps_Lock|K_DELTA,
|
||||
K_PRIOR = GDK_KEY_Page_Up|K_DELTA,
|
||||
K_PAGEUP = GDK_KEY_Page_Up|K_DELTA,
|
||||
K_NEXT = GDK_KEY_Page_Down|K_DELTA,
|
||||
K_PAGEDOWN = GDK_KEY_Page_Down|K_DELTA,
|
||||
K_END = GDK_KEY_End|K_DELTA,
|
||||
K_HOME = GDK_KEY_Home|K_DELTA,
|
||||
K_LEFT = GDK_KEY_Left|K_DELTA,
|
||||
K_UP = GDK_KEY_Up|K_DELTA,
|
||||
K_RIGHT = GDK_KEY_Right|K_DELTA,
|
||||
K_DOWN = GDK_KEY_Down|K_DELTA,
|
||||
K_INSERT = GDK_KEY_Insert|K_DELTA,
|
||||
|
||||
K_NUMPAD0 = GDK_KEY_KP_0|K_DELTA,
|
||||
K_NUMPAD1 = GDK_KEY_KP_1|K_DELTA,
|
||||
K_NUMPAD2 = GDK_KEY_KP_2|K_DELTA,
|
||||
K_NUMPAD3 = GDK_KEY_KP_3|K_DELTA,
|
||||
K_NUMPAD4 = GDK_KEY_KP_4|K_DELTA,
|
||||
K_NUMPAD5 = GDK_KEY_KP_5|K_DELTA,
|
||||
K_NUMPAD6 = GDK_KEY_KP_6|K_DELTA,
|
||||
K_NUMPAD7 = GDK_KEY_KP_7|K_DELTA,
|
||||
K_NUMPAD8 = GDK_KEY_KP_8|K_DELTA,
|
||||
K_NUMPAD9 = GDK_KEY_KP_9|K_DELTA,
|
||||
K_MULTIPLY = GDK_KEY_KP_Multiply|K_DELTA,
|
||||
K_ADD = GDK_KEY_KP_Add|K_DELTA,
|
||||
K_SEPARATOR = GDK_KEY_KP_Separator|K_DELTA,
|
||||
K_SUBTRACT = GDK_KEY_KP_Subtract|K_DELTA,
|
||||
K_DECIMAL = GDK_KEY_KP_Decimal|K_DELTA,
|
||||
K_DIVIDE = GDK_KEY_KP_Divide|K_DELTA,
|
||||
|
||||
K_SCROLL = GDK_KEY_Scroll_Lock|K_DELTA,
|
||||
|
||||
K_F1 = GDK_KEY_F1|K_DELTA,
|
||||
K_F2 = GDK_KEY_F2|K_DELTA,
|
||||
K_F3 = GDK_KEY_F3|K_DELTA,
|
||||
K_F4 = GDK_KEY_F4|K_DELTA,
|
||||
K_F5 = GDK_KEY_F5|K_DELTA,
|
||||
K_F6 = GDK_KEY_F6|K_DELTA,
|
||||
K_F7 = GDK_KEY_F7|K_DELTA,
|
||||
K_F8 = GDK_KEY_F8|K_DELTA,
|
||||
K_F9 = GDK_KEY_F9|K_DELTA,
|
||||
K_F10 = GDK_KEY_F10|K_DELTA,
|
||||
K_F11 = GDK_KEY_F11|K_DELTA,
|
||||
K_F12 = GDK_KEY_F12|K_DELTA,
|
||||
|
||||
K_A = GDK_KEY_A|K_DELTA,
|
||||
K_B = GDK_KEY_B|K_DELTA,
|
||||
K_C = GDK_KEY_C|K_DELTA,
|
||||
K_D = GDK_KEY_D|K_DELTA,
|
||||
K_E = GDK_KEY_E|K_DELTA,
|
||||
K_F = GDK_KEY_F|K_DELTA,
|
||||
K_G = GDK_KEY_G|K_DELTA,
|
||||
K_H = GDK_KEY_H|K_DELTA,
|
||||
K_I = GDK_KEY_I|K_DELTA,
|
||||
K_J = GDK_KEY_J|K_DELTA,
|
||||
K_K = GDK_KEY_K|K_DELTA,
|
||||
K_L = GDK_KEY_L|K_DELTA,
|
||||
K_M = GDK_KEY_M|K_DELTA,
|
||||
K_N = GDK_KEY_N|K_DELTA,
|
||||
K_O = GDK_KEY_O|K_DELTA,
|
||||
K_P = GDK_KEY_P|K_DELTA,
|
||||
K_Q = GDK_KEY_Q|K_DELTA,
|
||||
K_R = GDK_KEY_R|K_DELTA,
|
||||
K_S = GDK_KEY_S|K_DELTA,
|
||||
K_T = GDK_KEY_T|K_DELTA,
|
||||
K_U = GDK_KEY_U|K_DELTA,
|
||||
K_V = GDK_KEY_V|K_DELTA,
|
||||
K_W = GDK_KEY_W|K_DELTA,
|
||||
K_X = GDK_KEY_X|K_DELTA,
|
||||
K_Y = GDK_KEY_Y|K_DELTA,
|
||||
K_Z = GDK_KEY_Z|K_DELTA,
|
||||
K_0 = GDK_KEY_0|K_DELTA,
|
||||
K_1 = GDK_KEY_1|K_DELTA,
|
||||
K_2 = GDK_KEY_2|K_DELTA,
|
||||
K_3 = GDK_KEY_3|K_DELTA,
|
||||
K_4 = GDK_KEY_4|K_DELTA,
|
||||
K_5 = GDK_KEY_5|K_DELTA,
|
||||
K_6 = GDK_KEY_6|K_DELTA,
|
||||
K_7 = GDK_KEY_7|K_DELTA,
|
||||
K_8 = GDK_KEY_8|K_DELTA,
|
||||
K_9 = GDK_KEY_9|K_DELTA,
|
||||
|
||||
K_CTRL_LBRACKET = K_CTRL|GDK_KEY_bracketleft|K_DELTA,
|
||||
K_CTRL_RBRACKET = K_CTRL|GDK_KEY_bracketright|K_DELTA,
|
||||
K_CTRL_MINUS = K_CTRL|GDK_KEY_minus|K_DELTA,
|
||||
K_CTRL_GRAVE = K_CTRL|GDK_KEY_grave|K_DELTA,
|
||||
K_CTRL_SLASH = K_CTRL|GDK_KEY_slash|K_DELTA,
|
||||
K_CTRL_BACKSLASH = K_CTRL|GDK_KEY_backslash|K_DELTA,
|
||||
K_CTRL_COMMA = K_CTRL|GDK_KEY_comma|K_DELTA,
|
||||
K_CTRL_PERIOD = K_CTRL|GDK_KEY_period|K_DELTA,
|
||||
K_CTRL_SEMICOLON = K_CTRL|GDK_KEY_semicolon|K_DELTA,
|
||||
K_CTRL_EQUAL = K_CTRL|GDK_KEY_equal|K_DELTA,
|
||||
K_CTRL_APOSTROPHE= K_CTRL|GDK_KEY_apostrophe|K_DELTA,
|
||||
|
||||
K_BREAK = GDK_KEY_Break|K_DELTA,
|
||||
252
rainbow/Gtk/GtkTop.cpp
Normal file
252
rainbow/Gtk/GtkTop.cpp
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void TopWindow::SyncSizeHints()
|
||||
{
|
||||
GuiLock __;
|
||||
if(!top)
|
||||
return;
|
||||
GdkGeometry m;
|
||||
Size sz0 = GetRect().GetSize();
|
||||
Size sz = sz0;
|
||||
if(sizeable)
|
||||
sz = GetMinSize();
|
||||
m.min_width = sz.cx;
|
||||
m.min_height = sz.cy;
|
||||
sz = sz0;
|
||||
if(sizeable)
|
||||
sz = GetMaxSize();
|
||||
m.max_width = sz.cx;
|
||||
m.max_height = sz.cy;
|
||||
gtk_window_set_resizable(gtk(), sizeable);
|
||||
gtk_window_set_geometry_hints(gtk(), top->window, &m, GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE));
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle0()
|
||||
{
|
||||
GuiLock __;
|
||||
if(top)
|
||||
gtk_window_set_title(gtk(), FromUnicode(title, CHARSET_UTF8));
|
||||
}
|
||||
|
||||
void TopWindow::SyncCaption0()
|
||||
{
|
||||
GuiLock __;
|
||||
SyncTitle0();
|
||||
if(top) {
|
||||
if(gdk_icon.Set(icon))
|
||||
gtk_window_set_icon(gtk(), gdk_icon);
|
||||
gtk_window_set_decorated(gtk(), !frameless);
|
||||
gtk_window_set_urgency_hint(gtk(), urgent);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindow::CenterRect(Ctrl *owner)
|
||||
{
|
||||
GuiLock __;
|
||||
SetupRect();
|
||||
if(owner && center == 1 || center == 2) {
|
||||
Size sz = GetRect().Size();
|
||||
Rect r, wr;
|
||||
wr = Ctrl::GetWorkArea();
|
||||
// TODO: Add Frame support
|
||||
if(center == 1)
|
||||
r = owner->GetRect();
|
||||
else
|
||||
r = wr;
|
||||
Point p = r.CenterPos(sz);
|
||||
r = RectC(p.x, p.y, sz.cx, sz.cy);
|
||||
if(r.top < wr.top) {
|
||||
r.bottom += wr.top - r.top;
|
||||
r.top = wr.top;
|
||||
}
|
||||
if(r.bottom > wr.bottom)
|
||||
r.bottom = wr.bottom;
|
||||
minsize.cx = min(minsize.cx, r.GetWidth());
|
||||
minsize.cy = min(minsize.cy, r.GetHeight());
|
||||
SetRect(r);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean TopWindow::StateEvent(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
|
||||
{
|
||||
TopWindow *w = (TopWindow *)user_data;
|
||||
dword h = event->new_window_state;
|
||||
if(h & GDK_WINDOW_STATE_FULLSCREEN)
|
||||
w->state = FULLSCREEN;
|
||||
else
|
||||
if(h & GDK_WINDOW_STATE_ICONIFIED)
|
||||
w->state = MINIMIZED;
|
||||
else
|
||||
if(h & GDK_WINDOW_STATE_MAXIMIZED)
|
||||
w->state = MAXIMIZED;
|
||||
else
|
||||
w->state = OVERLAPPED;
|
||||
w->topmost = h & GDK_WINDOW_STATE_ABOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TopWindow::Open(Ctrl *owner)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("OPEN " << Name() << " owner: " << UPP::Name(owner));
|
||||
if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
|
||||
DistributeAccessKeys();
|
||||
if(fullscreen)
|
||||
SetRect(GetPrimaryScreenArea());
|
||||
else
|
||||
CenterRect(owner);
|
||||
IgnoreMouseUp();
|
||||
Create(owner, false);
|
||||
g_signal_connect(top->window, "window-state-event", G_CALLBACK(StateEvent), this);
|
||||
SyncSizeHints();
|
||||
SyncCaption();
|
||||
PlaceFocus();
|
||||
int q = state;
|
||||
state = OVERLAPPED;
|
||||
SetMode(q);
|
||||
SyncTopMost();
|
||||
}
|
||||
|
||||
void TopWindow::Open()
|
||||
{
|
||||
Open(GetActiveWindow()); //TODO!
|
||||
}
|
||||
|
||||
void TopWindow::OpenMain()
|
||||
{
|
||||
Open(NULL);
|
||||
}
|
||||
|
||||
void TopWindow::SyncTopMost()
|
||||
{
|
||||
if(top)
|
||||
gtk_window_set_keep_above(gtk(), topmost);
|
||||
}
|
||||
|
||||
void TopWindow::SetMode(int mode)
|
||||
{
|
||||
GtkWindow *w = gtk();
|
||||
if(w)
|
||||
switch(state) {
|
||||
case MINIMIZED:
|
||||
gtk_window_deiconify(w);
|
||||
break;
|
||||
case MAXIMIZED:
|
||||
gtk_window_unmaximize(w);
|
||||
break;
|
||||
case FULLSCREEN:
|
||||
gtk_window_unfullscreen(w);
|
||||
break;
|
||||
}
|
||||
state = mode;
|
||||
if(w)
|
||||
switch(state) {
|
||||
case MINIMIZED:
|
||||
gtk_window_iconify(w);
|
||||
break;
|
||||
case MAXIMIZED:
|
||||
gtk_window_maximize(w);
|
||||
break;
|
||||
case FULLSCREEN:
|
||||
gtk_window_fullscreen(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TopWindow::Minimize(bool effect)
|
||||
{
|
||||
SetMode(MINIMIZED);
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::FullScreen(bool b)
|
||||
{
|
||||
SetMode(FULLSCREEN);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TopWindow::Maximize(bool effect)
|
||||
{
|
||||
SetMode(MAXIMIZED);
|
||||
}
|
||||
|
||||
void TopWindow::Overlap(bool effect)
|
||||
{
|
||||
SetMode(OVERLAPPED);
|
||||
}
|
||||
|
||||
TopWindow& TopWindow::TopMost(bool b, bool)
|
||||
{
|
||||
GuiLock __;
|
||||
topmost = b;
|
||||
SyncTopMost();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TopWindow::IsTopMost() const
|
||||
{
|
||||
GuiLock __;
|
||||
return topmost;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformConstruct()
|
||||
{
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformDestruct()
|
||||
{
|
||||
}
|
||||
|
||||
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
|
||||
{
|
||||
GuiLock __;
|
||||
int version = 0;
|
||||
s / version;
|
||||
Rect rect = GetRect();
|
||||
s % overlapped % rect;
|
||||
bool mn = state == MINIMIZED;
|
||||
bool mx = state == MAXIMIZED;
|
||||
s.Pack(mn, mx);
|
||||
LLOG("TopWindow::SerializePlacement / " << (s.IsStoring() ? "write" : "read"));
|
||||
LLOG("minimized = " << mn << ", maximized = " << mx);
|
||||
LLOG("rect = " << rect << ", overlapped = " << overlapped);
|
||||
if(s.IsLoading()) {
|
||||
if(mn) rect = overlapped;
|
||||
Rect limit = GetWorkArea();
|
||||
Rect fm = windowFrameMargin;
|
||||
if((fm.left|fm.right|fm.top|fm.bottom) == 0)
|
||||
fm = Rect(8, 32, 8, 8);
|
||||
limit.left += fm.left;
|
||||
limit.right -= fm.right;
|
||||
limit.top += fm.top;
|
||||
limit.bottom -= fm.bottom;
|
||||
Size sz = min(rect.Size(), limit.Size());
|
||||
rect = RectC(
|
||||
minmax(rect.left, limit.left, limit.right - sz.cx),
|
||||
minmax(rect.top, limit.top, limit.bottom - sz.cy),
|
||||
sz.cx, sz.cy);
|
||||
state = OVERLAPPED;
|
||||
if(mn && reminimize)
|
||||
state = MINIMIZED;
|
||||
if(mx)
|
||||
state = MAXIMIZED;
|
||||
if(state == OVERLAPPED)
|
||||
SetRect(rect);
|
||||
if(IsOpen()) {
|
||||
if(state == MINIMIZED)
|
||||
Minimize(false);
|
||||
if(state == MAXIMIZED)
|
||||
Maximize(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
14
rainbow/Gtk/GtkTop.h
Normal file
14
rainbow/Gtk/GtkTop.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
//$ class TopWindow : Ctrl {
|
||||
ImageGdk gdk_icon;
|
||||
bool topmost;
|
||||
|
||||
enum { FULLSCREEN = 99 };
|
||||
|
||||
void CenterRect(Ctrl *owner);
|
||||
void SetMode(int mode);
|
||||
void SyncTopMost();
|
||||
|
||||
static gboolean StateEvent(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data);
|
||||
|
||||
friend class Ctrl;
|
||||
//$ };
|
||||
149
rainbow/Gtk/GtkUtil.cpp
Normal file
149
rainbow/Gtk/GtkUtil.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff)
|
||||
{
|
||||
}
|
||||
|
||||
void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, const int *pattern, Color color, int animation)
|
||||
{
|
||||
if(len <= 0)
|
||||
return;
|
||||
if(horz)
|
||||
w.Clip(x, y, len, n);
|
||||
else
|
||||
w.Clip(x, y, n, len);
|
||||
|
||||
(horz ? x : y) -= animation;
|
||||
len += animation;
|
||||
bool ch = false;
|
||||
while(len > 0) {
|
||||
int segment = pattern[ch];
|
||||
int d = segment + pattern[2];
|
||||
if(horz) {
|
||||
w.DrawRect(x, y, segment, n, color);
|
||||
x += d;
|
||||
}
|
||||
else {
|
||||
w.DrawRect(x, y, n, segment, color);
|
||||
y += d;
|
||||
}
|
||||
len -= d;
|
||||
ch = !ch;
|
||||
}
|
||||
w.End();
|
||||
}
|
||||
|
||||
void DrawDragFrame(SystemDraw& w, const Rect& r, int n, const int *pattern, Color color, int animation)
|
||||
{
|
||||
DrawDragLine(w, true, r.left, r.top, r.GetWidth(), n, pattern, color, animation);
|
||||
DrawDragLine(w, false, r.left, r.top + n, r.GetHeight() - 2 * n, n, pattern, color, animation);
|
||||
DrawDragLine(w, false, r.right - n, r.top + n, r.GetHeight() - 2 * n, n, pattern, color, animation);
|
||||
DrawDragLine(w, true, r.left, r.bottom - n, r.GetWidth(), n, pattern, color, animation);
|
||||
}
|
||||
|
||||
void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f)
|
||||
{
|
||||
ViewDraw w(&q);
|
||||
w.Clip(f.clip);
|
||||
static int dashes[3][3] = {
|
||||
{ 32, 32, 0 },
|
||||
{ 1, 1, 1 },
|
||||
{ 5, 1, 2 },
|
||||
};
|
||||
const int *dash = dashes[minmax(f.type, 0, 2)];
|
||||
Color color = InvertColor;
|
||||
DrawDragFrame(w, f.rect1, f.n, dash, color, f.animation);
|
||||
DrawDragFrame(w, f.rect2, f.n, dash, color, f.animation);
|
||||
w.End();
|
||||
}
|
||||
|
||||
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, int type, int animation)
|
||||
{
|
||||
Ctrl *top = q.GetTopCtrl();
|
||||
if(top && top->top) {
|
||||
Rect sv = q.GetScreenView();
|
||||
Rect tv = top->GetScreenView();
|
||||
Point off = sv.TopLeft() - tv.TopLeft();
|
||||
DrawDragRectInfo& f = top->top->dr.Create();
|
||||
f.rect1 = rect1 + off;
|
||||
f.rect2 = rect2 + off;
|
||||
f.clip = (clip & q.GetSize()) + off;
|
||||
f.n = n;
|
||||
f.color = color;
|
||||
f.type = type;
|
||||
f.animation = animation;
|
||||
DrawDragRect(*top, f);
|
||||
}
|
||||
}
|
||||
|
||||
void FinishDragRect(Ctrl& q)
|
||||
{
|
||||
Ctrl *top = q.GetTopCtrl();
|
||||
if(top && top->top && top->top->dr) {
|
||||
DrawDragRect(*top, *top->top->dr);
|
||||
top->top->dr.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
GdkRect::GdkRect(const Rect& r)
|
||||
{
|
||||
x = r.left;
|
||||
y = r.top;
|
||||
width = r.GetWidth();
|
||||
height = r.GetHeight();
|
||||
}
|
||||
|
||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||
{
|
||||
Image img;
|
||||
if(pixbuf) {
|
||||
if(gdk_pixbuf_get_n_channels (pixbuf) == 4 &&
|
||||
gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB &&
|
||||
gdk_pixbuf_get_bits_per_sample (pixbuf) == 8 &&
|
||||
gdk_pixbuf_get_has_alpha (pixbuf)) {
|
||||
Size sz(gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height(pixbuf));
|
||||
ImageBuffer m(sz);
|
||||
int stride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||
byte *l = (byte *)gdk_pixbuf_get_pixels(pixbuf);
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
RGBA *s = m[y];
|
||||
const RGBA *e = s + sz.cx;
|
||||
const byte *t = l;
|
||||
while(s < e) {
|
||||
s->r = *t++;
|
||||
s->g = *t++;
|
||||
s->b = *t++;
|
||||
s->a = *t++;
|
||||
s++;
|
||||
}
|
||||
l += stride;
|
||||
}
|
||||
img = m;
|
||||
}
|
||||
g_object_unref(pixbuf);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
GdkAtom GAtom(const String& id)
|
||||
{
|
||||
GuiLock __;
|
||||
static VectorMap<String, GdkAtom> m;
|
||||
int q = m.Find(id);
|
||||
return q >= 0 ? m[q] : (m.Add(id) = gdk_atom_intern(~id, FALSE));
|
||||
}
|
||||
|
||||
int rmsecs()
|
||||
{
|
||||
static int msecs0 = msecs();
|
||||
return msecs(msecs0);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
474
rainbow/Gtk/GtkWnd.cpp
Normal file
474
rainbow/Gtk/GtkWnd.cpp
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
#include <CtrlCore/CtrlCore.h>
|
||||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
Vector<Ctrl::Win> Ctrl::wins;
|
||||
|
||||
int Ctrl::WndCaretTime;
|
||||
bool Ctrl::WndCaretVisible;
|
||||
|
||||
int Ctrl::FindId(int id)
|
||||
{
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(wins[i].id == id)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Ctrl::FindCtrl(Ctrl *ctrl)
|
||||
{
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(wins[i].ctrl == ctrl)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Ctrl::FindGtkWindow(GtkWidget *gtk)
|
||||
{
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(wins[i].gtk == gtk)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Ctrl::FindGdkWindow(GdkWindow *gdk)
|
||||
{
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(wins[i].gdk == gdk)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Ctrl::IsAlphaSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::IsCompositedGui()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<Ctrl *> Ctrl::GetTopCtrls()
|
||||
{
|
||||
GuiLock __;
|
||||
Vector<Ctrl *> h;
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
h.Add(wins[i].ctrl);
|
||||
return h;
|
||||
}
|
||||
|
||||
void Ctrl::SetMouseCursor(const Image& image)
|
||||
{
|
||||
GuiLock __;
|
||||
int64 id = image.GetSerialId();
|
||||
Ctrl *topctrl = NULL;
|
||||
Top *top = NULL;
|
||||
if(mouseCtrl)
|
||||
topctrl = mouseCtrl->GetTopCtrl();
|
||||
if(topctrl)
|
||||
top = topctrl->top;
|
||||
if(top && id != top->cursor_id) {
|
||||
top->cursor_id = id;
|
||||
int64 aux = image.GetAuxData();
|
||||
GdkCursor *c = NULL;
|
||||
if(aux)
|
||||
c = gdk_cursor_new((GdkCursorType)(aux - 1));
|
||||
else
|
||||
if(IsNull(image))
|
||||
c = gdk_cursor_new(GDK_BLANK_CURSOR);
|
||||
else {
|
||||
Point p = image.GetHotSpot();
|
||||
ImageGdk m;
|
||||
m.Set(image);
|
||||
GdkPixbuf *pb = m;
|
||||
if(pb)
|
||||
c = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pb, p.x, p.y);
|
||||
}
|
||||
if(c) {
|
||||
gdk_window_set_cursor(topctrl->gdk(), c);
|
||||
gdk_cursor_unref(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetOwner()
|
||||
{
|
||||
GuiLock __;
|
||||
return top ? top->owner : NULL;
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetActiveCtrl()
|
||||
{
|
||||
GuiLock __;
|
||||
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
|
||||
}
|
||||
|
||||
// Vector<Callback> Ctrl::hotkey;
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Callback cb)
|
||||
{
|
||||
/* ASSERT(key >= K_DELTA);
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= MOD_ALT;
|
||||
if(key & K_SHIFT)
|
||||
mod |= MOD_SHIFT;
|
||||
if(key & K_CTRL)
|
||||
mod |= MOD_CONTROL;
|
||||
|
||||
return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
/* if(id >= 0 && id < hotkey.GetCount()) {
|
||||
UnregisterHotKey(NULL, id);
|
||||
hotkey[id].Clear();
|
||||
}*/
|
||||
}
|
||||
|
||||
void Ctrl::FocusSync()
|
||||
{
|
||||
GuiLock __;
|
||||
if(focusCtrlWnd && gtk_window_is_active(focusCtrlWnd->gtk()))
|
||||
return;
|
||||
Ptr<Ctrl> focus = NULL;
|
||||
static Ctrl *ctrl;
|
||||
for(int i = 0; i < wins.GetCount(); i++)
|
||||
if(gtk_window_is_active((GtkWindow *)wins[i].gtk)) {
|
||||
focus = wins[i].ctrl;
|
||||
break;
|
||||
}
|
||||
if(focus != ctrl) {
|
||||
if(ctrl)
|
||||
ctrl->KillFocusWnd();
|
||||
ctrl = focus;
|
||||
if(ctrl)
|
||||
ctrl->SetFocusWnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::AnimateCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
int v = !(((GetTickCount() - WndCaretTime) / 500) & 1);
|
||||
if(v != WndCaretVisible) {
|
||||
WndCaretVisible = v;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible);
|
||||
if(this == caretCtrl && WndCaretVisible)
|
||||
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetCaret " << Name());
|
||||
if(this == caretCtrl)
|
||||
RefreshCaret();
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
if(this == caretCtrl) {
|
||||
WndCaretTime = GetTickCount();
|
||||
RefreshCaret();
|
||||
AnimateCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
if(focusCtrl != caretCtrl) {
|
||||
LLOG("SyncCaret DO " << Upp::Name(caretCtrl) << " -> " << Upp::Name(focusCtrl));
|
||||
RefreshCaret();
|
||||
caretCtrl = focusCtrl;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWndScreenRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
if(top) {
|
||||
gint x, y;
|
||||
gdk_window_get_position(gdk(), &x, &y);
|
||||
gint width = gdk_window_get_width(gdk());
|
||||
gint height = gdk_window_get_height(gdk());
|
||||
return RectC(x, y, width, height);
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
void Ctrl::WndShow0(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndShow " << Name() << ", " << b);
|
||||
if(top) {
|
||||
if(b)
|
||||
gtk_widget_show_now(top->window);
|
||||
else
|
||||
gtk_widget_hide(top->window);
|
||||
StateH(SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndOpen() const {
|
||||
GuiLock __;
|
||||
return top && top->window && top->window->window;
|
||||
}
|
||||
|
||||
void Ctrl::SetAlpha(byte alpha)
|
||||
{
|
||||
GuiLock __;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea() const
|
||||
{
|
||||
GuiLock __;
|
||||
return GetWorkArea(GetRect().TopLeft());
|
||||
}
|
||||
|
||||
void Ctrl::GetWorkArea(Array<Rect>& rc)
|
||||
{
|
||||
GuiLock __;
|
||||
GdkScreen *s = gdk_screen_get_default();
|
||||
int n = gdk_screen_get_n_monitors(s);
|
||||
rc.Clear();
|
||||
for(int i = 0; i < n; i++) {
|
||||
GdkRectangle r;
|
||||
gdk_screen_get_monitor_geometry(s, i, &r); // TODO: Use WorkArea (for GTK 3.4)
|
||||
rc.Add(RectC(r.x, r.y, r.width, r.height));
|
||||
}
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWorkArea(Point pt)
|
||||
{
|
||||
Array<Rect> rc;
|
||||
GetWorkArea(rc);
|
||||
for(int i = 0; i < rc.GetCount(); i++)
|
||||
if(rc[i].Contains(pt))
|
||||
return rc[i];
|
||||
return GetPrimaryWorkArea();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualWorkArea()
|
||||
{
|
||||
Rect out = GetPrimaryWorkArea();
|
||||
Array<Rect> rc;
|
||||
GetWorkArea(rc);
|
||||
for(int i = 0; i < rc.GetCount(); i++)
|
||||
out |= rc[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
Rect Ctrl::GetVirtualScreenArea()
|
||||
{
|
||||
GuiLock __;
|
||||
gint x, y, width, height;
|
||||
gdk_window_get_geometry(gdk_screen_get_root_window(gdk_screen_get_default()),
|
||||
&x, &y, &width, &height, NULL);
|
||||
return RectC(x, y, width, height);
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryWorkArea()
|
||||
{
|
||||
Array<Rect> rc;
|
||||
GetWorkArea(rc);
|
||||
return rc.GetCount() ? rc[0] : RectC(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Rect Ctrl::GetPrimaryScreenArea()
|
||||
{
|
||||
return GetPrimaryWorkArea();
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdDelay()
|
||||
{
|
||||
GuiLock __;
|
||||
return 500;
|
||||
}
|
||||
|
||||
int Ctrl::GetKbdSpeed()
|
||||
{
|
||||
GuiLock __;
|
||||
return 1000 / 32;
|
||||
}
|
||||
|
||||
void Ctrl::SetWndForeground0()
|
||||
{
|
||||
GuiLock __;
|
||||
if(top)
|
||||
gtk_window_present(gtk());
|
||||
}
|
||||
|
||||
bool Ctrl::IsWndForeground() const
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("IsWndForeground");
|
||||
return top && gtk_window_is_active(gtk());
|
||||
}
|
||||
|
||||
void Ctrl::WndEnable0(bool *b)
|
||||
{
|
||||
GuiLock __;
|
||||
if(top) {
|
||||
gtk_widget_set_sensitive(top->window, *b);
|
||||
StateH(ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SetWndFocus0(bool *b)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetWndFocus0 " << top);
|
||||
if(top) {
|
||||
LLOG("SetWndFocus0 DO " << top->window);
|
||||
gdk_window_focus(gdk(), CurrentTime);
|
||||
*b = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndFocus() const
|
||||
{
|
||||
GuiLock __;
|
||||
return top && gtk_widget_is_focus(top->window);
|
||||
}
|
||||
|
||||
void Ctrl::WndInvalidateRect(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndInvalidateRect " << r);
|
||||
gdk_window_invalidate_rect(gdk(), GdkRect(r), TRUE);
|
||||
// gtk_widget_queue_draw_area(top->window, r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
}
|
||||
|
||||
void Ctrl::WndScrollView0(const Rect& r, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("ScrollView " << rect);
|
||||
WndInvalidateRect(r);
|
||||
}
|
||||
|
||||
bool Ctrl::SweepConfigure(bool wait)
|
||||
{
|
||||
bool r = false;
|
||||
FetchEvents(wait);
|
||||
for(int i = 0; i < Events.GetCount(); i++) {
|
||||
Event& e = Events[i];
|
||||
if(e.type == GDK_CONFIGURE && top->id == e.windowid) {
|
||||
Rect rect = e.value;
|
||||
LLOG("SweepConfigure " << rect);
|
||||
if(GetRect() != rect)
|
||||
SetWndRect(rect);
|
||||
r = true;
|
||||
e.type = EVENT_NONE;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void Ctrl::WndSetPos0(const Rect& rect)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndSetPos0 " << rect);
|
||||
if(!top)
|
||||
return;
|
||||
SweepConfigure(false); // Remove any previous GDK_CONFIGURE for this window
|
||||
gtk_window_move(gtk(), rect.left, rect.top);
|
||||
gtk_window_resize(gtk(), rect.GetWidth(), rect.GetHeight());
|
||||
int t0 = msecs();
|
||||
do { // Wait up to 500ms for corresponding GDK_CONFIGURE to arrive
|
||||
if(SweepConfigure(true))
|
||||
break;
|
||||
}
|
||||
while(msecs() - t0 < 500);
|
||||
LLOG("-- WndSetPos0 " << rect << " " << msecs() - t0);
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate0r(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndUpdate0r " << r);
|
||||
WndUpdate0(); // Not found a way how to update only part of window
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate0()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndUpdate0");
|
||||
gdk_window_process_updates(gdk(), TRUE);
|
||||
FetchEvents(FALSE); // Should pickup GDK_EXPOSE and repaint the window
|
||||
gdk_flush();
|
||||
}
|
||||
|
||||
Rect Ctrl::GetDefaultWindowRect()
|
||||
{
|
||||
GuiLock __;
|
||||
Size sz = GetPrimaryWorkArea().GetSize();
|
||||
static int pos = min(sz.cx / 10, 50);
|
||||
pos += 10;
|
||||
int cx = sz.cx * 2 / 3;
|
||||
int cy = sz.cy * 2 / 3;
|
||||
if(pos + cx + 50 > sz.cx || pos + cy + 50 > sz.cy)
|
||||
pos = 0;
|
||||
return RectC(pos + 20, pos + 20, cx, cy);
|
||||
}
|
||||
|
||||
ViewDraw::ViewDraw(Ctrl *ctrl)
|
||||
{
|
||||
EnterGuiMutex();
|
||||
Ctrl *top = ctrl->GetTopCtrl();
|
||||
cr = gdk_cairo_create(top->gdk());
|
||||
Clipoff(ctrl->GetScreenView() - top->GetScreenRect().TopLeft());
|
||||
}
|
||||
|
||||
ViewDraw::~ViewDraw()
|
||||
{
|
||||
cairo_destroy(cr);
|
||||
LeaveGuiMutex();
|
||||
}
|
||||
|
||||
Vector<WString> SplitCmdLine__(const char *cmd)
|
||||
{
|
||||
Vector<WString> out;
|
||||
while(*cmd)
|
||||
if((byte)*cmd <= ' ')
|
||||
cmd++;
|
||||
else if(*cmd == '\"') {
|
||||
WString quoted;
|
||||
while(*++cmd && (*cmd != '\"' || *++cmd == '\"'))
|
||||
quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString());
|
||||
out.Add(quoted);
|
||||
}
|
||||
else {
|
||||
const char *begin = cmd;
|
||||
while((byte)*cmd > ' ')
|
||||
cmd++;
|
||||
out.Add(String(begin, cmd).ToWString());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
3
rainbow/Gtk/init
Normal file
3
rainbow/Gtk/init
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef _Gtk_icpp_init_stub
|
||||
#define _Gtk_icpp_init_stub
|
||||
#endif
|
||||
12
rainbow/GtkMain/GtkMain.upp
Normal file
12
rainbow/GtkMain/GtkMain.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
uses
|
||||
CtrlLib,
|
||||
Gtk,
|
||||
RichEdit;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI GTK",
|
||||
"" = "GUI";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue