I extended my text box to a hole set of object for editing tags, which I hereby share with all of you. Any comments are ofcourse welcome.
The following code contains:
- InputBox (Title, Tag, Multivalue, x, y, Title width, Text box width, Font size)
- Keywords (Title, Tag, List of values, List of descriptions, x, y, Title width, Max width of values, Font size)
- CheckBox(Title, Tag, x, y, Title width, Font size)
- RadioBox(Title, Tag, List of values, List of descriptions, x, y, Title width, Value width [if not show all], Font size, Show all)
- InputRating (Title, Tag, Maximum rating, x, y, Title width, Font size)
inputobjects = [];
function InputBox(title, tag, multivalue, x, y, tw, tbw, h) {
this.type = "ib";
this.title = title;
this.tag = tag;
this.multivalue = multivalue;
this.editsep = "; ";
this.content = new Array();
this.contentedit = "";
this.contenteditbak = "";
this.nrvalues = 0;
this.tleft = x;
this.left = x + tw;
this.top = y;
this.tw = tw;
this.w = tbw;
this.h = 0;
this.fh = h;
this.margin = 0.3 * h;
this.colourb = RGB(255, 255, 255);
this.colourba = RGB(255, 255, 200);
this.colourt = RGB(255, 255, 255);
this.colourttb = RGB(0, 0, 0);
this.active = false;
this.specialchar = "";
this.gfont = gdi.Font("Arial Unicode MS", this.fh, 0);
inputobjects.push(this);
this.draw = function (gr) {
sepcolour = RGB(255, 127, 127);
flags = 0x00000000;
flagsl = 0x00000002;
nfo = gr.MeasureString("n", this.gfont, 0, 0, 10000, 100, 0);
sepinfo = gr.MeasureString(this.editsep, this.gfont, 0, 0, 10000, 100, 0);
this.h = nfo.Height;
//title
gr.GdiDrawText(this.title, this.gfont, this.colourt, this.tleft, this.top, this.tw-this.margin, this.h, 0);
if (!this.active) {
gr.FillSolidRect(this.left, this.top, this.w, this.h, this.colourb);
//content not active
pos = 0;
tmpstr = "";
for (n = 0 ; n < this.nrvalues; n++) {
if (n != 0) {
tmpstr += this.editsep;
if (pos < (this.w - 2 * this.margin)) gr.GdiDrawText(this.editsep, this.gfont, sepcolour, this.left + this.margin + pos, this.top, this.w - 2 * this.margin - pos, this.h, flags);
info = gr.MeasureString(this.editsep, this.gfont, 0, 0, 10000, 100, 0);
pos += info.Width;
if (tmpstr.slice(-1) == " ") pos += 0.5*nfo.Width;
}
tmpstr += this.content[n];
if (pos < (this.w - 2 * this.margin)) gr.GdiDrawText(this.content[n], this.gfont, this.colourttb, this.left + this.margin + pos, this.top, this.w - 2 * this.margin - pos, this.h, flags);
info = gr.MeasureString(this.content[n], this.gfont, 0, 0, 10000, 100, 0);
pos += info.Width;
}
}
else {
gr.FillSolidRect(this.left, this.top, this.w, this.h, this.colourba);
//content active
info = gr.MeasureString(this.contentedit, this.gfont, 0, 0, 10000, 100, 0);
flg = flags;
befcur = this.contentedit.slice(0, this.cursor);
tbw = this.w
cursorinfo = gr.MeasureString(befcur, this.gfont, 0, 0, 10000, 100, 0);
cend = false;
drwtxt = this.contentedit;
if (cursorinfo.Width > (this.w - this.margin - nfo.Width)) {
flg = flagsl;
cend = true;
drwtxt = befcur;
tbw -= 0.5 * nfo.Width;
}
gr.GdiDrawText(drwtxt, this.gfont, this.colourttb, this.left + this.margin, this.top, tbw - 2 * this.margin, this.h, flg);
//cursor
if (cend) {
gr.FillSolidRect(this.left + tbw - this.margin, this.top + 1.1 * this.fh, 0.5 * nfo.Width, 2, this.colourttb);
}
else {
cursorinfo=gr.MeasureString(this.contentedit.slice(0, this.cursor), this.gfont, 0, 0, 10000, 100, 0);
cleft = cursorinfo.Width;
if (befcur.slice(-1) == " ") cleft += 0.5*nfo.Width;
gr.FillSolidRect(this.left + this.margin + cleft, this.top + 1.1 * this.fh, 0.5 * nfo.Width, 2, this.colourttb);
}
}
}
this.onMove = function (x, y) {}
this.onClick = function (x, y) {
if ((this.left < x) && (x < (this.left + this.w)) && (this.top < y) && (y < (this.top + this.h))) {
if (!this.active) {
this.active = true;
this.cursor = this.contentedit.length;
this.special = false;
}
}
else {
this.save();
}
}
this.loadeditstr = function () {
tmpstr = "";
for (n = 0 ; n < this.nrvalues; n++) {
if (n != 0) tmpstr += this.editsep;
tmpstr += this.content[n];
}
this.contenteditbak = this.contentedit;
this.contentedit = tmpstr;
}
this.spliteditstr = function () {
if (this.multivalue) {
tmparr = new Array ();
tmpstr = this.contentedit;
editseptrim = this.editsep;
if (editseptrim.slice(0, 1) == " ") editseptrim = editsepttrim.slice(1);
if (editseptrim.slice(-1) == " ") editseptrim = editseptrim.slice(0, editseptrim.length - 1);
m = 0;
do {
seppos = tmpstr.indexOf(editseptrim);
if (seppos == -1) {
tmparr[m] = tmpstr;
}
else {
tmparr[m] = tmpstr.slice(0, seppos);
tmpstr = tmpstr.slice(seppos + 1);
if (tmpstr.slice(0, 1) == " ") tmpstr = tmpstr.slice(1);
}
if (tmparr[m].slice(-1) == " ") tmparr[m] = tmparr[m].slice(0, tmparr[m].Length - 1);
m++;
} while (seppos != -1);
this.content = tmparr;
this.nrvalues = m;
}
else
this.content[0] = this.contentedit;
}
this.load = function () {
idx = metadata.MetaFind(this.tag);
if (idx > metadata.MetaCount) this.nrvalues = 0; else this.nrvalues = metadata.MetaValueCount(idx);
for (n = 0 ; n < this.nrvalues; n++) this.content[n] = metadata.MetaValue(idx, n);
this.active = false;
this.loadeditstr();
}
this.save = function () {
if (this.contentedit != this.contenteditbak && this.active) {
this.spliteditstr();
if (this.multivalue) {
metadata.MetaRemoveField(this.tag);
idx = metadata.MetaAdd(this.tag, this.content[this.nrvalues -1]);
for (n = this.nrvalues - 2 ; n > -1; n--) {
metadata.MetaInsertValue(idx, 0, this.content[n]);
}
}
else
metadata.MetaSet (this.tag, this.content[0]);
g_handle.UpdateFileInfo(metadata);
this.active = false;
this.loadeditstr();
reload = true;
}
else
this.active = false;
}
}
function Keywords(title, tag, list, listlong, x, y, tw, kw, h) {
this.type = "kw";
this.title = title;
this.tag = tag;
this.list = list;
this.listlong = listlong;
this.content = new Array();
this.changed = false;
this.errorstr = "";
this.errorcontent = new Array();
this.nrvalues = 0;
this.tleft = x;
this.left = new Array();
this.top = y;
this.tw = tw;
this.kw = kw;
this.width = new Array();
this.h = 0;
this.fh = h;
this.margin = 0.3 * h;
this.scroll = 0;
this.maxscroll = 0;
this.scrollpbut = false;
this.scrollnbut = false;
this.colourkw = RGB(229, 229, 229);
this.colourkwh = RGB(255, 255, 200);
this.colourt = RGB(255, 255, 255);
this.hover = -1;
this.hoverbut = -1;
this.emptyhover = false;
this.emptyhoverbut = false;
this.gfont = gdi.Font("Arial Unicode MS", this.fh, 0);
this.gfontbut = gdi.Font("Arial Unicode MS", this.fh / 1.3, 0);
inputobjects.push(this);
this.draw = function (gr) {
flags = 0x00000000;
flagsl = 0x00000002;
flagsb = 0x00000001;
nfo = gr.MeasureString("n", this.gfont, 0, 0, 10000, 100, 0);
nfob = gr.MeasureString("◀", this.gfontbut, 0, 0, 10000, 100, 0);
nfof = gr.MeasureString("▶", this.gfontbut, 0, 0, 10000, 100, 0);
nfop = gr.MeasureString("+", this.gfontbut, 0, 0, 10000, 100, 0);
nfom = gr.MeasureString("−", this.gfontbut, 0, 0, 10000, 100, 0);
this.h = nfo.Height;
//title
gr.GdiDrawText(this.title, this.gfont, this.colourt, this.tleft, this.top, this.tw-this.margin, this.h, 0);
//values
leftstart = this.tleft + this.tw;
pos = 0;
for (i = 0 ; i < this.nrvalues; i++) {
this.left[i] = leftstart + pos;
info = gr.MeasureString(this.content[i], this.gfont, 0, 0, 10000, 100, 0);
this.width[i] = info.Width;
if (this.width[i] < (4 * this.h / 3)) this.width[i] = 4* this.h / 3;
pos += this.width[i];
this.maxscroll = pos - this.kw;
if (this.hover == i) colour = this.colourkwh; else colour = this.colourkw;
if (this.errorcontent[i]) colour = RGB(255, 0, 0);
this.left[i] -= this.scroll;
fl = flags;
if (this.left[i] < leftstart) {
fl = flagsl;
this.width[i] += this.left[i] - leftstart;
this.left[i] = leftstart;
}
if ((this.left[i] + this.width[i]) > (leftstart + this.kw)) this.width[i] = leftstart + this.kw - this.left[i];
if (this.width[i] >= 0) {
gr.GdiDrawText(this.content[i], this.gfont, colour, this.left[i], this.top, this.width[i], this.h, fl);
}
pos += nfo.Width + this.margin;
}
//menu
if (this.hover != -1 && !this.scrollpbut && !this.scrollnbut) {
gr.DrawLine(this.left[this.hover], this.top, this.left[this.hover] + this.width[this.hover], this.top, 1, this.colourkwh);
if (this.hoverbut == 0) {
gr.DrawRect(this.left[this.hover], this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
else
colour = this.colourkw;
gr.DrawLine(this.left[this.hover], this.top, this.left[this.hover] + this.h / 3, this.top, 1, this.colourkwh);
gr.GdiDrawText("◀", this.gfontbut, colour, this.left[this.hover] + (this.h / 3 - nfob.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
if (this.hoverbut == 1) {
gr.DrawRect(this.left[this.hover] + this.h / 3, this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
else
colour = this.colourkw;
gr.DrawLine(this.left[this.hover] + this.h / 3, this.top, this.left[this.hover] + 2 * this.h / 3, this.top, 1, this.colourkwh);
gr.GdiDrawText("▶", this.gfontbut, colour, this.left[this.hover] + this.h / 3 + (this.h / 3 - nfof.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
if (this.hoverbut == 2) {
gr.DrawRect(this.left[this.hover] + this.width[this.hover] - 2 * this.h / 3, this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
else
colour = this.colourkw;
gr.DrawLine(this.left[this.hover] + this.width[this.hover] - 2 * this.h / 3, this.top, this.left[this.hover] + this.width[this.hover] - this.h / 3, this.top, 1, this.colourkwh);
gr.GdiDrawText("+", this.gfontbut, colour, this.left[this.hover] + this.width[this.hover] - 2 * this.h / 3 + (this.h / 3 - nfop.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
if (this.hoverbut == 3) {
gr.DrawRect(this.left[this.hover] + this.width[this.hover] - this.h / 3, this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
else
colour = this.colourkw;
gr.DrawLine(this.left[this.hover] + this.width[this.hover] - this.h / 3, this.top, this.left[this.hover] + this.width[this.hover], this.top, 1, this.colourkwh);
gr.GdiDrawText("−", this.gfontbut, colour, this.left[this.hover] + this.width[this.hover] - this.h / 3 + (this.h / 3 - nfom.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
}
//scroll buttons
if (this.scrollpbut) {
gr.DrawRect(leftstart, this.top + this.h / 4, this.h / 2, this.h / 2, 1, this.colourkwh);
gr.GdiDrawText("◀", this.gfont, this.colourkwh, leftstart, this.top, this.h / 2, this.h, flagsb);
}
if (this.scrollnbut) {
gr.DrawRect(leftstart + this.kw - this.h / 2, this.top + this.h / 4, this.h / 2, this.h / 2, 1, this.colourkwh);
gr.GdiDrawText("▶", this.gfont, this.colourkwh, leftstart + this.kw - this.h / 2, this.top, this.h / 2, this.h, flagsb);
}
//empty
if (this.emptyhover) {
gr.DrawLine(leftstart + this.h / 3, this.top, leftstart + this.kw, this.top, 1, this.colourkwh);
if (this.emptyhoverbut == 0)
colour = this.colourkw;
else {
gr.DrawRect(leftstart, this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
gr.DrawLine(leftstart, this.top, leftstart + this.h / 3, this.top, 1, this.colourkwh);
gr.GdiDrawText("+", this.gfontbut, colour, leftstart + (this.h / 3 - nfop.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
}
}
this.onMove = function (x, y) {
this.hover = -1;
this.hoverbut = -1;
this.emptyhover = false;
this.emptyhoverbut = false;
for (i = 0 ; i < this.nrvalues; i++) {
if (this.width[i] >= 0) {
if ((this.left[i] < x) && (x < (this.left[i] + this.width[i])) && (this.top < y) && (y < (this.top + this.h))) {
this.hover = i;
if ((this.left[i] < x) && (x < (this.left[i] + this.h / 3)) && (this.top < y) && (y < (this.top + this.h / 3))) this.hoverbut = 0;
if (((this.left[i] + this.h / 3) < x) && (x < (this.left[i] + 2* this.h / 3) ) && (this.top < y) && (y < (this.top + this.h / 3))) this.hoverbut = 1;
if (((this.left[i] + this.width[i] - 2* this.h / 3) < x) && (x < (this.left[i] + this.width[i]) ) && (this.top < y) && (y < (this.top + this.h / 3))) this.hoverbut = 2;
if (((this.left[i] + this.width[i] - this.h / 3) < x) && (x < (this.left[i] + this.width[i]) ) && (this.top < y) && (y < (this.top + this.h / 3))) this.hoverbut = 3;
}
}
}
if (((this.tleft + this.tw) < x) && (x < (this.tleft + this.tw + this.h / 2)) && ((this.top + this.h / 4) < y) && (y < (this.top + 3 * this.h / 4)) && (this.scroll > 0)) {
this.scrollpbut = true;
this.hover = -1;
this.hoverbut = -1;
}
else
this.scrollpbut = false;
if (((this.tleft + this.tw + this.kw - this.h / 2) < x) && (x < (this.tleft + this.tw + this.kw)) && ((this.top + this.h / 4) < y) && (y < (this.top + 3 * this.h / 4)) && (this.scroll < this.maxscroll)) {
this.scrollnbut = true;
this.hover = -1;
this.hoverbut = -1;
}
else
this.scrollnbut = false;
if (((this.tleft + this.tw) < x) && (x < (this.tleft + this.tw + this.kw)) && (this.top < y) && (y < (this.top + this.h)) && (this.nrvalues == 0)) this.emptyhover = true;
if (((this.tleft + this.tw) < x) && (x < (this.tleft + this.tw + this.h / 3)) && (this.top < y) && (y < (this.top + this.h / 3)) && (this.nrvalues == 0)) this.emptyhoverbut = true;
}
this.onClick = function (x, y) {
tmparr1 = new Array ();
tmparr2 = new Array ();
for (i = 0 ; i < this.nrvalues; i++) {
if (this.hover == i) {
// <
if ((this.hoverbut == 0) && (i != 0)) {
for (j = 0 ; j < this.nrvalues; j++) {
tmparr1[j] = this.content[j];
tmparr2[j] = this.errorcontent[j];
}
tmparr1[i - 1] = this.content[i];
tmparr2[i - 1] = this.errorcontent[i];
tmparr1[i] = this.content[i - 1];
tmparr2[i] = this.errorcontent[i - 1];
for (j = 0 ; j < this.nrvalues; j++) {
this.content[j] = tmparr1[j];
this.errorcontent[j] = tmparr2[j];
}
this.changed = true;
this.save();
window.Repaint();
}
// >
if ((this.hoverbut == 1) && (i < this.nrvalues - 1)) {
for (j = 0 ; j < this.nrvalues; j++) {
tmparr1[j] = this.content[j];
tmparr2[j] = this.errorcontent[j];
}
tmparr1[i + 1] = this.content[i];
tmparr2[i + 1] = this.errorcontent[i];
tmparr1[i] = this.content[i + 1];
tmparr2[i] = this.errorcontent[i + 1];
for (j = 0 ; j < this.nrvalues; j++) {
this.content[j] = tmparr1[j];
this.errorcontent[j] = tmparr2[j];
}
this.changed = true;
this.save();
window.Repaint();
}
// +
if (this.hoverbut == 2) {
var popupmenu = window.CreatePopupMenu();
for (j in this.list) {
popupmenu.AppendMenuItem(0, parseInt(j) + 1, this.listlong[j]);
}
menuret = popupmenu.TrackPopupMenu(x, y);
if (menuret != 0) {
this.nrvalues += 1;
for (j = 0 ; j < this.nrvalues; j++) {
if (j <= i) {
tmparr1[j] = this.content[j];
tmparr2[j] = this.errorcontent[j];
}
if (j == (i + 1)) {
tmparr1[j] = this.listlong[menuret - 1];
tmparr2[j] = false;
}
if (j > (i + 1)) {
tmparr1[j] = this.content[j - 1];
tmparr2[j] = this.errorcontent[j - 1];
}
}
for (j = 0 ; j < this.nrvalues; j++) {
this.content[j] = tmparr1[j];
this.errorcontent[j] = tmparr2[j];
}
}
this.changed = true;
this.save();
window.Repaint();
}
// x
if (this.hoverbut == 3) {
this.nrvalues -= 1;
for (j = 0 ; j < this.nrvalues; j++) {
if (j >= i) tmparr1[j] = this.content[j + 1]; else tmparr1[j] = this.content[j];
if (j >= i) tmparr2[j] = this.errorcontent[j + 1]; else tmparr2[j] = this.errorcontent[j];
}
for (j = 0 ; j < this.nrvalues; j++) {
this.content[j] = tmparr1[j];
this.errorcontent[j] = tmparr2[j];
}
this.changed = true;
this.save();
window.Repaint();
}
}
}
// <<
if (this.scrollpbut) {
this.scroll -= this.h;
if (this.scroll < 0) this.scroll = 0;
window.Repaint();
}
// >>
if (this.scrollnbut) {
this.scroll += this.h;
if (this.scroll > this.maxscroll) this.scroll = this.maxscroll;
window.Repaint();
}
// +
if (this.emptyhoverbut) {
var popupmenu = window.CreatePopupMenu();
for (j in this.list) {
popupmenu.AppendMenuItem(0, parseInt(j) + 1, this.listlong[j]);
}
menuret = popupmenu.TrackPopupMenu(x, y);
if (menuret != 0) {
this.nrvalues += 1;
this.content[0] = this.listlong[menuret - 1];
this.changed = true;
this.save();
window.Repaint();
}
}
}
this.loadkeywords = function () {
for (i = 0 ; i < this.nrvalues; i++) {
this.errorcontent[i] = true;
for (j in this.list) {
if (this.content[i] == this.list[j]) {
this.content[i] = this.listlong[j];
this.errorcontent[i] = false;
}
}
}
}
this.load = function () {
idx = metadata.MetaFind(this.tag);
if (idx > metadata.MetaCount) this.nrvalues = 0; else this.nrvalues = metadata.MetaValueCount(idx);
for (n = 0 ; n < this.nrvalues; n++) this.content[n] = metadata.MetaValue(idx, n);
this.loadkeywords();
this.changed = false;
}
this.save = function () {
if (this.changed) {
metadata.MetaRemoveField(this.tag);
writestr = this.content[this.nrvalues - 1];
if (!this.errorcontent[this.nrvalues -1]) {
for (j in this.list) {
if (this.content[this.nrvalues -1] == this.listlong[j]) writestr = this.list[j];
}
}
if (this.nrvalues != 0) idx = metadata.MetaAdd(this.tag, writestr);
for (n = this.nrvalues - 2 ; n > -1; n--) {
writestr = this.content[n];
if (!this.errorcontent[n]) {
for (j in this.list) {
if (this.content[n] == this.listlong[j]) writestr = this.list[j];
}
}
metadata.MetaInsertValue(idx, 0, writestr);
}
g_handle.UpdateFileInfo(metadata);
reload = true;
}
this.changed = false;
}
}
function CheckBox(title, tag, x, y, tw, h) {
this.type = "cb";
this.title = title;
this.tag = tag;
this.content = 0;
this.changed = false;
this.tleft = x;
this.left = x + tw;
this.top = y;
this.tw = tw;
this.h = 0;
this.fh = h;
this.margin = 0.3 * h;
this.colourkw = RGB(229, 229, 229);
this.colourkwb = RGB(0, 0, 0);
this.colourkwh = RGB(255, 255, 200);
this.colourkwbh = RGB(0, 0, 0);
this.colourkws = RGB(229, 229, 229);
this.colourkwsb = RGB(104, 104, 104);
this.colourkwsh = RGB(255, 255, 200);
this.colourkwsbh = RGB(104, 104, 104);
this.colourt = RGB(255, 255, 255);
this.hover = false;
this.gfont = gdi.Font("Arial Unicode MS", this.fh, 0);
inputobjects.push(this);
this.draw = function (gr) {
flagsb = 0x00000001;
nfo = gr.MeasureString("n", this.gfont, 0, 0, 10000, 100, 0);
this.h = nfo.Height;
//title
gr.GdiDrawText(this.title, this.gfont, this.colourt, this.tleft, this.top, this.tw-this.margin, this.h, 0);
//checkbox
if (this.hover) {
colourback = RGB(255, 0, 0);
colour = this.colourkwh;
txt = "";
if (this.content == 0) {
colourback = this.colourkwbh;
colour = this.colourkwh;
txt = "";
}
if (this.content == 1) {
colourback = this.colourkwsbh;
colour = this.colourkwsh;
txt = "✕";
}
}
else {
colourback = RGB(255, 0, 0);
colour = this.colourkw;
txt = "";
if (this.content == 0) {
colourback = this.colourkwb;
colour = this.colourkw;
txt = "";
}
if (this.content == 1) {
colourback = this.colourkwsb;
colour = this.colourkws;
txt = "✕";
}
}
gr.FillEllipse(this.left, this.top, this.h, this.h, colourback);
gr.DrawEllipse(this.left, this.top, this.h, this.h, 1, colour);
gr.GdiDrawText(txt, this.gfont, colour, this.left, this.top, this.h, this.h, flagsb);
}
this.onMove = function (x, y) {
if ((this.left < x) && (x < (this.left + this.h)) && (this.top < y) && (y < (this.top + this.h))) this.hover = true; else this.hover = false;
}
this.onClick = function (x, y) {
if (this.hover) {
if (this.content == 0)
this.content = 1;
else if (this.content == 1)
this.content = 0;
else
this.content = 1;
this.changed = true;
this.save();
window.Repaint();
}
}
this.load = function () {
idx = metadata.MetaFind(this.tag);
if (idx > metadata.MetaCount) this.content = 0; else this.content = metadata.MetaValue(idx, 0);
this.changed = false;
}
this.save = function () {
if (this.changed) {
metadata.MetaSet (this.tag, this.content);
g_handle.UpdateFileInfo(metadata);
reload = true;
}
this.changed = false;
}
}
function RadioBox(title, tag, list, listlong, x, y, tw, rw, h, showall) {
this.type = "rb";
this.title = title;
this.tag = tag;
this.list = list;
this.listlong = listlong;
this.content = 0;
this.contenterror = false;
this.changed = false;
this.tleft = x;
this.left = new Array ();
this.top = y;
this.tw = tw;
this.rw = rw;
this.width = new Array();
this.h = 0;
this.fh = h;
this.margin = 0.3 * h;
this.colourkw = RGB(229, 229, 229);
this.colourkwb = RGB(0, 0, 0);
this.colourkwh = RGB(255, 255, 200);
this.colourkwbh = RGB(0, 0, 0);
this.colourkws = RGB(229, 229, 229);
this.colourkwsb = RGB(104, 104, 104);
this.colourkwsh = RGB(255, 255, 200);
this.colourkwsbh = RGB(104, 104, 104);
this.colourt = RGB(255, 255, 255);
this.showall = showall;
this.hover = -1;
this.gfont = gdi.Font("Arial Unicode MS", this.fh, 0);
this.gfontbut = gdi.Font("Arial Unicode MS", this.fh / 1.3, 0);
inputobjects.push(this);
this.draw = function (gr) {
nfo = gr.MeasureString("n", this.gfont, 0, 0, 10000, 100, 0);
nfod = gr.MeasureString("▾", this.gfontbut, 0, 0, 10000, 100, 0);
this.h = nfo.Height;
//title
gr.GdiDrawText(this.title, this.gfont, this.colourt, this.tleft, this.top, this.tw-this.margin, this.h, 0);
leftstart = this.tleft + this.tw;
if (showall) {
//values
pos = 0;
for (i in this.list) {
this.left[i] = leftstart + pos;
info = gr.MeasureString(this.listlong[i], this.gfont, 0, 0, 10000, 100, 0);
this.width[i] = info.Width;
pos += this.width[i];
if (this.hover == i) {
if (this.content == this.listlong[i]) {
colourback = this.colourkwsbh;
colourl = this.colourkwsh;
colour = this.colourkwsh;
tstsel = true
}
else {
colourback = this.colourkwbh;
colourl = this.colourkwbh;
colour = this.colourkwh;
tstsel = false;
}
}
else {
if (this.content == this.listlong[i]) {
colourback = this.colourkwsb;
colourl = this.colourkws;
colour = this.colourkws;
tstsel = true;
}
else {
colourback = this.colourkwb;
colourl = this.colourkwb;
colour = this.colourkw;
tstsel = false;
}
}
if (tstsel) {
this.left[i] += this.margin;
pos += this.margin;
}
if (this.contenterror) colour = RGB(255, 0, 0);
gr.FillSolidRect(this.left[i] - this.margin, this.top, this.width[i] + 2 * this.margin, this.h, colourback);
gr.DrawRect(this.left[i] - this.margin, this.top, this.width[i] + 2 * this.margin, this.h, 1, colourl);
gr.GdiDrawText(this.listlong[i], this.gfont, colour, this.left[i], this.top, this.width[i], this.h, 0);
pos += nfo.Width + this.margin;
}
}
else {
//value
if (this.hover == -1) colour = this.colourkw; else colour = this.colourkwh;
if (this.contenterror) colour = RGB(255, 0, 0);
if (this.content == "") {
str = "[none]";
colour = RGB(127, 127, 127);
}
else
str = this.content;
gr.GdiDrawText(str, this.gfont, colour, leftstart, this.top, this.rw, this.h, 0);
//menu
if (this.hover != -1) {
gr.DrawLine(leftstart, this.top, leftstart + this.rw, this.top, 1, this.colourkwh);
gr.GdiDrawText("▾", this.gfontbut, this.colourkwh, leftstart + this.rw - this.h / 3 + (this.h / 3 - nfom.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
}
}
}
this.onMove = function (x, y) {
if (showall) {
this.hover = -1;
for (i in this.list) {
if ((this.left[i] < x) && (x < (this.left[i] + this.width[i])) && (this.top < y) && (y < (this.top + this.h))) this.hover = i;
}
}
else {
if (((this.tleft + this.tw) < x) && (x < (this.tleft + this.tw + this. rw)) && (this.top < y) && (y < (this.top + this.h))) this.hover = 0; else this.hover = -1;
}
}
this.onClick = function (x, y) {
if (this.hover != -1) {
if (showall) {
if (this.content == this.listlong[this.hover])
this.content = "";
else
this.content = this.listlong[this.hover];
this.contenterror = false;
this.changed = true;
this.save();
window.Repaint();
}
else {
var popupmenu = window.CreatePopupMenu();
popupmenu.AppendMenuItem(0, 1, "[none]");
for (j in this.list) {
popupmenu.AppendMenuItem(0, parseInt(j) + 2, this.listlong[j]);
}
menuret = popupmenu.TrackPopupMenu(x, y);
if (menuret != 0) {
this.content = this.listlong[menuret - 2];
this.contenterror = false;
this.changed = true;
this.save();
window.Repaint();
}
}
}
}
this.load = function () {
idx = metadata.MetaFind(this.tag);
if (idx > metadata.MetaCount) {
this.content = "";
this.contenterror = false;
}
else {
str = metadata.MetaValue(idx, 0);
this.contenterror = true;
for (i in this.list) {
if (str == this.list[i]) {
this.content = this.listlong[i];
this.contenterror = false;
}
}
if (this.contenterror) this.content = str;
if (str == "") this.contenterror = false;
}
this.changed = false;
}
this.save = function () {
if (this.changed) {
for (i in this.list) {
if (this.content == this.listlong[i]) this.content = this.list[i];
}
metadata.MetaSet (this.tag, this.content);
g_handle.UpdateFileInfo(metadata);
reload = true;
}
this.changed = false;
}
}
function InputRating(title, tag, max, x, y, tw, h) {
this.type = "ra";
this.title = title;
this.tag = tag;
this.max = max;
this.content = 0;
this.contenterror = false;
this.changed = false;
this.tleft = x;
this.left = x + tw;
this.top = y;
this.tw = tw;
this.h = 0;
this.fh = h;
this.margin = 0.3 * h;
this.colourkw = RGB(229, 229, 229);
this.colourkwh = RGB(255, 255, 200);
this.colourt = RGB(255, 255, 255);
this.hover = -1;
this.gfont = gdi.Font("Arial Unicode MS", this.fh, 0);
this.gfontbut = gdi.Font("Arial Unicode MS", this.fh / 1.3, 0);
inputobjects.push(this);
this.draw = function (gr) {
nfo = gr.MeasureString("n", this.gfont, 0, 0, 10000, 100, 0);
nfom = gr.MeasureString("−", this.gfontbut, 0, 0, 10000, 100, 0);
this.h = nfo.Height;
//title
gr.GdiDrawText(this.title, this.gfont, this.colourt, this.tleft, this.top, this.tw-this.margin, this.h, 0);
//rating
for (i = 1; i <= this.max; i++) {
if (i <= this.content) {
str = "★";
if (this.hover == i) colour = this.colourkwh; else colour = this.colourkw;
}
else {
str = "☆"
if (this.hover == i) colour = this.colourkwh; else colour = RGB(127, 127, 127);
}
if (this.contenterror) colour = RGB(255, 0, 0);
gr.GdiDrawText(str, this.gfont, colour, this.left + (i - 1) * this.h, this.top, this.h, this.h, 0);
}
//menu
if (this.hover != -1) {
gr.DrawLine(this.left, this.top, this.left + this.max * this.h, this.top, 1, this.colourkwh);
if (this.hover == 0) {
gr.DrawRect(this.left + this.max * this.h - this.h / 3, this.top, this.h / 3, this.h / 3, 1, this.colourkwh);
colour = this.colourkwh;
}
else
colour = this.colourkw;
gr.GdiDrawText("−", this.gfontbut, colour, this.left + this.max * this.h - this.h / 3 + (this.h / 3 - nfom.width) / 2, this.top - 0.22 * this.h, this.h / 3, this.h, 0);
}
}
this.onMove = function (x, y) {
this.hover = -1;
for (i = 0; i < this.max; i++) {
if (((this.left + i * this.h) < x) && (x < (this.left + (i + 1) * this.h)) && (this.top < y) && (y < (this.top + this.h))) this.hover = i + 1;
}
if (((this.left + this.max * this.h - this.h / 3) < x) && (x < (this.left + this.max * this.h)) && (this.top < y) && (y < (this.top + this.h))) this.hover = 0;
}
this.onClick = function (x, y) {
if (this.hover >= 0) {
this.content = this.hover;
this.contenterror = false;
this.changed = true;
this.save();
window.Repaint();
}
}
this.load = function () {
idx = metadata.MetaFind(this.tag);
if (idx > metadata.MetaCount)
this.content = 0;
else {
str = metadata.MetaValue(idx, 0);
this.contenterror = true;
for (i = 0; i <= this.max; i ++) {
if (str == i) {
this.content = i;
this.contenterror = false;
}
if (this.contenterror) this.content = 0;
}
}
this.changed = false;
}
this.save = function () {
if (this.changed) {
metadata.MetaSet (this.tag, this.content);
g_handle.UpdateFileInfo(metadata);
reload = true;
}
this.changed = false;
}
}
function inputobjectsDraw(gr) {
for (i in inputobjects) {
inputobjects[i].draw(gr);
}
}
function inputobjectsLoad() {
if ((g_handle.Path != fpath) || (reload)) {
reload = false;
fpath = g_handle.Path;
for (i in inputobjects) {
inputobjects[i].load();
}
}
}
function inputobjectsSave() {
for (i in inputobjects) {
inputobjects[i].save();
}
}
function RGB(r, g, b) {
return (0xff000000 | (r << 16) | (g << 8) | (b));
}
// --- APPLICATION START
var g_handle = fb.GetFocusItem();
var metadata = g_handle.GetFileInfo();
reload = true;
fpath = ""
function on_mouse_move(x, y) {
for (i in inputobjects) {
inputobjects[i].onMove(x, y);
}
window.Repaint();
}
function on_mouse_lbtn_down(x, y) {
for (i in inputobjects) {
inputobjects[i].onClick(x,y);
}
window.Repaint();
}
function on_focus(is_focused) {
inputobjectsSave();
window.Repaint();
}
function on_item_focus_change() {
inputobjectsSave();
g_handle = fb.GetFocusItem();
metadata = g_handle.GetFileInfo();
reload = true;
window.Repaint();
}
function on_paint(gr) {
gr.FillSolidRect(0, 0, window.Width, window.Height, RGB(0,0,0));
inputobjectsLoad();
inputobjectsDraw(gr);
}
//Relates to: Inputbox
function on_key_down(vkey) {
key = vkey;
ins = "";
tb = null;
//ctrl, alt?
if (!utils.IsKeyPressed(17) & !utils.IsKeyPressed(18)){
for (i in inputobjects) {
tb = inputobjects[i];
if ((tb.type == "ib") && tb.active) break;
}
if ((tb.type == "ib") && tb.active) {
if (!tb.special) {
//0-9
if (47<key && key<58 && !utils.IsKeyPressed(16)) {
ins = String.fromCharCode(key);
}
//A-Z
if (64<key && key<91) {
if (!utils.IsKeyPressed(16)) key += 32
ins = String.fromCharCode(key);
}
//simple characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 189: ins = "-"; break;
case 187: ins = "="; break;
case 219: ins = "["; break;
case 221: ins = "]"; break;
case 186: ins = ";"; break;
case 220: ins = "\\"; break;
case 226: ins = "\\"; break;
case 188: ins = ","; break;
case 190: ins = "."; break;
case 191: ins = "/"; break;
}
}
//simple shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 49: ins = "!"; break;
case 50: ins = "@"; break;
case 51: ins = "#"; break;
case 52: ins = "$"; break;
case 53: ins = "%"; break;
case 55: ins = "&&"; break;
case 56: ins = "*"; break;
case 57: ins = "("; break;
case 48: ins = ")"; break;
case 189: ins = "_"; break;
case 187: ins = "+"; break;
case 219: ins = "{"; break;
case 221: ins = "}"; break;
case 186: ins = ":"; break;
case 220: ins = "|"; break;
case 226: ins = "|"; break;
case 188: ins = "<"; break;
case 190: ins = ">"; break;
case 191: ins = "?"; break;
}
}
//special characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 192: tb.special = true; tb.specialchar = "`"; break;
case 222: tb.special = true; tb.specialchar = "'"; break;
}
}
//special shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 192: tb.special = true; tb.specialchar = "~"; break;
case 54: tb.special = true; tb.specialchar = "^"; break;
case 222: tb.special = true; tb.specialchar = "\""; break;
}
}
//space
if (key == 32){
ins = String.fromCharCode(key);
}
}
else {
ins0 = tb.specialchar;
//special characters
switch (key){
case 65:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ã" : ins = "ã"; key = null; break;
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "À" : ins = "à"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Â" : ins = "â"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ä" : ins = "ä"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Á" : ins = "á"; key = null; break;
}
break;
case 67:
switch (tb.specialchar){
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ç" : ins = "ç"; key = null; break;
}
break;
case 69:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "È" : ins = "è"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ê" : ins = "ê"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ë" : ins = "ë"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "É" : ins = "é"; key = null; break;
}
break;
case 73:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ì" : ins = "ì"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Î" : ins = "î"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ï" : ins = "ï"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "í" : ins = "í"; key = null; break;
}
break;
case 78:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ñ" : ins = "ñ"; key = null; break;
}
break;
case 79:
switch (tb.specialchar){
case "~": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Õ" : ins = "õ"; key = null; break;
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ò" : ins = "ò"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ô" : ins = "ô"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ö" : ins = "ö"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ó" : ins = "ó"; key = null; break;
}
break;
case 83:
switch (tb.specialchar){
case "\"": if (!utils.IsKeyPressed(16)) {ins0 = ""; ins = "ß"; key = null}; break;
}
break;
case 85:
switch (tb.specialchar){
case "`": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ù" : ins = "ù"; key = null; break;
case "^": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Û" : ins = "û"; key = null; break;
case "\"": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ü" : ins = "ü"; key = null; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ú" : ins = "ú"; key = null; break;
}
break;
case 89:
switch (tb.specialchar){
case "\"": if (!utils.IsKeyPressed(16)) {ins0 = ""; ins = "ÿ"; key = null}; break;
case "'": ins0 = ""; (utils.IsKeyPressed(16)) ? ins = "Ý" : ins = "ý"; key = null; break;
}
break;
}
//0-9
if (47<key && key<58 && !utils.IsKeyPressed(16)) {
ins = String.fromCharCode(key);
}
//A-Z
if (64<key && key<91) {
if (!utils.IsKeyPressed(16)) key += 32
ins = String.fromCharCode(key);
}
//simple characters
if (!utils.IsKeyPressed(16)) {
switch (key){
case 189: ins = "-"; break;
case 187: ins = "="; break;
case 219: ins = "["; break;
case 221: ins = "]"; break;
case 186: ins = ";"; break;
case 220: ins = "\\"; break;
case 226: ins = "\\"; break;
case 188: ins = ","; break;
case 190: ins = "."; break;
case 191: ins = "/"; break;
}
}
//simple shift characters
if (utils.IsKeyPressed(16)) {
switch (key){
case 49: ins = "!"; break;
case 50: ins = "@"; break;
case 51: ins = "#"; break;
case 52: ins = "$"; break;
case 53: ins = "%"; break;
case 55: ins = "&&"; break;
case 56: ins = "*"; break;
case 57: ins = "("; break;
case 48: ins = ")"; break;
case 189: ins = "_"; break;
case 187: ins = "+"; break;
case 219: ins = "{"; break;
case 221: ins = "}"; break;
case 186: ins = ":"; break;
case 220: ins = "|"; break;
case 226: ins = "|"; break;
case 188: ins = "<"; break;
case 190: ins = ">"; break;
case 191: ins = "?"; break;
}
}
tmp = ins
ins = ins0 + tmp;
tb.special = false;
tb.specialchar = "";
}
//left
if (key == 37){
if (tb.cursor != 0) tb.cursor -= 1;
}
//right
if (key == 39){
if (tb.cursor != tb.contentedit.length) tb.cursor += 1;
}
//home
if (key == 36){
tb.cursor = 0;
}
//end
if (key == 35){
tb.cursor = tb.contentedit.length;
}
//backspace
if (key == 8){
if (tb.cursor != 0){
str2 = tb.contentedit.slice(tb.cursor);
tb.cursor -= 1;
str1 = tb.contentedit.slice (0, tb.cursor);
tb.contentedit = str1 + str2
}
}
//delete
if (key == 46){
if (tb.cursor != tb.content.length){
str2 = tb.contentedit.slice(tb.cursor + 1);
str1 = tb.contentedit.slice (0, tb.cursor);
tb.contentedit = str1 + str2
}
}
//enter
if (key == 13) {
inputobjectsSave();
}
//esc
if (key == 27) {
tb.contentedit = tb.contenteditbak;
tb.cursor = tb.contentedit.length;
}
str1 = tb.contentedit.slice(0, tb.cursor);
str2 = tb.contentedit.slice(tb.cursor);
tb.contentedit = str1 + ins + str2;
tb.cursor += ins.length;
window.Repaint();
}
}
}
var testshort = new Array ("t1", "t2", "t3", "t4", "t5");
var testlong = new Array ("test 1", "test 2", "test 3", "test 4", "test 5");
// InputBox (Title, Tag, Multivalue, x, y, Title width, Text box width, Font size)
var ib_test1 = new InputBox("Test 1", "test1", true, 10, 10, 100, 500, 20);
var ib_test2 = new InputBox("Test 2", "test2", true, 10, 40, 100, 500, 20);
var ib_test3 = new InputBox("Test 3", "test3", true, 10, 70, 100, 500, 20);
var ib_test4 = new InputBox("Test 4", "test4", true, 10, 100, 100, 500, 20);
// Keywords (Title, Tag, List of values, List of descriptions, x, y, Title width, Max width of values, Font size)
var kw_test = new Keywords("Test 1", "test1", testshort, testlong, 10, 130, 100, 500, 20);
// CheckBox(Title, Tag, x, y, Title width, Font size)
var cb_test = new CheckBox("Test 2", "test2", 10, 160, 100, 20);
// RadioBox(Title, Tag, List of values, List of descriptions, x, y, Title width, Value width [if not show all], Font size, Show all)
var rb_test1 = new RadioBox("Test 3", "test3", testshort, testlong, 10, 190, 100, 100, 20, true);
var rb_test2 = new RadioBox("Test 3", "test3", testshort, testlong, 10, 220, 100, 100, 20, false);
// InputRating (Title, Tag, Maximum rating, x, y, Title width, Font size)
var ra_test = new InputRating("Test 4", "test4", 5, 10, 250, 100, 20) ;