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 		window.init(windowSize, caption);
87 
88 		dstring cyrillicChars = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяє"d;
89 
90 		// ----------------------------- Setting renderer -----------------------------
91 		renderer = new Ogl3Renderer(window);
92 		renderer.setClearColor(clearColor);
93 
94 		// ----------------------------- Skin loading ---------------------------------
95 		string graySkinSource = cast(string)read("skingray.json");
96 		auto skinParser = new JsonGuiSkinParser;
97 		auto graySkin = skinParser.parse(graySkinSource);
98 
99 		// ----------------------------- Gui renderer ---------------------------------
100 		guiRenderer = new SkinnedGuiRenderer(renderer, graySkin);
101 		guiRenderer.fontManager.charCache ~= cyrillicChars;
102 		graySkin.loadResources(guiRenderer);
103 
104 		timerManager = new TimerManager(delegate double(){return window.elapsedTime;});
105 
106 		// ----------------------------- Template classes -----------------------------
107 		auto templateParser = new TemplateParser;
108 		templateManager = new TemplateManager(templateParser);
109 
110 		// ----------------------------- Setting context ------------------------------
111 		context = new GuiContext(guiRenderer, timerManager, templateManager, graySkin);
112 		context.setClipboardStringCallback = (dstring newStr) => window.clipboardString = to!string(newStr);
113 		context.getClipboardStringCallback = delegate dstring(){return to!dstring(window.clipboardString);};
114 		context.attachDefaultBehaviors();
115 		context.attachDefaultLayouts();
116 
117 		// ----------------------------- Rendering settings ---------------------------
118 		renderer.enableAlphaBlending();
119 		glEnable(GL_SCISSOR_TEST);
120 	}
121 
122 	void initLibs()
123 	{
124 		import derelict.freetype.ft;
125 		import derelict.freeimage.freeimage;
126 		import derelict.glfw3.glfw3;
127 		import derelict.opengl3.gl3;
128 
129 		DerelictFI.load(SharedLibVersion(3, 15, 0));
130 		DerelictFT.load();
131 		DerelictGL3.load();
132 		DerelictGLFW3.load();
133 	}
134 
135 	void load(in string[] args)
136 	{
137 
138 	}
139 
140 	void unload()
141 	{
142 		renderer.close();
143 	}
144 
145 	void update(double dt)
146 	{
147 		fpsHelper.update(dt);
148 		timerManager.updateTimers(window.elapsedTime);
149 		context.update(dt);
150 	}
151 
152 	void draw()
153 	{
154 		guiRenderer.setClientArea(Rect(0, 0, window.size.x, window.size.y));
155 		glClear(GL_COLOR_BUFFER_BIT);
156 
157 		context.eventDispatcher.draw();
158 
159 		window.swapBuffers();
160 	}
161 
162 	void closePressed()
163 	{
164 	}
165 
166 	void printTree()
167 	{
168 		void printWidget(Widget widget, string spacing)
169 		{
170 			auto children = widget["children"].get!(Widget[]);
171 			writefln("-%s %s", widget["type"], widget["name"]);
172 
173 			if (children.length > 0)
174 			{
175 				foreach(child; children[0..$-1])
176 				{
177 					writef("%s ├", spacing);
178 					printWidget(child, spacing~" |");
179 				}
180 				writef("%s └", spacing);
181 				printWidget(children[$-1], spacing~"  ");
182 			}
183 		}
184 
185 		foreach(root; context.roots)
186 		{
187 			printWidget(root, "");
188 		}
189 		writeln;
190 	}
191 }