From ccaa4513138f620fff0729255ed8d1c26d9cf56b Mon Sep 17 00:00:00 2001 From: "Mark Aherne (Faerdan)" Date: Wed, 28 Aug 2013 17:13:25 +0100 Subject: [PATCH 1/2] Added Nano UI Chemistry Dispenser. Fixed UI update issue with non auto-updating UIs. Misc tweaks for CSS and JS for UI styling. --- code/modules/client/client procs.dm | 1 + code/modules/nano/nanomanager.dm | 2 +- code/modules/nano/nanoui.dm | 3 + code/modules/reagents/Chemistry-Machinery.dm | 128 +++++++++---------- nano/css/shared.css | 12 ++ nano/js/nano_base_helpers.js | 21 ++- nano/js/nano_update.js | 9 +- nano/templates/chem_dispenser.tmpl | 59 +++++++++ 8 files changed, 162 insertions(+), 73 deletions(-) create mode 100644 nano/templates/chem_dispenser.tmpl diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 5f09128021..15a8b47bdd 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -249,6 +249,7 @@ 'nano/js/nano_base_helpers.js', 'nano/css/shared.css', 'nano/css/icons.css', + 'nano/templates/chem_dispenser.tmpl', 'nano/templates/cryo.tmpl', 'nano/images/uiBackground.png', 'nano/images/uiIcons16.png', diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index c3edfa04ea..45bb25f115 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -29,7 +29,7 @@ for (var/ui_key in open_uis[src_object_key]) for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) if(ui && ui.src_object && ui.user) - ui.process() + ui.process(1) update_count++ return update_count diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 565295d3f9..15dc1feec9 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -188,7 +188,10 @@ return if (src_object.Topic(href, href_list)) + usr << "Update after Topic" nanomanager.update_uis(src_object) // update all UIs attached to src_object + else + usr << "Don't update after Topic" /datum/nanoui/proc/get_footer() var/scriptsContent = "" diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 9435fee6a0..a85a19de19 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -3,7 +3,7 @@ #define GAS 3 /obj/machinery/chem_dispenser - name = "chem dispenser" + name = "Chem Dispenser" density = 1 anchored = 1 icon = 'icons/obj/chemical.dmi' @@ -65,74 +65,81 @@ del(src) return -/obj/machinery/chem_dispenser/proc/updateWindow(mob/user as mob) - winset(user, "chemdispenser.energy", "text=\"Energy: [src.energy]\"") - winset(user, "chemdispenser.amount", "text=\"Amount: [src.amount]\"") +/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main") + if(stat & (BROKEN|NOPOWER)) return + if(user.stat || user.restrained()) return + + var/data[0] + + data["amount"] = amount + data["energy"] = energy + + data["isBeakerLoaded"] = beaker ? 1 : 0 + + + var beakerContents[0] + var beakerCurrentVolume = 0 + if(beaker && beaker:reagents && beaker:reagents.reagent_list.len) + for(var/datum/reagent/R in beaker:reagents.reagent_list) + beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + beakerCurrentVolume += R.volume + data["beakerContents"] = beakerContents + if (beaker) - winset(user, "chemdispenser.eject", "text=\"Eject beaker\"") + data["beakerCurrentVolume"] = beakerCurrentVolume + data["beakerMaxVolume"] = beaker:volume else - winset(user, "chemdispenser.eject", "text=\"\[Insert beaker\]\"") -/obj/machinery/chem_dispenser/proc/initWindow(mob/user as mob) - var/i = 0 - var/list/nameparams = params2list(winget(user, "chemdispenser_reagents.template_name", "pos;size;type;image;image-mode")) - var/list/buttonparams = params2list(winget(user, "chemdispenser_reagents.template_dispense", "pos;size;type;image;image-mode;text;is-flat")) - for(var/re in dispensable_reagents) + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var chemicals[0] + for (var/re in dispensable_reagents) var/datum/reagent/temp = chemical_reagents_list[re] if(temp) - var/list/newparams1 = nameparams.Copy() - var/list/newparams2 = buttonparams.Copy() - var/posy = 8 + 40 * i - newparams1["pos"] = text("8,[posy]") - newparams2["pos"] = text("248,[posy]") - newparams1["parent"] = "chemdispenser_reagents" - newparams2["parent"] = "chemdispenser_reagents" - newparams1["text"] = temp.name - newparams2["command"] = text("skincmd \"chemdispenser;[temp.id]\"") - winset(user, "chemdispenser_reagent_name[i]", list2params(newparams1)) - winset(user, "chemdispenser_reagent_dispense[i]", list2params(newparams2)) - i++ - winset(user, "chemdispenser_reagents", "size=340x[8 + 40 * i]") + chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list... + data["chemicals"] = chemicals -/obj/machinery/chem_dispenser/SkinCmd(mob/user as mob, var/data as text) - if(stat & (BROKEN|NOPOWER)) return - if(usr.stat || usr.restrained()) return - if(!in_range(src, usr)) return + //user << list2json(data) - usr.set_machine(src) - - if (data == "amountc") - var/num = input("Enter desired output amount", "Amount", "30") as num - if (num) - amount = text2num(num) - else if (data == "eject") - if (src.beaker) - var/obj/item/weapon/reagent_containers/glass/B = src.beaker - B.loc = src.loc - src.beaker = null - else if (copytext(data, 1, 7) == "amount") - if (text2num(copytext(data, 7))) - amount = text2num(copytext(data, 7)) + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) + if (!ui) + ui = new(user, src, ui_key, "chem_dispenser.tmpl", "Chem Dispenser 5000", 370, 585) + // When the UI is first opened this is the data it will use + ui.set_initial_data(data) + ui.open() else - if (dispensable_reagents.Find(data) && beaker != null) + // The UI is already open so push the new data to it + ui.push_data(data) + return + +/obj/machinery/chem_dispenser/Topic(href, href_list) + if(stat & (NOPOWER|BROKEN)) + return 0 // don't update UIs attached to this object + + if(href_list["amount"]) + amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 + if (amount < 0) // Since the user can actually type the commands himself, some sanity checking + amount = 0 + if (amount > 100) + amount = 100 + + if(href_list["dispense"]) + if (dispensable_reagents.Find(href_list["dispense"]) && beaker != null) var/obj/item/weapon/reagent_containers/glass/B = src.beaker var/datum/reagents/R = B.reagents var/space = R.maximum_volume - R.total_volume - R.add_reagent(data, min(amount, energy * 10, space)) + R.add_reagent(href_list["dispense"], min(amount, energy * 10, space)) energy = max(energy - min(amount, energy * 10, space) / 10, 0) - amount = round(amount, 10) // Chem dispenser doesnt really have that much prescion - if (amount < 0) // Since the user can actually type the commands himself, some sanity checking - amount = 0 - if (amount > 100) - amount = 100 + if(href_list["ejectBeaker"]) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.loc = loc + beaker = null - for(var/mob/player in player_list) - if (player.machine == src && player.client) - updateWindow(player) - - src.add_fingerprint(usr) - return + add_fingerprint(usr) + return 1 // update UIs attached to this object /obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/reagent_containers/glass/B as obj, var/mob/user as mob) if(isrobot(user)) @@ -149,9 +156,7 @@ user.drop_item() B.loc = src user << "You add the beaker to the machine!" - for(var/mob/player in player_list) - if (player.machine == src && player.client) - updateWindow(player) + nanomanager.update_uis(src) // update all UIs attached to src /obj/machinery/chem_dispenser/attack_ai(mob/user as mob) return src.attack_hand(user) @@ -162,13 +167,8 @@ /obj/machinery/chem_dispenser/attack_hand(mob/user as mob) if(stat & BROKEN) return - user.set_machine(src) - initWindow(user) - updateWindow(user) - winshow(user, "chemdispenser", 1) - user.skincmds["chemdispenser"] = src - return + ui_interact(user) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/nano/css/shared.css b/nano/css/shared.css index b8c75eac04..2cfb8b466c 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -258,6 +258,7 @@ div.notice { float: left; width: 30%; + color: #e9c183; } .itemContent @@ -382,4 +383,15 @@ div.notice color: #ffffff; background: #999999; border-color: #666666; +} + +.fixedLeft +{ + width: 110px; + float: left; +} + +.floatRight +{ + float: right; } \ No newline at end of file diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js index d1c4e35880..f46c5828f3 100644 --- a/nano/js/nano_base_helpers.js +++ b/nano/js/nano_base_helpers.js @@ -15,20 +15,31 @@ NanoBaseHelpers = function () { $.views.helpers({ // Generate a Byond link - link: function( text, icon, parameters, status ) { + link: function( text, icon, parameters, status, elementClass, elementId) { var iconHtml = ''; - if (typeof icon != 'undefined' && icon != null) + if (typeof icon != 'undefined' && icon) { iconHtml = '
'; } - if (typeof status != 'undefined' && status != null) + if (typeof elementClass == 'undefined' || !elementClass) { - return ''; + elementClass = ''; } - return ''; + var elementIdHtml = ''; + if (typeof elementId != 'undefined' && elementId) + { + elementIdHtml = 'id="' + elementId + '"'; + } + + if (typeof status != 'undefined' && status) + { + return ''; + } + + return ''; }, // Round a number to the nearest integer round: function(number) { diff --git a/nano/js/nano_update.js b/nano/js/nano_update.js index 1034ac8979..ff8bf7b27b 100644 --- a/nano/js/nano_update.js +++ b/nano/js/nano_update.js @@ -101,9 +101,12 @@ NanoUpdate = function () $('body').oneTime(300, 'enableClick', function () { _canClick = true; }); - $(this).oneTime(300, 'linkPending', function () { - $(this).addClass('linkPending'); - }); + if (updateData['ui']['status'] == 2) + { + $(this).oneTime(300, 'linkPending', function () { + $(this).addClass('linkPending'); + }); + } window.location.href = href; } }); diff --git a/nano/templates/chem_dispenser.tmpl b/nano/templates/chem_dispenser.tmpl new file mode 100644 index 0000000000..4add36586e --- /dev/null +++ b/nano/templates/chem_dispenser.tmpl @@ -0,0 +1,59 @@ +
+
+ Energy: +
+
+ {^{:energy}} +
+
+ +
+
+ Dispense: +
+
+ {^{:~link('5', 'gear', {'amount' : 5}, (amount == 5) ? 'selected' : null)}} + {^{:~link('10', 'gear', {'amount' : 10}, (amount == 10) ? 'selected' : null)}} + {^{:~link('20', 'gear', {'amount' : 20}, (amount == 20) ? 'selected' : null)}} + {^{:~link('30', 'gear', {'amount' : 30}, (amount == 30) ? 'selected' : null)}} + {^{:~link('50', 'gear', {'amount' : 50}, (amount == 50) ? 'selected' : null)}} +
+
+
 
+
+
+ Chemical Dispenser +
+
+
+
+ {^{for chemicals}} + {^{:~link(title, 'circle-arrow-s', commands, null, 'fixedLeft')}} + {{/for}} +
+
+
 
+
+
+ Beaker Contents +
+
+ {^{:~link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled', 'floatRight')}} +
+
+
+
+
+ {^{if isBeakerLoaded}} + Volume: {^{:beakerCurrentVolume}} / {^{:beakerMaxVolume}}
+ {^{for beakerContents}} + {^{:volume}} units of {^{:name}}
+ {{else}} + Beaker is empty + {{/for}} + {{else}} + No beaker loaded + {{/if}} +
+
+
\ No newline at end of file From 9cb0b79d7849aeb67e64fc2e973ebb5296893226 Mon Sep 17 00:00:00 2001 From: "Mark Aherne (Faerdan)" Date: Wed, 28 Aug 2013 22:20:13 +0100 Subject: [PATCH 2/2] Fixed issue with links/buttons not working until first update. --- code/modules/nano/nanoui.dm | 4 +- nano/js/nano_update.js | 88 +++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 15dc1feec9..3ea42ae45a 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -185,13 +185,11 @@ /datum/nanoui/Topic(href, href_list) update_status(0) // update the status if (status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user + //usr << "Not interaction or wrong usr" return if (src_object.Topic(href, href_list)) - usr << "Update after Topic" nanomanager.update_uis(src_object) // update all UIs attached to src_object - else - usr << "Don't update after Topic" /datum/nanoui/proc/get_footer() var/scriptsContent = "" diff --git a/nano/js/nano_update.js b/nano/js/nano_update.js index ff8bf7b27b..cd24d20eef 100644 --- a/nano/js/nano_update.js +++ b/nano/js/nano_update.js @@ -13,6 +13,49 @@ NanoUpdate = function () var init = function () { + NanoUpdate.addAfterUpdateCallback(function (updateData) { + var uiStatusClass; + if (updateData['ui']['status'] == 2) + { + uiStatusClass = 'icon24 uiStatusGood'; + $('.linkActive').removeClass('inactive'); + } + else if (updateData['ui']['status'] == 1) + { + uiStatusClass = 'icon24 uiStatusAverage'; + $('.linkActive').addClass('inactive'); + } + else + { + uiStatusClass = 'icon24 uiStatusBad' + $('.linkActive').addClass('inactive'); + } + $('#uiStatusIcon').attr('class', uiStatusClass); + + $('.linkActive').stopTime('linkPending'); + $('.linkActive').removeClass('linkPending'); + + $('.linkActive').off('click'); + $('.linkActive').on('click', function (event) { + event.preventDefault(); + var href = $(this).data('href'); + if (href != null && _canClick) + { + _canClick = false; + $('body').oneTime(300, 'enableClick', function () { + _canClick = true; + }); + if (updateData['ui']['status'] == 2) + { + $(this).oneTime(300, 'linkPending', function () { + $(this).addClass('linkPending'); + }); + } + window.location.href = href; + } + }); + }); + var body = $('body'); // We store data in the body tag, it's as good a place as any _data = body.data('initialData'); @@ -57,6 +100,8 @@ NanoUpdate = function () { observedDataUpdateRecursive(_earlyUpdateData, _data); } + + executeCallbacks(_afterUpdateCallbacks, _data); //alert($("#mainTemplate").html()); } @@ -68,49 +113,6 @@ NanoUpdate = function () }); } } - - NanoUpdate.addAfterUpdateCallback(function (updateData) { - var uiStatusClass; - if (updateData['ui']['status'] == 2) - { - uiStatusClass = 'icon24 uiStatusGood'; - $('.linkActive').removeClass('inactive'); - } - else if (updateData['ui']['status'] == 1) - { - uiStatusClass = 'icon24 uiStatusAverage'; - $('.linkActive').addClass('inactive'); - } - else - { - uiStatusClass = 'icon24 uiStatusBad' - $('.linkActive').addClass('inactive'); - } - $('#uiStatusIcon').attr('class', uiStatusClass); - - $('.linkActive').stopTime('linkPending'); - $('.linkActive').removeClass('linkPending'); - - $('.linkActive').off('click'); - $('.linkActive').on('click', function (event) { - event.preventDefault(); - var href = $(this).data('href'); - if (href != null && _canClick) - { - _canClick = false; - $('body').oneTime(300, 'enableClick', function () { - _canClick = true; - }); - if (updateData['ui']['status'] == 2) - { - $(this).oneTime(300, 'linkPending', function () { - $(this).addClass('linkPending'); - }); - } - window.location.href = href; - } - }); - }); }; // Receive update data from the server