UIHeader.hx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. package arm.ui;
  2. import kha.System;
  3. import zui.Zui;
  4. import zui.Id;
  5. import iron.system.Input;
  6. import arm.shader.MakeMaterial;
  7. #if (is_paint || is_sculpt)
  8. import iron.RenderPath;
  9. import arm.util.UVUtil;
  10. import arm.util.RenderUtil;
  11. import arm.io.ImportAsset;
  12. import arm.sys.Path;
  13. #end
  14. @:access(zui.Zui)
  15. class UIHeader {
  16. public static var inst: UIHeader;
  17. public static inline var defaultHeaderH = 28;
  18. public static var headerh = defaultHeaderH;
  19. public var headerHandle = new Handle({ layout: Horizontal });
  20. public var worktab = Id.handle();
  21. public function new() {
  22. inst = this;
  23. }
  24. public function renderUI(g: kha.graphics2.Graphics) {
  25. var ui = UIBase.inst.ui;
  26. if (Config.raw.touch_ui) {
  27. headerh = defaultHeaderH + 6;
  28. }
  29. else {
  30. headerh = defaultHeaderH;
  31. }
  32. headerh = Std.int(headerh * ui.SCALE());
  33. if (Config.raw.layout[LayoutHeader] == 0) return;
  34. var nodesw = (UINodes.inst.show || UIView2D.inst.show) ? Config.raw.layout[LayoutNodesW] : 0;
  35. #if is_lab
  36. var ww = System.windowWidth() - nodesw;
  37. #else
  38. var ww = System.windowWidth() - UIToolbar.inst.toolbarw - Config.raw.layout[LayoutSidebarW] - nodesw;
  39. #end
  40. if (ui.window(headerHandle, iron.App.x(), headerh, ww, headerh)) {
  41. ui._y += 2;
  42. drawToolProperties(ui);
  43. }
  44. }
  45. #if is_paint
  46. public function drawToolProperties(ui: Zui) {
  47. if (Context.raw.tool == ToolColorId) {
  48. ui.text(tr("Picked Color"));
  49. if (Context.raw.colorIdPicked) {
  50. ui.image(RenderPath.active.renderTargets.get("texpaint_colorid").image, 0xffffffff, 64);
  51. }
  52. ui.enabled = Context.raw.colorIdPicked;
  53. if (ui.button(tr("Clear"))) {
  54. Context.raw.colorIdPicked = false;
  55. UIToolbar.inst.toolbarHandle.redraws = 1;
  56. }
  57. ui.enabled = true;
  58. ui.text(tr("Color ID Map"));
  59. if (Project.assetNames.length > 0) {
  60. var cid = ui.combo(Context.raw.colorIdHandle, App.enumTexts("TEX_IMAGE"), tr("Color ID"));
  61. if (Context.raw.colorIdHandle.changed) {
  62. Context.raw.ddirty = 2;
  63. Context.raw.colorIdPicked = false;
  64. UIToolbar.inst.toolbarHandle.redraws = 1;
  65. }
  66. ui.image(Project.getImage(Project.assets[cid]));
  67. if (ui.isHovered) ui.tooltipImage(Project.getImage(Project.assets[cid]), 256);
  68. }
  69. if (ui.button(tr("Import"))) {
  70. UIFiles.show(Path.textureFormats.join(","), false, true, function(path: String) {
  71. ImportAsset.run(path, -1.0, -1.0, true, false);
  72. Context.raw.colorIdHandle.position = Project.assetNames.length - 1;
  73. for (a in Project.assets) {
  74. // Already imported
  75. if (a.file == path) Context.raw.colorIdHandle.position = Project.assets.indexOf(a);
  76. }
  77. Context.raw.ddirty = 2;
  78. Context.raw.colorIdPicked = false;
  79. UIToolbar.inst.toolbarHandle.redraws = 1;
  80. UIBase.inst.hwnds[2].redraws = 2;
  81. });
  82. }
  83. ui.enabled = Context.raw.colorIdPicked;
  84. if (ui.button(tr("To Mask"))) {
  85. if (Context.raw.layer.isMask()) Context.setLayer(Context.raw.layer.parent);
  86. var m = App.newMask(false, Context.raw.layer);
  87. function _next() {
  88. if (App.pipeMerge == null) App.makePipe();
  89. if (iron.data.ConstData.screenAlignedVB == null) iron.data.ConstData.createScreenAlignedData();
  90. m.texpaint.g4.begin();
  91. m.texpaint.g4.setPipeline(App.pipeColorIdToMask);
  92. m.texpaint.g4.setTexture(App.texpaintColorId, RenderPath.active.renderTargets.get("texpaint_colorid").image);
  93. m.texpaint.g4.setTexture(App.texColorId, Project.getImage(Project.assets[Context.raw.colorIdHandle.position]));
  94. m.texpaint.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB);
  95. m.texpaint.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB);
  96. m.texpaint.g4.drawIndexedVertices();
  97. m.texpaint.g4.end();
  98. Context.raw.colorIdPicked = false;
  99. UIToolbar.inst.toolbarHandle.redraws = 1;
  100. UIHeader.inst.headerHandle.redraws = 1;
  101. Context.raw.layerPreviewDirty = true;
  102. App.updateFillLayers();
  103. }
  104. App.notifyOnNextFrame(_next);
  105. History.newWhiteMask();
  106. }
  107. ui.enabled = true;
  108. }
  109. else if (Context.raw.tool == ToolPicker || Context.raw.tool == ToolMaterial) {
  110. var baseRPicked = Math.round(Context.raw.pickedColor.base.R * 10) / 10;
  111. var baseGPicked = Math.round(Context.raw.pickedColor.base.G * 10) / 10;
  112. var baseBPicked = Math.round(Context.raw.pickedColor.base.B * 10) / 10;
  113. var normalRPicked = Math.round(Context.raw.pickedColor.normal.R * 10) / 10;
  114. var normalGPicked = Math.round(Context.raw.pickedColor.normal.G * 10) / 10;
  115. var normalBPicked = Math.round(Context.raw.pickedColor.normal.B * 10) / 10;
  116. var occlusionPicked = Math.round(Context.raw.pickedColor.occlusion * 100) / 100;
  117. var roughnessPicked = Math.round(Context.raw.pickedColor.roughness * 100) / 100;
  118. var metallicPicked = Math.round(Context.raw.pickedColor.metallic * 100) / 100;
  119. var heightPicked = Math.round(Context.raw.pickedColor.height * 100) / 100;
  120. var opacityPicked = Math.round(Context.raw.pickedColor.opacity * 100) / 100;
  121. var h = Id.handle();
  122. h.color.R = baseRPicked;
  123. h.color.G = baseGPicked;
  124. h.color.B = baseBPicked;
  125. var state = ui.text("", 0, h.color);
  126. if (state == State.Started) {
  127. var mouse = Input.getMouse();
  128. var uix = ui._x;
  129. var uiy = ui._y;
  130. App.dragOffX = -(mouse.x - uix - ui._windowX - 3);
  131. App.dragOffY = -(mouse.y - uiy - ui._windowY + 1);
  132. App.dragSwatch = Project.cloneSwatch(Context.raw.pickedColor);
  133. }
  134. if (ui.isHovered) ui.tooltip(tr("Drag and drop picked color to swatches, materials, layers or to the node editor"));
  135. if (ui.isHovered && ui.inputReleased) {
  136. UIMenu.draw(function(ui) {
  137. ui.fill(0, 0, ui._w / ui.ops.scaleFactor, ui.t.ELEMENT_H * 9, ui.t.SEPARATOR_COL);
  138. ui.changed = false;
  139. zui.Ext.colorWheel(ui, h, false, null, 10 * ui.t.ELEMENT_H * ui.SCALE(), false);
  140. if (ui.changed) UIMenu.keepOpen = true;
  141. }, 10);
  142. }
  143. if (ui.button(tr("Add Swatch"))) {
  144. var newSwatch = Project.cloneSwatch(Context.raw.pickedColor);
  145. Context.setSwatch(newSwatch);
  146. Project.raw.swatches.push(newSwatch);
  147. UIBase.inst.hwnds[2].redraws = 1;
  148. }
  149. if (ui.isHovered) ui.tooltip(tr("Add picked color to swatches"));
  150. ui.text(tr("Base") + ' ($baseRPicked,$baseGPicked,$baseBPicked)');
  151. ui.text(tr("Normal") + ' ($normalRPicked,$normalGPicked,$normalBPicked)');
  152. ui.text(tr("Occlusion") + ' ($occlusionPicked)');
  153. ui.text(tr("Roughness") + ' ($roughnessPicked)');
  154. ui.text(tr("Metallic") + ' ($metallicPicked)');
  155. ui.text(tr("Height") + ' ($heightPicked)');
  156. ui.text(tr("Opacity") + ' ($opacityPicked)');
  157. Context.raw.pickerSelectMaterial = ui.check(Id.handle({ selected: Context.raw.pickerSelectMaterial }), tr("Select Material"));
  158. ui.combo(Context.raw.pickerMaskHandle, [tr("None"), tr("Material")], tr("Mask"), true);
  159. if (Context.raw.pickerMaskHandle.changed) {
  160. MakeMaterial.parsePaintMaterial();
  161. }
  162. }
  163. else if (Context.raw.tool == ToolBake) {
  164. ui.changed = false;
  165. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  166. var baking = Context.raw.pdirty > 0;
  167. var rtBake = Context.raw.bakeType == BakeAO || Context.raw.bakeType == BakeLightmap || Context.raw.bakeType == BakeBentNormal || Context.raw.bakeType == BakeThickness;
  168. if (baking && ui.button(tr("Stop"))) {
  169. Context.raw.pdirty = 0;
  170. Context.raw.rdirty = 2;
  171. }
  172. #else
  173. var baking = false;
  174. var rtBake = false;
  175. #end
  176. if (!baking && ui.button(tr("Bake"))) {
  177. Context.raw.pdirty = rtBake ? Context.raw.bakeSamples : 1;
  178. Context.raw.rdirty = 3;
  179. App.notifyOnNextFrame(function() {
  180. Context.raw.layerPreviewDirty = true;
  181. });
  182. UIBase.inst.hwnds[0].redraws = 2;
  183. History.pushUndo = true;
  184. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  185. arm.render.RenderPathRaytraceBake.currentSample = 0;
  186. #end
  187. }
  188. var bakeHandle = Id.handle({ position: Context.raw.bakeType });
  189. var bakes = [
  190. tr("AO"),
  191. tr("Curvature"),
  192. tr("Normal"),
  193. tr("Object Normal"),
  194. tr("Height"),
  195. tr("Derivative"),
  196. tr("Position"),
  197. tr("TexCoord"),
  198. tr("Material ID"),
  199. tr("Object ID"),
  200. tr("Vertex Color"),
  201. ];
  202. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  203. if (Krom.raytraceSupported()) {
  204. bakes.push(tr("Lightmap"));
  205. bakes.push(tr("Bent Normal"));
  206. bakes.push(tr("Thickness"));
  207. }
  208. else {
  209. bakes.shift(); // Remove AO
  210. }
  211. #end
  212. Context.raw.bakeType = ui.combo(bakeHandle, bakes, tr("Bake"));
  213. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  214. if (!Krom.raytraceSupported()) {
  215. Context.raw.bakeType += 1; // Offset for removed AO
  216. }
  217. #end
  218. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  219. if (rtBake) {
  220. var samplesHandle = Id.handle({ value: Context.raw.bakeSamples });
  221. Context.raw.bakeSamples = Std.int(ui.slider(samplesHandle, tr("Samples"), 1, 512, true, 1));
  222. }
  223. #end
  224. if (Context.raw.bakeType == BakeNormalObject || Context.raw.bakeType == BakePosition || Context.raw.bakeType == BakeBentNormal) {
  225. var bakeUpAxisHandle = Id.handle({ position: Context.raw.bakeUpAxis });
  226. Context.raw.bakeUpAxis = ui.combo(bakeUpAxisHandle, [tr("Z"), tr("Y")], tr("Up Axis"), true);
  227. }
  228. if (Context.raw.bakeType == BakeAO || Context.raw.bakeType == BakeCurvature) {
  229. var bakeAxisHandle = Id.handle({ position: Context.raw.bakeAxis });
  230. Context.raw.bakeAxis = ui.combo(bakeAxisHandle, [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")], tr("Axis"), true);
  231. }
  232. if (Context.raw.bakeType == BakeAO) {
  233. var strengthHandle = Id.handle({ value: Context.raw.bakeAoStrength });
  234. Context.raw.bakeAoStrength = ui.slider(strengthHandle, tr("Strength"), 0.0, 2.0, true);
  235. var radiusHandle = Id.handle({ value: Context.raw.bakeAoRadius });
  236. Context.raw.bakeAoRadius = ui.slider(radiusHandle, tr("Radius"), 0.0, 2.0, true);
  237. var offsetHandle = Id.handle({ value: Context.raw.bakeAoOffset });
  238. Context.raw.bakeAoOffset = ui.slider(offsetHandle, tr("Offset"), 0.0, 2.0, true);
  239. }
  240. #if (kha_direct3d12 || kha_vulkan || kha_metal)
  241. if (rtBake) {
  242. var progress = arm.render.RenderPathRaytraceBake.currentSample / Context.raw.bakeSamples;
  243. if (progress > 1.0) progress = 1.0;
  244. // Progress bar
  245. ui.g.color = ui.t.SEPARATOR_COL;
  246. ui.drawRect(ui.g, true, ui._x + 1, ui._y, ui._w - 2, ui.ELEMENT_H());
  247. ui.g.color = ui.t.HIGHLIGHT_COL;
  248. ui.drawRect(ui.g, true, ui._x + 1, ui._y, (ui._w - 2) * progress, ui.ELEMENT_H());
  249. ui.g.color = 0xffffffff;
  250. ui.text(tr("Samples") + ": " + arm.render.RenderPathRaytraceBake.currentSample);
  251. ui.text(tr("Rays/pixel" + ": ") + arm.render.RenderPathRaytraceBake.raysPix);
  252. ui.text(tr("Rays/second" + ": ") + arm.render.RenderPathRaytraceBake.raysSec);
  253. }
  254. #end
  255. if (Context.raw.bakeType == BakeCurvature) {
  256. var strengthHandle = Id.handle({ value: Context.raw.bakeCurvStrength });
  257. Context.raw.bakeCurvStrength = ui.slider(strengthHandle, tr("Strength"), 0.0, 2.0, true);
  258. var radiusHandle = Id.handle({ value: Context.raw.bakeCurvRadius });
  259. Context.raw.bakeCurvRadius = ui.slider(radiusHandle, tr("Radius"), 0.0, 2.0, true);
  260. var offsetHandle = Id.handle({ value: Context.raw.bakeCurvOffset });
  261. Context.raw.bakeCurvOffset = ui.slider(offsetHandle, tr("Offset"), -2.0, 2.0, true);
  262. var smoothHandle = Id.handle({ value: Context.raw.bakeCurvSmooth });
  263. Context.raw.bakeCurvSmooth = Std.int(ui.slider(smoothHandle, tr("Smooth"), 0, 5, false, 1));
  264. }
  265. if (Context.raw.bakeType == BakeNormal || Context.raw.bakeType == BakeHeight || Context.raw.bakeType == BakeDerivative) {
  266. var ar = [for (p in Project.paintObjects) p.name];
  267. var polyHandle = Id.handle({ position: Context.raw.bakeHighPoly });
  268. Context.raw.bakeHighPoly = ui.combo(polyHandle, ar, tr("High Poly"));
  269. }
  270. if (ui.changed) {
  271. MakeMaterial.parsePaintMaterial();
  272. }
  273. }
  274. else if (Context.raw.tool == ToolBrush ||
  275. Context.raw.tool == ToolEraser ||
  276. Context.raw.tool == ToolFill ||
  277. Context.raw.tool == ToolDecal ||
  278. Context.raw.tool == ToolText ||
  279. Context.raw.tool == ToolClone ||
  280. Context.raw.tool == ToolBlur ||
  281. Context.raw.tool == ToolSmudge ||
  282. Context.raw.tool == ToolParticle) {
  283. var decal = Context.raw.tool == ToolDecal || Context.raw.tool == ToolText;
  284. var decalMask = decal && Operator.shortcut(Config.keymap.decal_mask, ShortcutDown);
  285. if (Context.raw.tool != ToolFill) {
  286. if (decalMask) {
  287. Context.raw.brushDecalMaskRadius = ui.slider(Context.raw.brushDecalMaskRadiusHandle, tr("Radius"), 0.01, 2.0, true);
  288. if (ui.isHovered) ui.tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", ["brush_radius" => Config.keymap.brush_radius, "brush_radius_decrease" => Config.keymap.brush_radius_decrease, "brush_radius_increase" => Config.keymap.brush_radius_increase]));
  289. }
  290. else {
  291. Context.raw.brushRadius = ui.slider(Context.raw.brushRadiusHandle, tr("Radius"), 0.01, 2.0, true);
  292. if (ui.isHovered) ui.tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", ["brush_radius" => Config.keymap.brush_radius, "brush_radius_decrease" => Config.keymap.brush_radius_decrease, "brush_radius_increase" => Config.keymap.brush_radius_increase]));
  293. }
  294. }
  295. if (Context.raw.tool == ToolDecal || Context.raw.tool == ToolText) {
  296. Context.raw.brushScaleX = ui.slider(Context.raw.brushScaleXHandle, tr("Scale X"), 0.01, 2.0, true);
  297. }
  298. if (Context.raw.tool == ToolBrush ||
  299. Context.raw.tool == ToolFill ||
  300. Context.raw.tool == ToolDecal ||
  301. Context.raw.tool == ToolText) {
  302. var brushScaleHandle = Id.handle({ value: Context.raw.brushScale });
  303. Context.raw.brushScale = ui.slider(brushScaleHandle, tr("UV Scale"), 0.01, 5.0, true);
  304. if (brushScaleHandle.changed) {
  305. if (Context.raw.tool == ToolDecal || Context.raw.tool == ToolText) {
  306. ui.g.end();
  307. RenderUtil.makeDecalPreview();
  308. ui.g.begin(false);
  309. }
  310. }
  311. Context.raw.brushAngle = ui.slider(Context.raw.brushAngleHandle, tr("Angle"), 0.0, 360.0, true, 1);
  312. if (ui.isHovered) ui.tooltip(tr("Hold {brush_angle} and move mouse to the left to decrease the angle\nHold {brush_angle} and move mouse to the right to increase the angle", ["brush_angle" => Config.keymap.brush_angle]));
  313. if (Context.raw.brushAngleHandle.changed) {
  314. MakeMaterial.parsePaintMaterial();
  315. }
  316. }
  317. Context.raw.brushOpacity = ui.slider(Context.raw.brushOpacityHandle, tr("Opacity"), 0.0, 1.0, true);
  318. if (ui.isHovered) ui.tooltip(tr("Hold {brush_opacity} and move mouse to the left to decrease the opacity\nHold {brush_opacity} and move mouse to the right to increase the opacity", ["brush_opacity" => Config.keymap.brush_opacity]));
  319. if (Context.raw.tool == ToolBrush || Context.raw.tool == ToolEraser || Context.raw.tool == ToolClone || decalMask) {
  320. Context.raw.brushHardness = ui.slider(Id.handle({ value: Context.raw.brushHardness }), tr("Hardness"), 0.0, 1.0, true);
  321. }
  322. if (Context.raw.tool != ToolEraser) {
  323. var brushBlendingHandle = Id.handle({ value: Context.raw.brushBlending });
  324. Context.raw.brushBlending = ui.combo(brushBlendingHandle, [
  325. tr("Mix"),
  326. tr("Darken"),
  327. tr("Multiply"),
  328. tr("Burn"),
  329. tr("Lighten"),
  330. tr("Screen"),
  331. tr("Dodge"),
  332. tr("Add"),
  333. tr("Overlay"),
  334. tr("Soft Light"),
  335. tr("Linear Light"),
  336. tr("Difference"),
  337. tr("Subtract"),
  338. tr("Divide"),
  339. tr("Hue"),
  340. tr("Saturation"),
  341. tr("Color"),
  342. tr("Value"),
  343. ], tr("Blending"));
  344. if (brushBlendingHandle.changed) {
  345. MakeMaterial.parsePaintMaterial();
  346. }
  347. }
  348. if (Context.raw.tool == ToolBrush || Context.raw.tool == ToolFill) {
  349. var paintHandle = Id.handle();
  350. Context.raw.brushPaint = ui.combo(paintHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord"));
  351. if (paintHandle.changed) {
  352. MakeMaterial.parsePaintMaterial();
  353. }
  354. }
  355. if (Context.raw.tool == ToolText) {
  356. var h = Id.handle();
  357. h.text = Context.raw.textToolText;
  358. var w = ui._w;
  359. if (ui.textSelectedHandle == h || ui.submitTextHandle == h) {
  360. ui._w *= 3;
  361. }
  362. Context.raw.textToolText = ui.textInput(h, "", Left, true, true);
  363. ui._w = w;
  364. if (h.changed) {
  365. ui.g.end();
  366. RenderUtil.makeTextPreview();
  367. RenderUtil.makeDecalPreview();
  368. ui.g.begin(false);
  369. }
  370. }
  371. if (Context.raw.tool == ToolFill) {
  372. ui.combo(Context.raw.fillTypeHandle, [tr("Object"), tr("Face"), tr("Angle"), tr("UV Island")], tr("Fill Mode"));
  373. if (Context.raw.fillTypeHandle.changed) {
  374. if (Context.raw.fillTypeHandle.position == FillFace) {
  375. ui.g.end();
  376. // UVUtil.cacheUVMap();
  377. UVUtil.cacheTriangleMap();
  378. ui.g.begin(false);
  379. // wireframeHandle.selected = drawWireframe = true;
  380. }
  381. MakeMaterial.parsePaintMaterial();
  382. MakeMaterial.parseMeshMaterial();
  383. }
  384. }
  385. else {
  386. var _w = ui._w;
  387. var sc = ui.SCALE();
  388. var touchHeader = (Config.raw.touch_ui && Config.raw.layout[LayoutHeader] == 1);
  389. if (touchHeader) ui._x -= 4 * sc;
  390. ui._w = Std.int((touchHeader ? 54 : 60) * sc);
  391. var xrayHandle = Id.handle({ selected: Context.raw.xray });
  392. Context.raw.xray = ui.check(xrayHandle, tr("X-Ray"));
  393. if (xrayHandle.changed) {
  394. MakeMaterial.parsePaintMaterial();
  395. }
  396. var symXHandle = Id.handle({ selected: false });
  397. var symYHandle = Id.handle({ selected: false });
  398. var symZHandle = Id.handle({ selected: false });
  399. if (Config.raw.layout[LayoutHeader] == 1) {
  400. if (Config.raw.touch_ui) {
  401. ui._w = Std.int(19 * sc);
  402. Context.raw.symX = ui.check(symXHandle, "");
  403. ui._x -= 4 * sc;
  404. Context.raw.symY = ui.check(symYHandle, "");
  405. ui._x -= 4 * sc;
  406. Context.raw.symZ = ui.check(symZHandle, "");
  407. ui._x -= 4 * sc;
  408. ui._w = Std.int(40 * sc);
  409. ui.text(tr("X") + tr("Y") + tr("Z"));
  410. }
  411. else {
  412. ui._w = Std.int(56 * sc);
  413. ui.text(tr("Symmetry"));
  414. ui._w = Std.int(25 * sc);
  415. Context.raw.symX = ui.check(symXHandle, tr("X"));
  416. Context.raw.symY = ui.check(symYHandle, tr("Y"));
  417. Context.raw.symZ = ui.check(symZHandle, tr("Z"));
  418. }
  419. ui._w = _w;
  420. }
  421. else {
  422. // Popup
  423. ui._w = _w;
  424. Context.raw.symX = ui.check(symXHandle, tr("Symmetry") + " " + tr("X"));
  425. Context.raw.symY = ui.check(symYHandle, tr("Symmetry") + " " + tr("Y"));
  426. Context.raw.symZ = ui.check(symZHandle, tr("Symmetry") + " " + tr("Z"));
  427. }
  428. if (symXHandle.changed || symYHandle.changed || symZHandle.changed) {
  429. MakeMaterial.parsePaintMaterial();
  430. }
  431. }
  432. #if arm_physics
  433. if (Context.raw.tool == ToolParticle) {
  434. ui._x += 10 * ui.SCALE();
  435. var physHandle = Id.handle({ selected: false });
  436. Context.raw.particlePhysics = ui.check(physHandle, tr("Physics"));
  437. if (physHandle.changed) {
  438. arm.util.ParticleUtil.initParticlePhysics();
  439. MakeMaterial.parsePaintMaterial();
  440. }
  441. }
  442. #end
  443. }
  444. }
  445. #end
  446. #if is_sculpt
  447. public function drawToolProperties(ui: Zui) {}
  448. #end
  449. #if is_lab
  450. public function drawToolProperties(ui: Zui) {
  451. if (Context.raw.tool == ToolPicker) {
  452. }
  453. else if (Context.raw.tool == ToolEraser ||
  454. Context.raw.tool == ToolClone ||
  455. Context.raw.tool == ToolBlur ||
  456. Context.raw.tool == ToolSmudge) {
  457. var inpaint = UINodes.inst.getNodes().nodesSelected.length > 0 && UINodes.inst.getNodes().nodesSelected[0].type == "InpaintNode";
  458. if (inpaint) {
  459. Context.raw.brushRadius = ui.slider(Context.raw.brushRadiusHandle, tr("Radius"), 0.01, 2.0, true);
  460. if (ui.isHovered) ui.tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", ["brush_radius" => Config.keymap.brush_radius, "brush_radius_decrease" => Config.keymap.brush_radius_decrease, "brush_radius_increase" => Config.keymap.brush_radius_increase]));
  461. }
  462. }
  463. }
  464. #end
  465. }