1 /**
2 Copyright: Copyright (c) 2014 Andrey Penechko.
3 License: a$(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module anchovy.gui.application.application;
8 
9 import std.stdio : writeln;
10 import anchovy.core.interfaces.iwindow;
11 import anchovy.gui;
12 
13 public import anchovy.gui.application.eventaggregator;
14 public import anchovy.gui.application.fpshelper;
15 
16 class Application(WindowType)
17 {
18 	IWindow window;
19 	EventAggregator!WindowType aggregator;
20 	FpsHelper fpsHelper;
21 	TimerManager timerManager;
22 	bool isRunning = true;
23 	Color clearColor = Color(50, 10, 45);
24 
25 	IRenderer renderer;
26 	IGuiRenderer guiRenderer;
27 
28 	GuiContext context;
29 	TemplateManager templateManager;
30 
31 	this()
32 	{
33 		window = new WindowType();
34 
35 		aggregator = new EventAggregator!WindowType(this, window);
36 	}
37 
38 	void run(in string[] args, uvec2 windowSize, string caption)
39 	{
40 		init(args, windowSize, caption);
41 		load(args);
42 
43 		double lastTime = window.elapsedTime;
44 		double newTime;
45 
46 		while(isRunning)
47 		{
48 			window.processEvents();
49 
50 			newTime = window.elapsedTime;
51 
52 			update(newTime - lastTime);
53 
54 			lastTime = newTime;
55 
56 			draw();
57 
58 			fpsHelper.sleepAfterFrame(lastTime - window.elapsedTime);
59 		}
60 
61 		unload();
62 
63 		window.releaseWindow;
64 	}
65 
66 	string[] getHardwareInfo()
67 	{
68 		import core.cpuid;
69 		import anchovy.utils.string : ZToString;
70 
71 		return [
72 			"CPU vendor: " ~ vendor,
73 			"CPU name: " ~ processor,
74 			"Cores: " ~ to!string(coresPerCPU),
75 			"Threads: " ~ to!string(threadsPerCPU),
76 			"CPU chache levels: " ~ to!string(cacheLevels),
77 			"GPU vendor: " ~ ZToString(glGetString(GL_VENDOR)),
78 			"Renderer: " ~ ZToString(glGetString(GL_RENDERER)),
79 			"OpenGL version: " ~ ZToString(glGetString(GL_VERSION)),
80 			"GLSL version: " ~ ZToString(glGetString(GL_SHADING_LANGUAGE_VERSION)),
81 		];
82 	}
83 
84 	void init(in string[] args, uvec2 windowSize, string caption)
85 	{
86 		initLibs();
87 		window.init(windowSize, caption);
88 
89 		dstring cyrillicChars = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяє"d;
90 
91 		// ----------------------------- Setting renderer -----------------------------
92 		renderer = new Ogl3Renderer(window);
93 		renderer.setClearColor(clearColor);
94 
95 		// ----------------------------- Skin loading ---------------------------------
96 		string graySkinSource = cast(string)read("skingray.json");
97 		auto skinParser = new JsonGuiSkinParser;
98 		auto graySkin = skinParser.parse(graySkinSource);
99 
100 		// ----------------------------- Gui renderer ---------------------------------
101 		guiRenderer = new SkinnedGuiRenderer(renderer, graySkin);
102 		guiRenderer.fontManager.charCache ~= cyrillicChars;
103 		graySkin.loadResources(guiRenderer);
104 
105 		timerManager = new TimerManager(delegate double(){return window.elapsedTime;});
106 
107 		// ----------------------------- Template classes -----------------------------
108 		auto templateParser = new TemplateParser;
109 		templateManager = new TemplateManager(templateParser);
110 
111 		// ----------------------------- Setting context ------------------------------
112 		context = new GuiContext(guiRenderer, timerManager, templateManager, graySkin);
113 		context.setClipboardStringCallback = (dstring newStr) => window.clipboardString = to!string(newStr);
114 		context.getClipboardStringCallback = delegate dstring(){return to!dstring(window.clipboardString);};
115 		context.attachDefaultBehaviors();
116 		context.attachDefaultLayouts();
117 
118 		// ----------------------------- Rendering settings ---------------------------
119 		renderer.enableAlphaBlending();
120 		glEnable(GL_SCISSOR_TEST);
121 	}
122 
123 	void initLibs()
124 	{
125 		import derelict.freetype.ft;
126 		import derelict.freeimage.freeimage;
127 		import derelict.glfw3.glfw3;
128 		import derelict.opengl3.gl3;
129 
130 		DerelictFI.load(SharedLibVersion(3, 15, 0));
131 		DerelictFT.load();
132 		DerelictGL3.load();
133 		DerelictGLFW3.load();
134 	}
135 
136 	void load(in string[] args)
137 	{
138 
139 	}
140 
141 	void unload()
142 	{
143 		renderer.close();
144 	}
145 
146 	void update(double dt)
147 	{
148 		fpsHelper.update(dt);
149 		timerManager.updateTimers(window.elapsedTime);
150 		context.update(dt);
151 	}
152 
153 	void draw()
154 	{
155 		guiRenderer.setClientArea(Rect(0, 0, window.size.x, window.size.y));
156 		glClear(GL_COLOR_BUFFER_BIT);
157 
158 		context.eventDispatcher.draw();
159 
160 		window.swapBuffers();
161 	}
162 
163 	void closePressed()
164 	{
165 	}
166 
167 	void printTree()
168 	{
169 		void printWidget(Widget widget, string spacing)
170 		{
171 			auto children = widget["children"].get!(Widget[]);
172 			writefln("-%s %s", widget["type"], widget["name"]);
173 
174 			if (children.length > 0)
175 			{
176 				foreach(child; children[0..$-1])
177 				{
178 					writef("%s ├", spacing);
179 					printWidget(child, spacing~" |");
180 				}
181 				writef("%s └", spacing);
182 				printWidget(children[$-1], spacing~"  ");
183 			}
184 		}
185 
186 		foreach(root; context.roots)
187 		{
188 			printWidget(root, "");
189 		}
190 		writeln;
191 	}
192 }