Proxymity's Recent Forum Activity

  • I hope this will work for you (I've not tried it). NWjs spawning .bat and .cmd

    Edit:

    If you include the .bat file inside the package.nw (ie import it into c2) then use:

    require('child_process').exec('cmd /c batfile.bat', function(){
       // …your callback code may run here…
    });[/code:192a6lsf]
    

    Thanks, Colludium!

    Already took a look at that Wiki entry - but I hoped to realize that without modifing anything.

    I could also use ajax to realize that, but the main problem is, that I do not want to add anything into the C2 project. When starting the script/app you are prompted for 2 *.csv files, one contains software (vendor,name,path-to-exe, etc.) and one contains a collection of batch-files. The reason why Im doing it that way: not every machine has the same software and/or "functions/features" installed - because of that, you ll have multiple "Softwareconfiguration.csv"s and "Functionconfiguration.csv"s. Plus: when a new software is added to the system, you only have to add a row in one of the *.csv file; same with the "function" configuration. Its aimed to be multiusable without even thouching the C2 projectfiles... (you may know the wise words: "lazy admin is best admin" ).

    So all in all I want to compile the C2 project a single time and want to be able to extend the functionality anytime just by editing *.csv files (and last but not least, editing a *.csv file is much more easier for my collegues instead of opening C2 and editing something in the project itself (and of course, I own the license by myself, not in/for the company ).

    But well, if there isnt an another way, I have to mod the plugin.

    Thanks, anyway!

    Have a great weekend!

    Proxy

  • Hi community!

    First off: this question isnt part of a game - Im playing arround with C2. I want to extend a console-automation I wrote for my company with a GUI (since making a GUI in PowerShell is a pain in the a.... without tools from SAPIEN or others...).

    I tryed a whole lot in making NWjs to open a *.bat or command prompt window. I can't figure out how to do that.

    Something of what I tried so far:

    • NWjs | Run "C:\Temp\my_bat_file.bat" // nope
    • NWjs | Run "C:\Windows\system32\cmd.exe" // nope
    • NWjs | Run "C:\Windows\SysWOW64\cmd.exe" // nope
    • NWjs | Run "cmd.exe" // nope
    • NWjs | Run "process.env.ComSpec + ' /c batfile.bat" // nope (whyever I thought that may works - found that while searching on Google - and yes, I pasted node.js code here... )

    Since launching a *.exe works fine just as it should, I downloaded a bat2exe complier and compiled my *.bat into an executable:

    • NWjs | Run "C:\Temp\my_bat_file.exe" // also: nope

    [everything else what I tried doesnt really made sense at all...]

    My batch just pings Google (8.8.8.8) so far - nothing special. I do not need any kind of automation/value-returning - the user should just see the opened command prompt window with its contents shown before a "pause"- interaction.

    I thought about security reasons why it isnt possible - but writing a malicious script in VS/vbs and compiling it into a native executable is just as easy as in a simple batch script - so I dont think that someone restricted that because of security reasons (obviously I do not want to write malicious software nor harm any system - just to have it said at this point!).

    Does someone know a work-arround for simply opening a *.bat - or if not otherwise possible a compiled *.exe from a *.bat script?

    Have a great weekend

    Proxy

    Edit: even the fail-safe method: NWjs Open Dialog, choosing file, Run NWjs.ChosenPath - doesnt work... I think this has nothing to do with a wrong path or such...

  • andykenobi

    *Sorry for the delay.

    [quote:3oll0gef]

    • Add Set Header (*not stable with fixed header).
    • Add Change Value.

    edittime

    function GetPluginSettings() 
    {
    	return {
    		"name":		"Listview",
    		"id":			"Listview",
    		"version":		"1.3.2",
    		"version modified":		"2",
    		"description":	"Listview.",
    		"author":		"HMMG",
    		"modified by":	"PlayLive",
    		"help url":		"https://www.scirra.com/forum/plugin-listview-header-sorting_t124360",
    		"category":	"Addon",
    		"type":		"world",			// appears in layout
    		"rotatable":	false,
    		"flags":		pf_position_aces | pf_size_aces,
    		"dependency":"jquery.stickytableheaders.min.js;jquery.tablesorter.js;"+
    						"theme.black-ice.css;"+
    						"theme.blue.css;"+
    						"theme.bootstrap.css;"+
    						"theme.bootstrap_2.css;"+
    						"theme.dark.css;"+
    						"theme.default.css;"+
    						"theme.dropbox.css;"+
    						"theme.green.css;"+
    						"theme.grey.css;"+
    						"theme.ice.css;"+
    						"theme.jui.css;"
    	};
    };
    
    ////////////////////////////////////////
    // Parameter types:
    // AddNumberParam(label, description [, initial_string = "0"])			// a number
    // AddStringParam(label, description [, initial_string = "\"\""])		// a string
    // AddAnyTypeParam(label, description [, initial_string = "0"])			// accepts either a number or string
    // AddCmpParam(label, description)										// combo with equal, not equal, less, etc.
    // AddComboParamOption(text)											// (repeat before "AddComboParam" to add combo items)
    // AddComboParam(label, description [, initial_selection = 0])			// a dropdown list parameter
    // AddObjectParam(label, description)									// a button to click and pick an object type
    // AddLayerParam(label, description)									// accepts either a layer number or name (string)
    // AddLayoutParam(label, description)									// a dropdown list with all project layouts
    // AddKeybParam(label, description)										// a button to click and press a key (returns a VK)
    // AddAnimationParam(label, description)								// a string intended to specify an animation name
    // AddAudioFileParam(label, description)								// a dropdown list with all imported project audio files
    
    ////////////////////////////////////////
    // Conditions
    
    // AddCondition(id,					// any positive integer to uniquely identify this condition
    //				flags,				// (see docs) cf_none, cf_trigger, cf_fake_trigger, cf_static, cf_not_invertible,
    //									// cf_deprecated, cf_incompatible_with_triggers, cf_looping
    //				list_name,			// appears in event wizard list
    //				category,			// category in event wizard list
    //				display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
    //				description,		// appears in event wizard dialog when selected
    //				script_name);		// corresponding runtime function name
    				
    
    AddCondition(0, cf_trigger, "On selection changed", "Listview", "On selection changed", "Triggered when the selected ligne changes.", "OnSelectionChanged");
    AddCondition(1, cf_trigger, "On clicked", "Listview", "On clicked", "Triggered when the Listview is clicked.", "OnClicked");
    AddCondition(2, cf_trigger, "On double-clicked", "Listview", "On double-clicked", "Triggered when the Listview is double-clicked.", "OnDoubleClicked");
    AddCondition(3, cf_trigger, "On mouse over", "Listview", "On mouse over", "Triggered when the cursor is over the Listview .", "OnHover");
    
    ////////////////////////////////////////
    // Actions
    
    // AddAction(id,				// any positive integer to uniquely identify this action
    //			 flags,				// (see docs) af_none, af_deprecated
    //			 list_name,			// appears in event wizard list
    //			 category,			// category in event wizard list
    //			 display_str,		// as appears in event sheet - use {0}, {1} for parameters and also <b></b>, <i></i>
    //			 description,		// appears in event wizard dialog when selected
    //			 script_name);		// corresponding runtime function name
    
    AddNumberParam("Index", "The zero-based index of the Row to select.");
    AddAction(0, af_none, "Set selected index", "Row", "Select Row <i>{0}</i>", "Select a Row in the listview.", "SelectedRow");
    
    AddComboParamOption("Invisible");
    AddComboParamOption("Visible");
    AddComboParam("Visibility", "Choose whether to hide or show the listview.");
    AddAction(1, af_none, "Set visible", "Appearance", "Set <b>{0}</b>", "Hide or show the listview.", "SetVisible");
    
    AddAction(2, af_none, "Set focused", "Listview", "Set focused", "Set the input focus to the listview.", "SetFocus");
    AddAction(3, af_none, "Set unfocused", "Listview", "Set unfocused", "Remove the input focus from the listview.", "SetBlur");
    
    AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
    AddAction(4, af_none, "Add Row", "Row", "Add Row <i>{0}</i>", "Append a new Row to the listview.", "AddRow");
    
    AddNumberParam("Index", "The zero-based index of the Row to insert before.");
    AddStringParam("Text", "The Row text to add (to add \":\" use \\:). Exemple 3 Column       \"Item1:Item2:Item3\"");
    AddAction(5, af_none, "Add Row at", "Row", "Add Row <i>{1}</i> at index <i>{0}</i>", "Append a new Row to a specific place in the listview.", "AddRowAt");
    
    AddNumberParam("Index", "The zero-based index of the Row to remove.");
    AddAction(6, af_none, "Remove At", "Row", "Remove Row <i>{0}</i>", "Remove a Row from the listview.", "RemoveAt");
    
    AddAction(7, af_none, "Clear", "Row", "Clear all Rows", "Remove all Rows from the listview.", "Clear");
    
    AddNumberParam("Index", "The zero-based index of the Row to Change css.");
    AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
    AddAction(8, af_none, "Change Row CSS At", "Row", "Change Row <i>{0}</i> CSS to <i>{1}</i>", "Change a Row css.", "ChangeRowCssAt");
    
    AddNumberParam("Row Index", "The zero-based index of the Row to Change the css.");
    AddNumberParam("Cell Index", "The zero-based index of the Cell to Change the css.");
    AddStringParam("Css", "Css exemple    \"background-color:blue;color:white;\" .");
    AddAction(9, af_none, "Change Cell CSS At Row", "Row", "Change Cell <i>{1}</i> At Row <i>{0}</i> CSS to <i>{2}</i>", "Change a Cell css.", "ChangeCellCssAt");
    
    AddNumberParam("Index", "The zero-based index of the Row to Change add a value to.");
    AddStringParam("Key", "Key name where to store the value in the row");
    AddStringParam("Value", "Value to store.");
    AddAction(10, af_none, "Add Value at Row", "Row", "Set <i>{1}</i> = <i>{2}</i> At <i>{0}</i>", "Store a value.", "StoreValueAt");
    
    AddNumberParam("Index", "The zero-based index of the Column to sort by.");
    AddComboParamOption("Ascendant");
    AddComboParamOption("Descendant");
    AddComboParam("Direction", "Select if the sort is Ascendant or Descendant")
    AddAction(11, af_none, "Sort Column", "Sort", "Sort Column of index <i>{0}</i> , Order <i>{1}</i> ", "Sort Column", "sortColumn");
    
    // PlayLive
    AddAction(12, af_none, "Scroll Top", "Listview", "Scroll top", "Scroll to the top line of this object.", "ScrollTop");
    AddAction(13, af_none, "Scroll bottom", "Listview", "Scroll bottom", "Scroll to the bottom of this object.", "ScrollBottom");
    
    AddStringParam("Text", "Set Header (to add \":\" use \\:). Exemple 3 Column       \"Header1:Header2:Header3\"");
    AddAction(14, af_none, "Set Header", "Listview", "Set the header (<i>{0}</i>)", "Set the header.", "SetHeader");
    
    AddNumberParam("Row Index", "The zero-based index of the Row to change the value.");
    AddNumberParam("Cell Index", "The zero-based index of the Cell to change the value.");
    AddStringParam("Value", "Change value (to add \":\" use \\:).");
    AddAction(15, af_none, "Change Value", "Row", "Change value [{0}][{1}] to (<i>{2}</i>)", "Change value at row and cell.", "ChangeValue");
    
    //////////////////////////////////////// 
    // Expressions
    
    // AddExpression(id,			// any positive integer to uniquely identify this expression
    //				 flags,			// (see docs) ef_none, ef_deprecated, ef_return_number, ef_return_string,
    //								// ef_return_any, ef_variadic_parameters (one return flag must be specified)
    //				 list_name,		// currently ignored, but set as if appeared in event wizard
    //				 category,		// category in expressions panel
    //				 exp_name,		// the expression name after the dot, e.g. "foo" for "myobject.foo" - also the runtime function name
    //				 description);	// description in expressions panel
    
    AddExpression(0, ef_return_number, "", "Listview", "RowsCount", "The number of Rows in the listview.");
    AddExpression(1, ef_return_number, "", "Listview", "SelectedRowIndex", "The zero-based index of the currently selected Row.");
    
    AddNumberParam("SubTextIndex", "subText index to get.");
    AddExpression(2, ef_return_string, "", "Listview", "SubTextSelectedRow", "The subText of the currently selected Row.");
    
    AddNumberParam("RowIndex", "Row number to get.");
    AddNumberParam("SubTextIndex", "subText index to get.");
    AddExpression(3, ef_return_string, "", "Listview", "SubTextAt", "The subText of the Nth Row in the listview.");
    
    AddNumberParam("RowIndex", "Row number to get.");
    AddStringParam("Key", "Key name.");
    AddExpression(4, ef_return_string, "", "Listview", "getValueOfKeyAt", "Get stored value of key at a specific row.");
    
    ACESDone();
    
    // Property grid properties for this plugin
    var property_list = [
    	new cr.Property(ept_text,	"Header",				"",			"The initial listiew's header separeted by colon : Exemple header1:header2:header3"),
    	new cr.Property(ept_text,	"Items",				"",			"The initial listiew of items, separated by semicolons ; and colomuns separeted by colon : .Exemple Row1Col1:Row1Col2:Row1Col3;Row2Col1:Row2Col2:Row2Col3;"),
    	new cr.Property(ept_text,	"Colomun Width",	"",			"Set Listview Colomun Width separated by semicolons ;  .Exemple 20%:50%:30%"),
    	new cr.Property(ept_combo,	"Initial visibility",	"Visible",	"Choose whether the list is visible on startup.", "Invisible|Visible"),
    	new cr.Property(ept_text,	"ID (optional)",		"",			"An ID for the control allowing it to be styled with CSS from the page HTML."),
    	new cr.Property(ept_text,	"Header CSS (optional)",		"",		"Add Some CSS to your Listview's header."),
    	new cr.Property(ept_text,	"Rows CSS (optional)",		"",			"Add Some CSS to your Listview's Rows."),
    	new cr.Property(ept_text,	"Cell CSS (optional)",		"",			"Add Some CSS to your Listview's Cells."),
    	new cr.Property(ept_combo,	"Horizontal Alignement",	"Center",		"Set Columns Alignement.", "Left|Center|Right"),
    	new cr.Property(ept_combo,	"Vertical Alignement",	"Center",		"Set Columns Alignement.", "Top|Center|Bottom"),
    	new cr.Property(ept_combo,	"Show Grid",	"No",		"For listview Grid.", "No|Yes"),
    	new cr.Property(ept_combo,	"Show Sorter",	"Yes",		"Show Sorter Icons.", "No|Yes"),
    	new cr.Property(ept_combo,	"Sorter Alignement",	"Right",		"Sorter Alignement .", "Left|Center|Right"),
    	new cr.Property(ept_combo,	"Fixed Header",	"No",		"Header Fixed when scroll.", "No|Yes"),
    	new cr.Property(ept_combo,	"Allow Sort",	"No",		"Allow Sorting.", "No|Yes"),
    	new cr.Property(ept_combo,	"Theme",	"Default",		"Select Listview Theme.", "None|Black-Ice|Blue|Bootstrap|Bootstrap 2|Dark|Default|Dropbox|Green|Grey|Ice|Jui"),
    	new cr.Property(ept_combo,	"Show Y-Scroll",	"Auto",		"Show Y-Scroll.", "Auto|Yes|No")
    ];
    	
    // Called by IDE when a new object type is to be created
    function CreateIDEObjectType()
    {
    	return new IDEObjectType();
    }
    
    // Class representing an object type in the IDE
    function IDEObjectType()
    {
    	assert2(this instanceof arguments.callee, "Constructor called as a function");
    }
    
    // Called by IDE when a new object instance of this type is to be created
    IDEObjectType.prototype.CreateInstance = function(instance)
    {
    	return new IDEInstance(instance);
    }
    
    // Class representing an individual instance of an object in the IDE
    function IDEInstance(instance, type)
    {
    	assert2(this instanceof arguments.callee, "Constructor called as a function");
    	
    	// Save the constructor parameters
    	this.instance = instance;
    	this.type = type;
    	
    	// Set the default property values from the property table
    	this.properties = {};
    	
    	for (var i = 0; i < property_list.length; i++)
    		this.properties[property_list[i].name] = property_list[i].initial_value;
    		
    	// Plugin-specific variables
    	this.just_inserted = false;
    	this.font = null;
    }
    
    IDEInstance.prototype.OnCreate = function()
    {
    	this.instance.SetHotspot(new cr.vector2(0, 0));
    }
    
    IDEInstance.prototype.OnInserted = function()
    {
    	this.instance.SetSize(new cr.vector2(150, 22));
    }
    
    IDEInstance.prototype.OnDoubleClicked = function()
    {
    }
    
    // Called by the IDE after a property has been changed
    IDEInstance.prototype.OnPropertyChanged = function(property_name)
    {
    }
    
    IDEInstance.prototype.OnRendererInit = function(renderer)
    {
    }
    	
    // Called to draw self in the editor
    IDEInstance.prototype.Draw = function(renderer)
    {
    	if (!this.font)
    		this.font = renderer.CreateFont("Arial", 14, false, false);
    		
    	renderer.SetTexture(null);
    	var quad = this.instance.GetBoundingQuad();
    	renderer.Fill(quad, this.properties["Enabled"] === "Yes" ? cr.RGB(255, 255, 255) : cr.RGB(224, 224, 224));
    	renderer.Outline(quad, cr.RGB(0, 0, 0));
    	
    	cr.quad.prototype.offset.call(quad, 4, 2);
    	
    	this.font.DrawText(this.properties["Items"].replace(/;/g, "\n"),
    							quad,
    							cr.RGB(0, 0, 0),
    							ha_left);
    
    }
    
    IDEInstance.prototype.OnRendererReleased = function(renderer)
    {
    	this.font = null;
    }
    [/code:3oll0gef]
    
    [b]runtime[/b]
    [code:3oll0gef]
    // ECMAScript 5 strict mode
    "use strict";
    // Dropbox , Grey , Bootstap Theme dont have Sort icons
    assert2(cr, "cr namespace not created");
    assert2(cr.plugins_, "cr.plugins_ not created");
    
    /////////////////////////////////////
    // Plugin class
    cr.plugins_.Listview = function(runtime)
    {
    	this.runtime = runtime;
    };
    
    (function ()
    {
    	/////////////////////////////////////
    	var pluginProto = cr.plugins_.Listview.prototype;
    		
    	/////////////////////////////////////
    	// Object type class
    	pluginProto.Type = function(plugin)
    	{
    		this.plugin = plugin;
    		this.runtime = plugin.runtime;
    	};
    
    	var typeProto = pluginProto.Type.prototype;
    
    	// called on startup for each object type
    	typeProto.onCreate = function()
    	{
    	};
    
    	/////////////////////////////////////
    	// Instance class
    	pluginProto.Instance = function(type)
    	{
    		this.type = type;
    		this.runtime = type.runtime;
    	};
    	
    	var instanceProto = pluginProto.Instance.prototype;
    
    	/////////////////////////////////////
    	// PlayLive vars
    	var header = [];
    	var lenCol = [];
    	var align = "";
    	var valign = "";
    	
    	// called whenever an instance is created
    	instanceProto.onCreate = function()
    	{
    		// Not supported in DC
    		if (this.runtime.isDomFree)
    		{
    			cr.logexport("[Construct 2] List plugin not supported on this platform - the object will not be created");
    			return;
    		}
    	
    		this.elem = document.createElement("div");
    		this.elem.table = document.createElement("table");
    		this.elem.id = this.properties[4];
    		if($.trim(this.elem.id) <= 0)
    		{
    			this.elem.id = makeid();
    		}
    		this.lastSelection = -1 ;
    
    		$(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
    		
    		// PlayLive
    		if(this.properties[16] == 0)
    			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","auto").css("padding","0px").css("margin","0px");
    		else if(this.properties[16] == 1)
    			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","scroll").css("padding","0px").css("margin","0px");
    		else if(this.properties[16] == 2)
    			$(this.elem).addClass("scrollable-area-"+this.elem.id).append($(this.elem.table)).css("overflow-y","hidden").css("padding","0px").css("margin","0px");
    		
    		var self = this;
    		var ligne = [];
    		var theme = "";
    		
    		if($.trim(self.properties[0]).length>0)
    		{
    			if(self.properties[0][self.properties[0].length-1] == ":")
    				self.properties[0]= self.properties[0].slice(0,-1);
    			header=self.properties[0].split(":");
    		}
    		
    		if($.trim(self.properties[1]).length>0)
    		{
    			if(self.properties[1][self.properties[1].length-1] == ";")
    				self.properties[1]= self.properties[1].slice(0,-1);
    			ligne=self.properties[1].split(";");
    		}
    		
    		if($.trim(self.properties[2]).length>0)
    		{
    			if(self.properties[2][self.properties[2].length-1] == ":")
    				self.properties[2]= self.properties[2].slice(0,-1);
    			lenCol=self.properties[2].split(":");
    		}
    		
    		switch(self.properties[8])
    		{
    			case 0 : align="left";break;
    			case 1 : align="center";break;
    			case 2 : align="right";break;
    			default : align="center";break;
    		}
    		switch(self.properties[9])
    		{
    			case 0 : valign="top";break;
    			case 1 : valign="center";break;
    			case 2 : valign="bottom";break;
    			default : valign="center";break;
    		}
    		
    		
    		this.align = align;
    		this.valign = valign;
    		//$(self.elem.table).addClass("tablesorter");
    		
    		
    		$(self.elem.table).attr({
    							"border":self.properties[10],
    							"cellpadding":"0px",
    							"cellspacing":"0px",
    							"width":"100%"
    		}).css("color","black");
    
    		if(header.length>0)
    		{
    			$(self.elem.table).append("<thead><tr></tr></thead>");
    			for(var i=0 ; i<header.length ; i++)
    			{
    				$(this.elem.table).find("thead tr").append("<th width='"+lenCol[i]+"' colNum='"+i+"' align='"+align+"' valign='"+valign+"' >"+header[i]+"</th>");
    			}
    		}
    		
    		$(self.elem.table).append("<tbody></tbody>");
    		if(ligne.length>0)
    		{
    			for(var i=0 ; i<ligne.length ; i++)
    			{
    				var rowId = "";
    				do
    				{
    					rowId = makeid();
    				}while( $("#"+rowId).length);
    				var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
    				var a = ligne[i].split(":");
    				for(var j=0 ; j<a.length ; j++)
    				{
    					if($.trim(self.properties[7]).length >0)
    						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"' style='"+self.properties[7]+"'>"+a[j]+"</td>");
    					else
    						LigneToAdd.append("<td align='"+align+"' valign='"+valign+"'>"+a[j]+"</td>");
    				}
    				$(self.elem.table).find("tbody").append(LigneToAdd);
    			}
    		}
    
    		if($.trim(self.properties[5]).length >0)
    			$(self.elem.table).find("thead tr").attr("style",self.properties[5]);
    		if($.trim(self.properties[6]).length >0)
    			$(self.elem.table).find("tbody tr").attr("style",self.properties[6]);
    		
    		if( self.properties[14] == 1)
    		{
    			if(self.properties[15] > 0)
    			{
    				switch(self.properties[15])
    				{
    					case 0 : theme="none";break;
    					case 1 : theme="blackice";break;
    					case 2 : theme="blue";break;
    					case 3 : theme="bootstrap";break;
    					case 4 : theme="bootstrap_2";break;
    					case 5 : theme="dark";break;
    					case 6 : theme="default";break;
    					case 7 : theme="dropbox";break;
    					case 8 : theme="green";break;
    					case 9 : theme="grey";break;
    					case 10 : theme="ice";break;
    					case 11 : theme="jui";break;
    					default : theme="default";break;
    				}
    				$(self.elem.table).tablesorter(
    				{
    					theme:theme
    				});
    			}
    			else
    			{
    				$(self.elem.table).tablesorter().removeClass("tablesorter-default");
    			}
    		}
    		else
    		{
    			if(self.properties[15] > 0)
    			{
    				switch(self.properties[15])
    				{
    					case 0 : theme="none";break;
    					case 1 : theme="blackice";break;
    					case 2 : theme="blue";break;
    					case 3 : theme="bootstrap";break;
    					case 4 : theme="bootstrap_2";break;
    					case 5 : theme="dark";break;
    					case 6 : theme="default";break;
    					case 7 : theme="dropbox";break;
    					case 8 : theme="green";break;
    					case 9 : theme="grey";break;
    					case 10 : theme="ice";break;
    					case 11 : theme="jui";break;
    					default : theme="default";break;
    				}
    				$(self.elem.table).addClass("tablesorter-"+theme);
    			}
    		}
    
    		// PlayLive
    		if( self.properties[13] == 1)
    			$(self.elem.table).stickyTableHeaders({ scrollableArea: $(".scrollable-area-"+this.elem.id) })
    
    		var sorterAlign = 2;
    		var sorterVisib = "initial";
    
    		switch(self.properties[12])
    		{
    			case 0 : sorterAlign="left";break;
    			case 1 : sorterAlign="center";break;
    			case 2 : sorterAlign="right";break;
    			default : sorterVisib="right";break;
    		}
    
    		$(self.elem.table).find("thead tr .header").css(
    		{
    			"background-position":"center "+sorterAlign
    		});
    		if( self.properties[11] == 0)
    		{
    			$(self.elem.table).find("thead tr .header").css(
    			{
    				"background-image":"none"
    			});
    		}
    		
    		
    		$(this.elem.table).find("tbody").on('click' , 'tr', function() 
    		{
    			if( parseInt($(this).index()) != self.lastSelection)
    			{
    				self.lastSelection = parseInt($(this).index());
    				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnSelectionChanged, self);
    			}
    		});
    		
    		$(this.elem.table).find("tbody").on('mouseover' , 'tr', function() 
    		{
    			self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnHover, self);
    		});
    		
    		this.elem.onclick = function(e) {
    				e.stopPropagation();
    				self.runtime.isInUserInputEvent = true;
    				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnClicked, self);
    				self.runtime.isInUserInputEvent = false;
    			};
    		
    		this.elem.ondblclick = function(e) {
    				e.stopPropagation();
    				self.runtime.isInUserInputEvent = true;
    				self.runtime.trigger(cr.plugins_.Listview.prototype.cnds.OnDoubleClicked, self);
    				self.runtime.isInUserInputEvent = false;
    			};
    		
    		// Prevent touches reaching the canvas
    		this.elem.addEventListener("touchstart", function (e) {
    			e.stopPropagation();
    		}, false);
    		
    		this.elem.addEventListener("touchmove", function (e) {
    			e.stopPropagation();
    		}, false);
    		
    		this.elem.addEventListener("touchend", function (e) {
    			e.stopPropagation();
    		}, false);
    		
    		// Prevent clicks being blocked
    		jQuery(this.elem).mousedown(function (e) {
    			e.stopPropagation();
    		});
    		
    		jQuery(this.elem).mouseup(function (e) {
    			e.stopPropagation();
    		});
    		
    		this.lastLeft = 0;
    		this.lastTop = 0;
    		this.lastRight = 0;
    		this.lastBottom = 0;
    		this.lastWinWidth = 0;
    		this.lastWinHeight = 0;
    		this.isVisible = true;
    		
    		this.updatePosition(true);
    		
    		this.runtime.tickMe(this);
    	};
    	
    	instanceProto.saveToJSON = function ()
    	{
    		var o = {
    			"tooltip": this.elem.title,
    			"disabled": !!this.elem.disabled,
    			"items": [],
    			"sel": []
    		};
    		
    		var i, len;
    		var itemsarr = o["items"];
    		
    		for (i = 0, len = this.elem.length; i < len; i++)
    		{
    			itemsarr.push(this.elem.options[i].text);
    		}
    		
    		var selarr = o["sel"];
    		
    		if (this.elem["multiple"])
    		{
    			for (i = 0, len = this.elem.length; i < len; i++)
    			{
    				if (this.elem.options[i].selected)
    					selarr.push(i);
    			}
    		}
    		else
    		{
    			selarr.push(this.elem["selectedIndex"]);
    		}
    		
    		return o;
    	};
    	
    	instanceProto.loadFromJSON = function (o)
    	{
    		this.elem.title = o["tooltip"];
    		this.elem.disabled = o["disabled"];
    		
    		var itemsarr = o["items"];
    		
    		// Clear the list
    		while (this.elem.length)
    			this.elem.remove(this.elem.length - 1);
    			
    		var i, len, opt;
    		for (i = 0, len = itemsarr.length; i < len; i++)
    		{
    			opt = document.createElement("option");
    			opt.text = itemsarr[i];
    			this.elem.add(opt);
    		}
    		
    		var selarr = o["sel"];
    		
    		if (this.elem["multiple"])
    		{
    			for (i = 0, len = selarr.length; i < len; i++)
    			{
    				if (selarr[i] < this.elem.length)
    					this.elem.options[selarr[i]].selected = true;
    			}
    		}
    		else if (selarr.length >= 1)
    		{
    			this.elem["selectedIndex"] = selarr[0];
    		}
    	};
    	
    	instanceProto.onDestroy = function ()
    	{
    		if (this.runtime.isDomFree)
    				return;
    		
    		jQuery(this.elem).remove();
    		this.elem = null;
    	};
    	
    	instanceProto.tick = function ()
    	{
    		this.updatePosition();
    	};
    	
    	instanceProto.updatePosition = function (first)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		var left = this.layer.layerToCanvas(this.x, this.y, true);
    		var top = this.layer.layerToCanvas(this.x, this.y, false);
    		var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
    		var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
    		
    		var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
    		var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
    		
    		// Is entirely offscreen or invisible: hide
    		if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
    		{
    			if (this.isVisible)
    				jQuery(this.elem).hide();
    			
    			this.isVisible = false;
    			return;
    		}
    		
    		// Truncate to canvas size
    		if (left < 1)
    			left = 1;
    		if (top < 1)
    			top = 1;
    		if (right >= rightEdge)
    			right = rightEdge - 1;
    		if (bottom >= bottomEdge)
    			bottom = bottomEdge - 1;
    		
    		var curWinWidth = window.innerWidth;
    		var curWinHeight = window.innerHeight;
    			
    		// Avoid redundant updates
    		if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
    		{
    			if (!this.isVisible)
    			{
    				jQuery(this.elem).show();
    				this.isVisible = true;
    			}
    			
    			return;
    		}
    			
    		this.lastLeft = left;
    		this.lastTop = top;
    		this.lastRight = right;
    		this.lastBottom = bottom;
    		this.lastWinWidth = curWinWidth;
    		this.lastWinHeight = curWinHeight;
    		
    		if (!this.isVisible)
    		{
    			jQuery(this.elem).show();
    			this.isVisible = true;
    		}
    		
    		var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
    		var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
    		jQuery(this.elem).css("position", "absolute");
    		jQuery(this.elem).offset({left: offx, top: offy});
    		jQuery(this.elem).width(Math.round(right - left));
    		jQuery(this.elem).height(Math.round(bottom - top));
    		
    	};
    	
    	// only called if a layout object
    	instanceProto.draw = function(ctx)
    	{
    	};
    	
    	instanceProto.drawGL = function(glw)
    	{
    	};
    	
    	/**BEGIN-PREVIEWONLY**/
    	instanceProto.getDebuggerValues = function (propsections)
    	{
    		propsections.push({
    			"title": "List",
    			"properties": [
    				{"name": "Item count", "value": this.elem.length, "readonly": true},
    				{"name": "Enabled", "value": !this.elem.disabled},
    				{"name": "Tooltip", "value": this.elem.title},
    				{"name": "Selected index", "value": this.elem.selectedIndex}
    			]
    		});
    		
    		var props = [], i, len;
    		for (i = 0, len = this.elem.length; i < len; ++i)
    		{
    			props.push({"name": i.toString(), "value": this.elem.options[i].text});
    		}
    		
    		propsections.push({
    			"title": "Items",
    			"properties": props
    		});
    	};
    	
    	instanceProto.onDebugValueEdited = function (header, name, value)
    	{
    		if (header === "List")
    		{
    			switch (name) {
    			case "Enabled":
    				this.elem.disabled = !value;
    				break;
    			case "Tooltip":
    				this.elem.title = value;
    				break;
    			case "Selected index":
    				this.elem.selectedIndex = value;
    				break;
    			}
    		}
    		else if (header === "Items")
    		{
    			this.elem.options[parseInt(name, 10)].text = value;
    		}
    	};
    	/**END-PREVIEWONLY**/
    
    	//////////////////////////////////////
    	// Conditions
    	function Cnds() {};
    	
    	Cnds.prototype.OnSelectionChanged = function ()
    	{
    		return true;
    	};
    	
    	Cnds.prototype.OnClicked = function ()
    	{
    		return true;
    	};
    	
    	Cnds.prototype.OnDoubleClicked = function ()
    	{
    		return true;
    	};
    	
    	Cnds.prototype.OnHover = function ()
    	{
    		return true;
    	};
    	
    	
    	pluginProto.cnds = new Cnds();
    	
    	//////////////////////////////////////
    	// Actions
    	function Acts() {};
    	
    	Acts.prototype.SelectedRow = function (i)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		this.lastSelection = i;
    		$(this.elem.table).find("tbody tr.selected").removeClass("selected");
    		$(this.elem.table).find("tbody tr").eq(i).addClass("selected");
    	};
    	
    	Acts.prototype.SetVisible = function (vis)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		this.visible = (vis !== 0);
    	};
    	
    	Acts.prototype.SetFocus = function ()
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		this.elem.table.focus();
    	};
    	
    	Acts.prototype.SetBlur = function ()
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		this.elem.table.blur();
    	};
    
    	
    	Acts.prototype.AddRow = function (text_)
    	{
    		if (this.runtime.isDomFree)
    			return;
    
    		var rowId = "";
    		do { rowId = makeid(); }
    		while( $("#"+rowId).length);
    		
    		
    		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
    		var a = text_.split(":");
    		var r = a.toString().replace(/\\,/g, ":");
    		a = r.split(",");
    
    		for(var j=0 ; j<a.length ; j++)
    		{
    			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
    		}
    
    		$(this.elem.table).find("tbody").append(LigneToAdd);
    
    		if( this.properties[14] == 1)
    		{
    			$(this.elem.table).trigger('update');     
    			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
    		}
    	};
    	
    	Acts.prototype.AddRowAt = function (index_, text_)
    	{
    		if (this.runtime.isDomFree)
    			return;
    
    		var rowId = "";
    		do
    		{
    			rowId = makeid();
    		}while( $("#"+rowId).length);
    		
    		
    		var LigneToAdd = $("<tr id-row='"+rowId+"'></tr>");
    		var a = text_.split(":");
    		var r = a.toString().replace(/,,/g, ":");
    		a = r.split(",");
    		for(var j=0 ; j<a.length ; j++)
    		{
    			LigneToAdd.append("<td align='"+this.align+"' valign='"+this.valign+"' style='"+this.properties[7]+"'>"+a[j]+"</td>");
    		}
    		
    		if(index_ > 0)
    			LigneToAdd.insertBefore($(this.elem.table).find("tbody tr").eq(index_));
    		else
    			LigneToAdd.appendTo($(this.elem.table).find("tbody"));
    		
    		if( this.properties[14] == 1 )
    		{
    			$(this.elem.table).trigger('update');
    			$(this.elem.table).trigger("sorton",[$(this.elem.table).get(0).config.sortList]); 
    		}
    	};
    	
    	Acts.prototype.RemoveAt = function (index_)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		if(index_ == this.lastSelection)
    				this.lastSelection = -1 ;
    
    		$(this.elem.table).find("tbody tr").eq(index_).remove();
    	};
    
    	Acts.prototype.ChangeRowCssAt = function (index_,css)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		var item = $(this.elem.table).find("tbody tr").eq(index_);
    		if(item.is("[style]"))
    			item.attr("style",item.attr("style")+css);
    		else
    			item.attr("style",css);
    	};
    	
    	Acts.prototype.ChangeCellCssAt = function (index_,index_2,css)
    	{
    		if (this.runtime.isDomFree)
    			return;
    
    		var item = $(this.elem.table).find("tbody tr").eq(index_).find("td").eq(index_2);
    		if(item.is("[style]"))
    			item.attr("style",item.attr("style")+css);
    		else
    			item.attr("style",css);
    	};
    	
    	Acts.prototype.StoreValueAt = function (index_,key,val)
    	{
    		if (this.runtime.isDomFree)
    			return;
    
    		$(this.elem.table).find("tbody tr").eq(index_).attr(key,val);
    	};
    	
    	Acts.prototype.sortColumn = function (index_,val)
    	{
    		if (this.runtime.isDomFree)
    			return;
    		$("table").trigger("sorton",[ [[index_,val]] ]);
    		
    	};
    	
    	Acts.prototype.Clear = function ()
    	{
    		$(this.elem.table).find("tbody tr").remove();
    	};
    
    	Acts.prototype.ScrollTop = function () // PlayLive
    	{
    		if (this.runtime.isDomFree)
    			return;
    
            this.elem.scrollTop = 0;
    	};
    
    	Acts.prototype.ScrollBottom = function () // PlayLive
    	{
    		if (this.runtime.isDomFree)
    			return;
    		
    		this.elem.scrollTop = this.elem.scrollHeight;
    	};
    
    	Acts.prototype.SetHeader = function (str_) // PlayLive
    	{
    		if (this.runtime.isDomFree)
    			return;
    /*
    		var newheader = str_.split(":");
    
    		if (newheader.length > 0)
    		{
    			$(this.elem.table).find("thead tr th").text("");
    			var table = $(this.elem.table).find("thead tr th").length / 2;
    
    			while (newheader.length > table) {
    				$(this.elem.table).find("thead tr").append("<th align='"+align+"' valign='"+valign+"'></th>");
    				table++;
    			}
    
    			while (newheader.length < table) {
    				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
    				$(this.elem.table).find("thead tr th:eq("+(table)+")").remove();
    				table--;
    			}
    
    			for (var i = 0; i < table; i++) {
    				$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
    			}
    		}
    */
    		var newheader = str_.split(":");
    		$(this.elem.table).find("thead tr th").text("");
    
    		for (var i = 0; i < newheader.length; i++)
    			$(this.elem.table).find("thead tr th:eq("+i+")").text(newheader[i]);
    
    	};
    
    	Acts.prototype.ChangeValue = function (row_, cell_, str_) // PlayLive
    	{
    		$(this.elem.table).find("tbody tr:eq("+row_+") td:eq("+cell_+")").text(str_);
    	};
    	
    	pluginProto.acts = new Acts();
    	
    	//////////////////////////////////////
    	// Expressions
    	function Exps() {};
    	
    	Exps.prototype.RowsCount = function (ret)
    	{
    		if (this.runtime.isDomFree)
    		{
    			ret.set_int(0);
    			return;
    		}
    		
    		ret.set_int($(this.elem.table).find("tbody tr").length);
    	};
    	
    	Exps.prototype.SelectedRowIndex = function (ret)
    	{
    		if (this.runtime.isDomFree)
    		{
    			ret.set_int(0);
    			return;
    		}
    		ret.set_int(this.lastSelection);
    	};
    	
    	Exps.prototype.SubTextSelectedRow = function (ret,SubTextIndex)
    	{
    		if (this.runtime.isDomFree)
    		{
    			ret.set_string("");
    			return;
    		}
    		
    		ret.set_string($(this.elem.table).find("tbody tr").eq(this.lastSelection).find("td").eq(SubTextIndex).text());
    	};
    	
    	
    	Exps.prototype.SubTextAt = function (ret,LigneIndex , SubTextIndex)
    	{
    		if (this.runtime.isDomFree)
    		{
    			ret.set_string("");
    			return;
    		}
    		
    		ret.set_string($(this.elem.table).find("tbody tr").eq(LigneIndex).find("td").eq(SubTextIndex).text() );
    	};
    	
    	
    	Exps.prototype.getValueOfKeyAt = function (ret,RowIndex , Key) // PlayLive
    	{
    		if (this.runtime.isDomFree)
    		{
    			ret.set_string("");
    			return;
    		}
    		
    		ret.set_string($(this.elem.table).find("tbody tr").eq(RowIndex).attr(Key) );
    	};
    	pluginProto.exps = new Exps();
    
    }());
    
    function makeid()
    {
        var text = "";
        var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    	
        for( var i=0; i < 10; i++ )
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        return text;
    }
    
    function createCSSSelector(selector, style) 
    {
    	var cssrules =  $("<style type='text/css'> </style>").appendTo("head");
    	cssrules.append(selector+"{ "+style+" }"); 
    }
    [/code:3oll0gef]
    
    
    Thanks for the update!
    
    Does someone can tell me how to fill the listview with a JSON as source? oO Somehow I cant manage that...
  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • mattb

    Well, thats exactly what I needed! Thanks!

  • Thanks for providing us your sources! Creative ideas are always great

    By the way, do you know Jams, where the topic "low poly" is commonly used? I know what jams are, but not really where I can find them (beside stupidly googling them ;D ).

  • is it possible to do it without smtp?

    http://stackoverflow.com/questions/2513 ... using-smtp

    Hi again,

    as far as I know its not possible to send a mail without an outgoing server. The only way without having a smtp server, which comes in my mind, is setting up a temporary, local, one. The problem could be (in fact, its a great thing - but not for your idea <img src="{SMILIES_PATH}/icon_e_wink.gif" alt=";)" title="Wink"> ), that most hosters (aol, hotmail, gmx, etc.) will definatly decline your mail (not even putting it into spam - it just wont be delivered) because your IP may be "unknown" (or you just got one, which was banned before).. chances are huge, when setting up a local smtp on a not static IP, that your users will run into this. Maybe checking a users IP (tools like http://mxtoolbox.com/blacklists.aspx) could secure, that a sended mail will be delivered, but dont count on that.

    You could possibly just setup a new outlook.com account; enable pop/imap functionality (in order to also enable external mailsending via smtp) or get a domainhosting. Dont know about free-mailhostings if you can "spoof" your sender-address (turning XY@outlook.com into XY@something.com - but I dont think that free hoster will do so); otherwise the reciever will get your sended mails with its original domain (@outlook.com or something).

    (in short: easiest is getting a hosted domain with mails; setting up a php backend-script and sending mails over that - that will secure that your mails are delivered in *any* case and that you got a professional looking domain like "support@yourgame.com" and not a junky one like "mygame12345@outlook.com" <img src="{SMILIES_PATH}/icon_e_wink.gif" alt=";)" title="Wink"> )

    You may want to read this: http://superuser.com/a/1006087

    Regards

    Proxy

  • Hi blurymind,

    of course; with C2 (nearly) everything is possible!

    The easiest way, which comes in my mind, is using the AJAX plugin to give over informations to a PHP script. Take a look at: http://teachingyou.net/php/simple-php-c ... sing-ajax/ - that should do the trick (transfer your data from your project with POST to the backend script and see the magic happen).

    You could also take a look in here (dont know the current state of the plugin): send-emails-with-construct_t167741

    or

    https://www.scirra.com/store/royalty-fr ... sender-156

    In any way you'll also need a SMTP server.

    Regards

    Proxy

  • Im working on a roguelike-rpg-ish game (or maybe a gamekit/template... lets see how much time I got the next months), featuring a pattern-based procedual dungeon/world-generation with different enemy-types and behaviours (a very early version of the generation is here: https://www.scirra.com/forum/viewtopic.php?f=147&t=179311&p).

    All graphics are placeholders (untill I find someone who can deal with 16x16 sprites.. because I cant .

  • That's great man,

    Looking forward to seeing some gameplay

    Thanks

    This is how far I have come today/and yesterday..? ).

    Working with tilemaps is much easier than I thought...!

    After spending hours trying to realize the idea of creating an additional array (1D), just for storing already calculated (by random) X,Y coords for each newly generated tilemap, at some point where I realized that this method is slower (I strongly think, thats just me, beeing unable to work with arrays that way

    Cheers

    Proxy

  • It looks good to me. If you did find that it stutters a bit when you add in all your other gameplay elements on top you could think about creating the room a bit more slowly to lessen the load at the point of creation but it probably won't be necessary.

    Ill see it, when its time to script that part of the game

    If I remind myself, Im going to report here, how performance is going (and may keep this *.capx here updated ).

    "Final" version (for now) for generating rooms:

    http://www.proxy.wtf/_storage/construct2/capxs/PBDG_v2.capx

    In the end, it was very simple... had too many too complex thoughts about what Im going to need & do... as always... thanks C2 for your simpleness! ;D

    Best regards

    Proxy

  • Hey Proxy, is this dungeon intended to be seamless? The only thing I would worry about if I was you would be creating another room while there is a lot going on in the current screen because that is how you get jank.

    Debug is your friend. Keep a close eye on how things are going as you implement it and it should give you a good idea of what is efficient and what isn't.

    Hi GenkiGenga,

    yes, its intended to be seamless.

    Im thinking about generating 3-4 rooms on start, and every time you reach the next one, an another is beeing genereted, if there isnt much action onscreen (thinking about making the generation dynamically; if not many objects are onscreen, the "generate-trigger" will be called; if there isnt such moment there is a hard-cap, when entering the last room created.... something like this might be possible somehow, if I debug it correctly, how you said .

    This is my current status on it (much more simpler than I thought at first, lol...):

    http://proxy.wtf/_storage/construct2/capxs/PBDG.capx

    This is a very quick and even more dirty version... rooms are stored in *.txt files; they are loaded into an array on start.... just figured out, that my experience in working with tilemaps isnt the best - after I got the generator done, Ill take a look into it. The "TilemapGenerator" layout + event sheet is provided by R0J0hound: (will be removed, just used it for a fast tilemap JSON).

    Cheers

    Proxy

  • Hi nemezes,

    you might take a look at: https://www.scirra.com/store/royalty-fr ... g-1134#faq bought it myself some time ago and I can really recommend this template. Might help you out <img src="{SMILIES_PATH}/icon_e_wink.gif" alt=";)" title="Wink"> .

    Have a great weekend

    Proxy

Proxymity's avatar

Proxymity

Member since 24 Oct, 2014

None one is following Proxymity yet!

Connect with Proxymity