welsonjs/lib/gtk.js

467 lines
10 KiB
JavaScript

////////////////////////////////////////////////////////////////////////
//
// GTKServer API
//
// * Breif: GTK GUI Programming with WSH (Windows Scripting Host)
// * Author: Go Namhyeon <gnh1201@gmail.com>
// * Project site: https://github.com/gnh1201/welsonjs
//
////////////////////////////////////////////////////////////////////////
var SHELL = require("lib/shell");
// set binPath
var binPath = "bin\\gtk-server";
// start GTKServer
var GTKServer = SHELL.createProcess([binPath, "-stdin"]);
// Common (Widgets)
var GTKWidgets = {};
// Common (Element)
var GTKWidget = function(options) {
this.widgetType = "GTKWidget";
this.widgetID = "0";
this.dispatchEvent = function(event) {
var eventName = 'on' + event.eventName;
event.target = this;
if(eventName in this) {
this[eventName](event);
}
};
this.addEventListener = function(eventName, fn) {
if (typeof(fn) == "function") {
this['on' + eventName] = fn;
} else {
throw new TypeError("EventListener must be a function");
}
};
this.eventListener = function() {
this.dispatchEvent(new GTKEvent("wait"));
return GTKEventListener(this);
};
this.setWidgetType = function(widgetType) {
this.widgetType = widgetType;
};
this.update = function() {
if (typeof(options) === "object") {
for (var k in options) {
this[k] = options[k];
}
}
};
this.create = function() {
this.update();
this.dispatchEvent(new GTKEvent("load"));
this.widgetID = GTKCreateWidget(this);
GTKWidgets[this.widgetID] = this;
}
};
// Common (definedEvents)
var definedEvents = {
"Window": [],
"Table": [],
"Button": ["click"],
"Entry": ["enter"],
"RadioBox": ["click"],
"TextBox": []
};
// Common (Event)
var GTKEvent = function(eventName) {
this.eventName = eventName;
this.target = null;
};
// GTKEventListener
var GTKEventListener = function(widget) {
if (widget.widgetType in definedEvents) {
var widgetEvents = definedEvents[widget.widgetType];
for (var i = 0; i < widgetEvents.length; i++) {
widget.dispatchEvent(new GTKEvent(widgetEvents[i]));
}
}
};
// GTKCreateWidget
var GTKCreateWidget = function(widget) {
var widgetID, commands = [];
switch (widget.widgetType) {
case "Window":
commands.push([
"gtk_window_new",
widget.type
]);
break;
case "Table":
commands.push([
"gtk_table_new",
widget.rows,
widget.columns,
widget.homogeneous
]);
break;
case "Button":
commands.push([
"gtk_button_new_with_label",
"\"" + widget.text + "\""
]);
break;
case "Entry":
commands.push([
"gtk_entry_new",
"NULL",
"NULL"
]);
break;
case "RadioBox":
commands.push([
"gtk_radio_button_new_with_label_from_widget",
widget.memberWidget.widgetID,
"\"" + widget.text + "\""
]);
break;
case "TextBox":
commands.push([
"gtk_text_new",
"NULL",
"NULL"
]);
break;
}
while (commands.length > 0) {
widgetID = GTKExecCommand(commands.pop());
}
return widgetID;
};
// GTKExecCommand
var GTKExecCommand = function(command) {
var line, _command = [];
for (var i = 0; i < command.length; i++) {
var term = command[i];
if (typeof(term) == "number") {
_command.push(term == 0 ? '0' : term);
} else if (typeof(term) == "boolean") {
_command.push(!term ? '0' : '1');
} else if (typeof(term) == "string") {
_command.push(term);
}
}
line = _command.join(' ');
console.log(line);
GTKServer.StdIn.WriteLine(line);
return GTKServer.StdOut.ReadLine();
};
// GTKInit
var GTKInit = function(callback) {
GTKExecCommand([
"gtk_init",
"NULL",
"NULL"
]);
if (typeof(callback) == "function") {
callback();
}
};
// GTKExit
var GTKExit = function() {
return GTKExecCommand([
"gtk_server_exit"
]);
};
// Window
var Window = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "Window";
this.type = 0;
this.title = "WelsonJS GTK GUI Application";
this.width = 450;
this.height = 400;
this.containerWidget = null;
this.setContainer = function(widget) {
this.containerWidget = widget;
return GTKExecCommand([
"gtk_container_add",
this.widgetID,
widget.widgetID
]);
};
this.show = function() {
return GTKExecCommand([
"gtk_widget_show_all",
this.widgetID
]);
};
this.setWidgetType(this.widgetType);
this.create();
GTKExecCommand([
"gtk_window_set_title",
this.widgetID,
"\"" + this.title + "\""
]);
GTKExecCommand([
"gtk_widget_set_usize",
this.widgetID,
this.width,
this.height
]);
};
Window.prototype = new GTKWidget();
Window.prototype.constructor = Window;
// Table
var Table = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "Table";
this.rows = 1;
this.columns = 1;
this.homogeneous = true;
this.attachedWidgets = [];
this.attach = function(widget, left, right, top, bottom) {
this.attachedWidgets.push(widget);
return GTKExecCommand([
"gtk_table_attach_defaults",
this.widgetID,
widget.widgetID,
left,
right,
top,
bottom
]);
};
this.setWidgetType(this.widgetType);
this.create();
};
Table.prototype = new GTKWidget();
Table.prototype.constructor = Table;
// Button
var Button = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "Button";
this.text = "New Button";
this.setWidgetType(this.widgetType);
this.create();
};
Button.prototype = new GTKWidget();
Button.prototype.constructor = Button;
// Entry
var Entry = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "Entry";
this.text = "New Label";
this.focus = function() {
return GTKExecCommand([
"gtk_widget_grab_focus",
this.widgetID
]);
};
this.empty = function() {
GTKExecCommand([
"gtk_editable_delete_text",
this.widgetID,
0,
-1
]);
};
this.getText = function() {
this.text = GTKExecCommand([
"gtk_entry_get_text",
this.widgetID
]);
return this.text;
};
this.setText = function(text) {
this.text = text;
GTKExecCommand([
"gtk_entry_set_text",
this.widgetID,
"\"" + this.text + "\""
]);
};
this.setText(this.text);
this.setWidgetType(this.widgetType);
this.create();
};
Entry.prototype = new GTKWidget();
Entry.prototype.constructor = Entry;
// RadioBox
var RadioBox = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "RadioBox";
this.text = "New RadioBox";
this.group = {
widgetID: "NULL"
};
this.memberWidget = {
widgetID: "NULL"
};
this.setMemberWidget = function(widget) {
this.memberWidget = widget;
};
this.setWidgetType(this.widgetType);
this.update();
if (this.group.widgetID != "NULL") {
this.group.add(this);
}
this.create();
};
RadioBox.prototype = new GTKWidget();
RadioBox.prototype.constructor = RadioBox;
// RadioGroup
var RadioGroup = function() {
GTKWidget.apply(this, arguments);
this.memberWidgets = [];
this.widgetType = "RadioGroup";
this.add = function(widget) {
if (this.memberWidgets.length > 0) {
widget.setMemberWidget(this.memberWidgets[0]);
}
this.memberWidgets.push(widget);
};
};
RadioBox.prototype = new GTKWidget();
RadioBox.prototype.constructor = RadioGroup;
// TextBox
var TextBox = function() {
GTKWidget.apply(this, arguments);
this.widgetType = "TextBox";
this.text = "New TextBox";
this.setText = function(text) {
this.text = text;
GTKExecCommand([
"gtk_text_insert",
this.widgetID,
"NULL",
"NULL",
"NULL",
"\"" + this.text + "\"",
"-1"
]);
};
this.setText(this.text);
this.setWidgetType(this.widgetType);
this.create();
};
TextBox.prototype = new GTKWidget();
TextBox.prototype.constructor = TextBox;
// GTKWait
var GTKWait = function(callback) {
var even;
while (true) {
even = GTKExecCommand([
"gtk_server_callback",
"wait"
]);
if (even in GTKWidgets) {
GTKWidgets[even].eventListener();
}
if (typeof(callback) == "function") {
callback(even);
}
}
GTKExit();
};
// GladeXML
var GladeXML = function() {
var xml;
this.load = function(filename) {
xml = GTKExecCommand([
"glade_xml_new",
filename,
"NULL",
"NULL"
]);
};
this.findWidget = function(widgetName) {
var widgetId = GTKExecCommand([
"glade_xml_get_widget",
xml,
widgetName
]);
var widget = new GTKWidget({
widgetId: widgetId
});
widget.create();
return widget;
};
};
exports.Widget = GTKWidget;
exports.Window = Window;
exports.Table = Table;
exports.Button = Button;
exports.Entry = Entry;
exports.RadioBox = RadioBox;
exports.RadioGroup = RadioGroup;
exports.TextBox = TextBox;
exports.GladeXML = GladeXML;
exports.init = GTKInit;
exports.wait = GTKWait;
exports.exit = GTKExit;
exports.VERSIONINFO = "GTKServer Module (gtk.js) version 0.2";
exports.global = global;
exports.require = require;