#pragma once
#include <Gorgon/Window.h>
#include <Gorgon/WindowManager.h>
#include <Gorgon/Main.h>
#include <Gorgon/Graphics/Layer.h>
#include <Gorgon/Graphics/Bitmap.h>
#include <Gorgon/Graphics/FreeType.h>
#include <Gorgon/OS.h>
#include <Gorgon/UI.h>
#include <Gorgon/Widgets/Generator.h>
#ifdef LINUX
#include <unistd.h>
#include <wait.h>
namespace Gorgon { namespace OS {
bool Start(const std::string &name, std::streambuf *&buf, const std::vector<std::string> &args);
} }
#endif
using namespace Gorgon;
namespace WM = Gorgon::WindowManager;
using Graphics::Bitmap;
Graphics::Bitmap BGImage(int w, int h, Byte col1 = 0x10, Byte col2 = 0x30);
template<class W_>
class basic_Application {
public:
basic_Application(std::string appname, std::string title, std::string helptext, int tilesize=25, int colmod = 0x10, Gorgon::Geometry::Size size={800,600}) :
appname(appname)
{
std::cout<<"Current working directory: ";
#ifdef WIN32
system("cd");
#else
system("pwd");
#endif
std::cout<<std::endl;
Gorgon::Initialize(appname);
wind = W_{size, appname, title, true};
//Gorgon::GL::log.InitializeConsole();
Graphics::Initialize();
auto &gen = *new Gorgon::Widgets::SimpleGenerator;
gen.Init("xyz", "", 7.5);
UI::Initialize(gen);
//UI::Initialize();
wind.ClosingEvent.Register([] { exit(0); });
l.setname("BG");
wind.Add(l);
if(icon.Import("icon.png")) {
ico = WM::Icon{icon.GetData()};
wind.SetIcon(ico);
}
wind.setname("Wind");
if(tilesize) {
bgimage = BGImage(tilesize, tilesize, colmod, colmod*3);
bgimage.Prepare();
bgimage.DrawIn(l);
}
int sz = 13;
#ifdef WIN32
fnt.LoadFile("C:/Windows/Fonts/tahoma.ttf", sz);
fntlarge.LoadFile("C:/Windows/Fonts/tahoma.ttf", int(std::round(sz*1.5)));
fntsmall.LoadFile("C:/Windows/Fonts/tahoma.ttf", int(std::round(sz*0.8)));
#else
bool found = false;
std::streambuf *buf;
OS::Start("fc-match", buf, {"-v", "sans"});
if(buf) {
std::istream in(buf);
std::string line;
while(getline(in, line)) {
line = String::Trim(line);
auto name = String::Extract(line, ':', true);
if(name == "file") {
String::Extract(line, '"', true);
auto fname = String::Extract(line, '"', true);
std::cout<<fname<<std::endl;
found = fnt.LoadFile(fname, sz);
if(found)
fntlarge.LoadFile(fname, sz*1.5);
if(found)
fntsmall.LoadFile(fname, sz*0.7);
break;
}
}
delete buf;
}
if(!found) {
fnt.LoadFile("/usr/share/fonts/gnu-free/FreeSans.ttf", sz);
fntlarge.LoadFile("/usr/share/fonts/gnu-free/FreeSans.ttf", sz*1.5);
fntsmall.LoadFile("/usr/share/fonts/gnu-free/FreeSans.ttf", sz*0.7);
}
#endif
/*if(!fnt.HasKerning()) {
auto bmpfnt = new Graphics::BitmapFont(fnt.MoveOutBitmap());
sty.SetGlyphRenderer(*bmpfnt);
bmpfnt->AutoKern();
}*/
sty.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
sty.SetColor({0.6f, 1.f, 1.f});
sty.JustifyLeft();
stylarge.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
stylarge.SetColor({1.f, 1.f, 1.f});
stylarge.AlignCenter();
sty.SetTabWidthInLetters(4);
sty.SetParagraphSpacing(4);
sty.Print(l,
helptext
, 600, 10, wind.GetWidth()-605
);
wind.KeyEvent.Register([](Input::Key key, bool state) {
namespace Keycodes = Gorgon::Input::Keyboard::Keycodes;
if(!state && (key == Keycodes::Escape))
exit(0);
return false;
});
}
W_ wind;
Graphics::Layer l;
Bitmap bgimage, icon;
Graphics::FreeType fnt, fntlarge, fntsmall;
Graphics::StyledPrinter sty = {fnt}, stylarge = {fntlarge}, stysmall = {fntsmall};
WM::Icon ico;
std::string appname;
};
using Application = basic_Application<Gorgon::Window>;
inline Graphics::Bitmap Circle(int r) {
Graphics::Bitmap b({r*2+3, r*2+3}, Graphics::ColorMode::Alpha);
auto ri = (r-0.5)*(r-0.5);
auto ro = (r+0.5)*(r+0.5);
for(int y=0; y<b.GetHeight(); y++) {
for(int x=0; x<b.GetWidth(); x++) {
float xx = float(x - (r+1));
float yy = float(y - (r+1));
float ds = xx*xx + yy*yy;
int v;
if(ds < ri) {
v = 0xff;
}
else if(ds <= ro) {
v = int(0xff * (1 - (sqrt(ds) - (r-0.5))));
}
else {
v = 0;
}
b(x,y,0) = v;
}
}
return b;
}
inline Graphics::Bitmap Triangle(int w, int h) {
Graphics::Bitmap b({2*w+1, h}, Graphics::ColorMode::Alpha);
float cw = 0.5;
float xinc = float(w)/h;
for(int y=0; y<h; y++) {
for(int x=0; x<b.GetWidth(); x++) {
if(x>w-floor(cw) && x<w+floor(cw)) {
b(x,y,0) = 255;
}
else if(x>w-ceil(cw) && x<w+ceil(cw)) {
b(x,y,0) = Byte(255*(cw-floor(cw)));
}
else {
b(x,y,0) = 0;
}
}
cw += xinc;
}
return b;
}
inline Graphics::Bitmap Triangle1(int w, int h) {
Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
float cw = 1;
float xinc = float(w)/h;
for(int y=0; y<h; y++) {
for(int x=0; x<b.GetWidth(); x++) {
if(x<floor(cw)) {
b(x,y,0) = 255;
}
else if(x<ceil(cw)) {
b(x,y,0) = Byte(255*(cw-floor(cw)));
}
else {
b(x,y,0) = 0;
}
}
cw += xinc;
}
return b;
}
inline Graphics::Bitmap Triangle2(int w, int h) {
Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
float cw = 1;
float xinc = float(w)/h;
for(int y=0; y<h; y++) {
for(int x=0; x<b.GetWidth(); x++) {
if(x>w-floor(cw)) {
b(x,y,0) = 255;
}
else if(x>w-ceil(cw)) {
b(x,y,0) = Byte(255*(cw-floor(cw)));
}
else {
b(x,y,0) = 0;
}
}
cw += xinc;
}
return b;
}
inline Graphics::Bitmap Triangle4(int w, int h) {
Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
float cw = 1;
float xinc = float(w)/h;
for(int y=0; y<h; y++) {
for(int x=0; x<b.GetWidth(); x++) {
if(x<floor(cw)) {
b(x,h-y-1,0) = 255;
}
else if(x<ceil(cw)) {
b(x,h-y-1,0) = Byte(255*(cw-floor(cw)));
}
else {
b(x,h-y-1,0) = 0;
}
}
cw += xinc;
}
return b;
}
inline Graphics::Bitmap Triangle3(int w, int h) {
Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
float cw = 1;
float xinc = float(w)/h;
for(int y=0; y<h; y++) {
for(int x=0; x<b.GetWidth(); x++) {
if(x>w-floor(cw)) {
b(x,h-y-1,0) = 255;
}
else if(x>w-ceil(cw)) {
b(x,h-y-1,0) = Byte(255*(cw-floor(cw)));
}
else {
b(x,h-y-1,0) = 0;
}
}
cw += xinc;
}
return b;
}
inline Graphics::Bitmap Rectangle(int w, int h) {
Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
b(x, y, 0) = 255;
}
}
return b;
}
inline Graphics::Bitmap Pattern(int f) {
Graphics::Bitmap b({2, 2}, Graphics::ColorMode::Alpha);
b.Clear();
if(f>0)
b(0, 0, 0) = 255;
if(f>1)
b(1, 1, 0) = 255;
if(f>2)
b(1, 0, 0) = 255;
if(f>3)
b(0, 1, 0) = 255;
return b;
}
inline Graphics::Bitmap BGImage(int w, int h, Byte col1, Byte col2) {
Graphics::Bitmap bgimage({w*2, h*2}, Graphics::ColorMode::Grayscale);
for(int x = 0; x<w*2; x++) {
for(int y = 0; y<h*2; y++) {
if((x/w) != (y/h))
bgimage({x, y}, 0) = col1;
else
bgimage({x, y}, 0) = col2;
}
}
return bgimage;
}