1 /*
2     Copyright © 2022, Inochi2D Project
3     Distributed under the 2-Clause BSD License, see LICENSE file.
4     
5     Authors: Luna Nielsen
6 */
7 module creator.windows.imgexport;
8 import creator.windows;
9 import creator.widgets;
10 import creator.core;
11 import creator.core.i18n;
12 import creator;
13 import std.string;
14 import creator.utils.link;
15 import creator.ext;
16 import creator.io;
17 import i18n;
18 import inmath;
19 import inochi2d;
20 
21 /**
22     Settings window
23 */
24 class ImageExportWindow : Window {
25 private:
26     string outFile;
27     ExCamera selectedCamera;
28     ExCamera[] cameras;
29     bool transparency;
30     bool postprocessing;
31 
32     void export_() {
33         Camera cam = selectedCamera.getCamera();
34         vec2 vp = selectedCamera.getViewport();
35 
36         Camera oc;
37         float or, og, ob, oa;
38         int ow, oh;
39         inGetViewport(ow, oh);
40         oc = inGetCamera();
41 
42         // Set state for dumping viewport
43         inSetCamera(cam);
44         inSetViewport(cast(int)vp.x, cast(int)vp.y);
45         if (transparency) {
46             inGetClearColor(or, og, ob, oa);
47             inSetClearColor(0, 0, 0, 0);
48         }
49 
50         // Render viewport
51         inBeginScene();
52             incActivePuppet().draw();
53         inEndScene();
54         if (postprocessing) inPostProcessScene();
55 
56         // Dump to file
57         ubyte[] data = new ubyte[inViewportDataLength()];
58         inDumpViewport(data);
59         incExportImage(outFile, data, cast(int)vp.x, cast(int)vp.y);
60 
61         // Reset state
62         if (transparency) inSetClearColor(or, og, ob, oa);
63         inSetViewport(ow, oh);
64         inSetCamera(oc);
65     }
66 
67 protected:
68     override
69     void onBeginUpdate() {
70         flags |= ImGuiWindowFlags.NoSavedSettings;
71         
72         ImVec2 wpos = ImVec2(
73             igGetMainViewport().Pos.x+(igGetMainViewport().Size.x/2),
74             igGetMainViewport().Pos.y+(igGetMainViewport().Size.y/2),
75         );
76 
77         ImVec2 uiSize = ImVec2(
78             512, 
79             256
80         );
81 
82         igSetNextWindowPos(wpos, ImGuiCond.Appearing, ImVec2(0.5, 0.5));
83         igSetNextWindowSize(uiSize, ImGuiCond.Appearing);
84         igSetNextWindowSizeConstraints(uiSize, ImVec2(float.max, float.max));
85         super.onBeginUpdate();
86     }
87 
88     override
89     void onUpdate() {
90 
91         // Contents
92         if (igBeginChild("ExportContent", ImVec2(0, -28), true)) {
93             incText(_("Export Settings"));
94 
95             igSpacing();
96 
97             if (incBeginCategory(__("Camera"))) {
98                 if (igBeginCombo("###CAMERA", selectedCamera.name.toStringz)) {
99 
100                     foreach(ref camera; cameras) {
101                         if (igMenuItem(camera.cName)) {
102                             selectedCamera = camera;
103                         }
104                     }
105 
106                     igEndCombo();
107                 }
108 
109                 igSpacing();
110                 igCheckbox(__("Allow Transparency"), &transparency);
111                 igCheckbox(__("Use Post Processing"), &postprocessing);
112             }
113             incEndCategory();
114         }
115         igEndChild();
116 
117         // Bottom buttons
118         if (igBeginChild("ExportButtons", ImVec2(0, 0), false, ImGuiWindowFlags.NoScrollbar)) {
119             incDummy(ImVec2(-64, 0));
120             igSameLine(0, 0);
121 
122             if (igButton(__("Save"), ImVec2(64, 24))) {
123                 this.export_();
124                 this.close();
125             }
126         }
127         igEndChild();
128     }
129 
130 public:
131     this(string outFile) {
132         super(_("Export Image..."));
133 
134         this.outFile = outFile;
135 
136         // Search for cameras
137         cameras = incActivePuppet().findNodesType!ExCamera(incActivePuppet().root);
138         if (cameras.length == 0) {
139             incDialog("Error", "No cameras to export from in Scene, please add a Camera.");
140             this.close();
141             return;
142         }
143 
144         selectedCamera = cameras[0];
145     }
146 }