5class SCR_GenerateLayoutClassPlugin : WorkbenchPlugin
7 protected static const string PLUGIN_VERSION =
"0.5.1";
8 protected static const string PLUGIN_NAME =
"Generate Class from Layout";
9 protected static const string DIALOG_CAPTION = PLUGIN_NAME +
" [v" + PLUGIN_VERSION +
"]";
10 protected static const string INTRO_TEXT =
"This plugin autogenerates widget-binding scripts for .layout files.\n\n";
17 BaseContainer widgetSource = Workbench.GetModule(ResourceManager).GetContainer();
20 Workbench.Dialog(DIALOG_CAPTION, INTRO_TEXT +
"You need to open a .layout file first!");
24 BaseContainer exportRule = SCR_WidgetExportRuleRoot.FindInWidgetSource(widgetSource);
27 Workbench.Dialog(DIALOG_CAPTION, INTRO_TEXT +
"You need to attach a SCR_WidgetExportRuleRoot component to root widget of your layout!");
31 string layoutPath = widgetSource.GetName();
32 string scriptClassName = GenerateScriptClassName(layoutPath, exportRule);
33 string destinationPath = ResolveDestinationPath(scriptClassName +
".c");
34 string dialogText = INTRO_TEXT +
35 "The generator only exports widgets and their components if the widget name starts with 'm_'.\n" +
36 "Attach SCR_WidgetExportRule component to a widget to alter its export rules.\n\n" +
37 "- - - - - - - - - - - - - - - - - - - - \n\n" +
38 string.Format(
"Generated script class name:\n%1\n\n", scriptClassName) +
39 string.Format(
"Destination file path:\n%1\n\n", destinationPath) +
40 string.Format(
"WARNING: The destination file will be overwritten if it already exists! (file exists: %1)",
FileIO.FileExists(destinationPath).ToString());
42 if (!Workbench.ScriptDialog(DIALOG_CAPTION, dialogText,
this))
45 Generate(widgetSource, exportRule, scriptClassName, destinationPath);
57 array<BaseContainer> widgets = {};
58 array<ref array<BaseContainer>> paths = {};
59 BuildWidgetArray(widgetSource, {}, widgets, paths);
62 string layoutPath = widgetSource.GetName();
63 _print(
string.Format(
"Layout path: %1", layoutPath));
64 _print(
string.Format(
"Script class name: %1", scriptClassName));
67 string variablesDeclaration;
68 string variablesBinding;
71 _print(
"Iterating widgets...");
72 bool generateFullWidgetPath = SCR_WidgetExportRuleRoot.GetGenerateFullWidgetPath(exportRule);
73 array<BaseContainer> pathToThisWidget;
74 array<BaseContainer> components;
77 pathToThisWidget = paths[widgetId];
79 string wName = GetWidgetName(thisWidget);
82 if (!IsWidgetExportRequired(thisWidget, pathToThisWidget))
85 if (!ValidateWidget(thisWidget))
88 components = ResolveWidgetComponentsForExport(thisWidget);
89 int componentsCount = components.Count();
91 if (componentsCount > 0 && !variablesDeclaration.IsEmpty())
93 variablesDeclaration +=
"\n";
94 variablesBinding +=
"\n";
97 string widgetVariableName = ResolveWidgetVariableName(thisWidget);
98 if (!widgetVariableName.StartsWith(
"m_w"))
100 if (widgetVariableName.StartsWith(
"m_"))
103 widgetVariableName =
"m_w" + widgetVariableName;
106 string pathToThisWidgetStr = GetStringPathToWidget(pathToThisWidget);
108 _print(
string.Format(
"Exporting widget: %1, %2, %3", wName, widgetVariableName, pathToThisWidgetStr));
111 string wClassName = thisWidget.GetClassName();
112 wClassName = wClassName.Substring(0, wClassName.Length() - 5);
113 variablesDeclaration +=
string.Format(
"\t%1 %2;\n", wClassName, widgetVariableName);
116 if (generateFullWidgetPath)
117 variablesBinding +=
string.Format(
"\t\t%1 = %2.Cast(root.FindWidget(\"%3\"));\n", widgetVariableName, wClassName, pathToThisWidgetStr);
119 variablesBinding +=
string.Format(
"\t\t%1 = %2.Cast(root.FindAnyWidget(\"%3\"));\n", widgetVariableName, wClassName, GetWidgetName(thisWidget));
121 if (componentsCount < 1)
129 string compClassName = comp.GetClassName();
132 if (componentsCount == 1)
133 compVarName =
string.Format(
"%1Component", noMWPrefixWidgetVariableName);
135 compVarName =
string.Format(
"%1Component%2", noMWPrefixWidgetVariableName, i);
137 variablesDeclaration +=
string.Format(
"\t%1 %2;\n", compClassName, compVarName);
140 variablesBinding +=
string.Format(
"\t\t%1 = %2.Cast(%3.FindHandler(%4));\n", compVarName, compClassName, widgetVariableName, compClassName);
143 variablesDeclaration +=
"\n";
144 variablesBinding +=
"\n";
149 string.Format(
"/" +
"/ Autogenerated by the Generate Class from Layout plugin v%1\n", PLUGIN_VERSION) +
150 string.Format(
"/" +
"/ Layout file: %1\n", layoutPath) +
151 string.Format(
"class %1\n{\n", scriptClassName) +
152 string.Format(
"\tprotected static const ResourceName LAYOUT = \"%1\";\n\n", widgetSource.GetResourceName()) +
153 variablesDeclaration +
"\n" +
154 "\t//------------------------------------------------------------------------------------------------\n" +
155 "\tbool Init(notnull Widget root)\n\t{\n" +
156 variablesBinding +
"\n" +
157 "\t\treturn true;\n\t}\n\n" +
158 "\t//------------------------------------------------------------------------------------------------\n" +
159 "\tResourceName GetLayout()\n\t{\n\t\t" +
"return LAYOUT;\n\t}\n" +
163 string fileOutPath = destinationPath;
165 _print(
string.Format(
"Exporting to file: %1", fileOutPath));
169 _print(
"Error opening file!");
173 fileHandle.Write(gc);
175 _print(
"Export finished!");
177 ScriptEditor scriptEditor = Workbench.GetModule(ScriptEditor);
179 scriptEditor.SetOpenedResource(fileOutPath);
186 protected bool IsWidgetExportRequired(notnull
BaseContainer ws, notnull array<BaseContainer>
path)
210 return GetWidgetName(ws).StartsWith(
"m_");
218 string wName = GetWidgetName(ws);
224 if (wNameFromRule.IsEmpty())
227 return wNameFromRule;
235 string wName = GetWidgetName(ws);
236 if (wName.Contains(
" "))
238 _print(
string.Format(
"Widget name contains space: %1", wName),
LogLevel.ERROR);
247 if (!wNameFromRule.IsEmpty() && wNameFromRule.Contains(
" "))
249 _print(
string.Format(
"Widget name in the export rule contains space: %1, widget: %2", wNameFromRule, wName),
LogLevel.ERROR);
258 protected array<BaseContainer> ResolveWidgetComponentsForExport(
WidgetSource ws)
261 array<BaseContainer> outArray = {};
263 typename compTypename;
264 for (
int i, count = components.Count(); i < count; i++)
266 comp = components.Get(i);
267 compTypename = comp.GetClassName().ToType();
270 if (!compTypename || (!compTypename.IsInherited(
SCR_WidgetExportRule) && !compTypename.IsInherited(SCR_WidgetExportRuleRoot)))
271 outArray.Insert(comp);
279 protected string GenerateScriptClassName(
string path, notnull
BaseContainer exportRule)
281 int slashId =
path.LastIndexOf(
"/");
282 int dotId =
path.LastIndexOf(
".");
283 int cutSize = dotId - slashId - 1;
284 string fileNameNoPathNoExt =
path.Substring(slashId + 1, cutSize);
286 string prefix, suffix;
287 SCR_WidgetExportRuleRoot.GetClassPrefixAndSuffix(exportRule, prefix, suffix);
289 return string.Format(
"%1%2%3", prefix, fileNameNoPathNoExt, suffix);
298 protected static void BuildWidgetArray(
300 notnull array<BaseContainer> pathToThis,
301 notnull out array<BaseContainer> outArray,
302 notnull out array<ref array<BaseContainer>> outArrayPaths)
304 array<BaseContainer> fullPathToThis = {};
305 fullPathToThis.Copy(pathToThis);
306 fullPathToThis.Insert(ws);
308 outArrayPaths.Insert(fullPathToThis);
312 for (
int e = 0, count = ws.GetNumChildren(); e < count; e++)
314 BuildWidgetArray(ws.GetChild(e), fullPathToThis, outArray, outArrayPaths);
323 protected static string GetStringPathToWidget(notnull array<BaseContainer>
path)
325 int c =
path.Count();
330 for (
int i = 1; i < c - 1; i++)
332 pathStr = pathStr + GetWidgetName(
path[i]) +
".";
335 return pathStr + GetWidgetName(
path[c - 1]);
344 ws.Get(
"Name", result);
350 protected string ResolveDestinationPath(
string fileOutName)
353 BaseContainer widgetSource = Workbench.GetModule(ResourceManager).GetContainer();
355 string destinationPath;
358 BaseContainer rule = SCR_WidgetExportRuleRoot.FindInWidgetSource(widgetSource);
361 destinationPath = SCR_WidgetExportRuleRoot.GetDestinationPath(rule);
362 scriptAddon = SCR_WidgetExportRuleRoot.GetScriptAddon(rule);
365 int bracketIndex = destinationPath.LastIndexOf(
"}");
366 string fileOutPath = destinationPath.Substring(bracketIndex + 1, destinationPath.Length() - bracketIndex - 1);
367 if (!fileOutPath.EndsWith(
"/"))
368 fileOutPath = fileOutPath +
"/";
370 fileOutPath = fileOutPath + fileOutName;
371 fileOutPath = scriptAddon + fileOutPath;
380 PrintFormat(
"[GenerateLayoutClassPlugin] %1", str, level: logLevel);
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
static string ReplaceTimes(string input, string sample, string replacement, int howMany=1, int skip=0)
static string InsertAt(string input, string insertion, int insertionIndex=0)
LogLevel
Enum with severity of the logging message.
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
FileMode
Mode for opening file. See FileSystem::Open.