Adding graphics in a specific location (GUI) (SOLVED)

Today I created 3d models of the first three rooms in my game...

Main character's living room:

... and I've been playing around with how to implement them into the game.
I've decided what I want to do (and of course it's something I have no idea how to, or if it's actually possible?).

Is it possible to show a picture under over the inventory pane?
Using the same width as the other panes?

(sorry for reusing an old screenie, I CBA to make a new one)
It would be super extra mega cool if I could put the picture inside a fancy pane with rounded corners, like the "status" or "inventory"... but I'm afraid to even ask.

Edit:
Something like this? Possible, yes?


I was also interested in this question. I wanted to have a map and picture frame in the same game. I guess you could add an image to the custom status pane (even though you're already using it), but that's an inelegant solution. Javascript anyone?


If you want this to be there when a new or saved game loads, add this to your room's "Before entering room" script:

msg ("<img id='pane-pic1' style='display:none;' src='http://whywelovemusic.com/quest/anx.png' />")
JS.eval("$('#pane-pic1').insertBefore($('#inventoryLabel')).show().width('100%');")


If you want to get fancy...

You could PUFF it in (there are other animations, too):

SetTimeout(2){
  msg ("<img id='pane-pic1' style='display:none;' src='http://whywelovemusic.com/quest/anx.png' />")
  JS.eval ("$('#pane-pic1').insertBefore($('#inventoryLabel')).width('100%').toggle('puff');")
}


I think I got this.

No internet here, so I'm on my mobile again and can't easily test (but can look through the source still)

(function () {
  $('<h3 id="pictureLabel" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top"><span class="ui-icon ui-icon-triangle-1-s"></span><span class="accordion-header-text">Picture</span></h3><div id="pictureAccordion" class="ui-accordion-content-active ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"></div>').insertBefore("#inventoryLabel");
  var picturediv = $("#pictureAccordion");
  setPanelHeight = function() {
    $("#gamePanel").hide();
    $("#gamePanelSpacer").hide();
    picturediv.empty();
    var h = 0;
    $("#gamePanel img").each(function (i) {
      $(this).appendTo(picturediv);
      $(this).css("width", "100%");
      h += $(this).outerHeight() + 2;
    });
    picturediv.animate({height: h}, 100);
  };
})();

If I got it right, that should cause the image specified by the room's picture property to load in a pane above the inventory pane, instead of in the standard location.

I also figured out a way to get it so that when you move from one room with a picture to another, the old one scrolls out and the new one comes in, in a direction determined by the compass direction. But that's a little silly, and quite a lot of code :p


I also figured out a way to get it so that when you move from one room with a picture to another, the old one scrolls out and the new one comes in, in a direction determined by the compass direction. But that's a little silly, and quite a lot of code

That is cool. It may be silly, too, but so be it.


Wow, I really though it would be a super difficult task and you did it in 2 lines of code K.V.! Thanks a bunch!!!!1!!!11

On another note:
On the subway ride home I checked the forum and noticed that highly annoying hotlink picture above... do you still see those (i tried to alter the .htacess file on my web space from my phone) or can you see the actual pictures now?

Again; super thanks to all of you for your quick replies!


Again, thanks K.V.!!
It works perfectly!


To change the picture:

JS.eval("$('#pane-pic1').attr('src', 'https://i.imgur.com/mBf7TBeb.png');")

To remove an image completely:

JS.eval("$('#pane-pic1').remove();")

Ah yes. Exactly what I needed!

Soon you need to start charging me by the hour. Or by the line of code :)

Thank you K.V.!


To round the edges:

JS.eval("$('#pane-pic1').css('border-radius','5px');")

It's looking great!!


Impressive KV! I played around with it in my game and it's working great. Now I can display both a map and room picture. Thank you!

I don't get how simple it was to create the additional pane just by giving it an ID and printing it? That was too easy! It's also strange how the print script has to precede the JS.eval script.


I have a different room picture in each room. But when traveling quickly from one room to the next, the changing room pictures and their differing heights cause the compass to bounce up and down. To remedy this, I added a couple of CSS properties to the end of KV's original second line:

JS.eval("$('#pane-pic1').insertBefore($('#inventoryLabel')).show().width('100%').css({'min-height': '150px', 'max-height': '150px'});")

That sets the minimum and maximum heights of the room pic to the same absolute value of 150px or whatever you like.


@mrangel
I haven't looked into your way of doing it yet but I do appreciate you taking the time and I'll check it out in a bit. Thanks for replying!

@Dcoder
I haven't had any problems like that but if it happens, I now know how to solve it. Thanks!


My version is pretty much the same as KV's I think; except instead of printing a new <img/> tag I took the one already used by the "room picture" system and moved it into the sidebar. Looking at it now, that code could have been a whole lot cleaner. (I also have no idea if it works; I was on my phone when I wrote it, so had to just skim-read the relevant bits of playercore.js and then write code off the top of my head)

@Dcoder

Now I can display both a map and room picture.

And now you've got me thinking that it shouldn't be that hard to move the picture and the map into sidebar panes, and let the player "maximise" whichever they want back up to usual size.


And now you've got me thinking that it shouldn't be that hard to move the picture and the map into sidebar panes, and let the
player "maximise" whichever they want back up to usual size.

That would be extremely useful!


That would be extremely useful!

Here's a step in the right direction:

Hidden: Various things I tried which may be useful to other people
$('<h3 id="mapLabel" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top"><span class="ui-icon ui-icon-triangle-1-s"></span><span class="accordion-header-text">Map</span></h3><div id="mapAccordion" class="ui-accordion-content-active ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"></div>').insertBefore("#inventoryLabel");
var size = $("#mapAccordion").innerWidth();
$("#gridCanvas").width(size).height(size).appendTo("#mapAccordion");
paper.view.viewSize.width = size;
paper.view.viewSize.height = size;
$("#gridPanel").hide();

Tried out in the browser's javascript console (as none of my test games have the map enabled), it moves the map of a functional game into the sidebar, and everything seems to work fine.

NOTE: The map pane looks like the other panes, but can't be expanded/collapsed. That's because multiOpenAccordion doesn't allow you to add panes once it's been created.

Normally you'd unregister the accordion widget and create it again, but this doesn't work due to a known bug in the MultiOpenAccordion UI widget, which a fix has been submitted for but not yet accepted. This is from the widget's bugtracker; I haven't actually tested it. In quest-5.7.2/Prototypes/jsrunner/ui/jquery.multi-open-accordion-1.5.3.js line 83, destroy should be _destroy. If that works, you could then do:

$("#gamePanesRunning").multiOpenAccordion("destroy");
$('<h3 id="mapLabel"><span>Map</span></h3><div id="mapAccordion"></div>').insertBefore("#inventoryLabel");
var size = $("#mapAccordion").innerWidth();
$("#gridCanvas").width(size).height(size).appendTo("#mapAccordion");
paper.view.viewSize.width = size;
paper.view.viewSize.height = size;
$("#gridPanel").hide();
$("#gamePanesRunning").multiOpenAccordion();

...

I'm trying to find a workaround for this book, but it's being a bit flaky.


Finally, the code you were looking for:

It works, but…

$('<h3 id="mapLabel" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top"><span class="ui-icon ui-icon-triangle-1-s"></span><span class="accordion-header-text">Map</span></h3><div id="mapAccordion" class="ui-accordion-content-active ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"></div>').insertBefore("#inventoryLabel");
var size = $("#mapAccordion").innerWidth();
$("#gridCanvas").width(size).height(size).appendTo("#mapAccordion");
paper.view.viewSize.width = size;
paper.view.viewSize.height = size;
$("#gridPanel").hide();
$("#mapLabel").bind("click", $._data($("#inventoryLabel")[0]).events['click'][0]['handler']);
$("#mapLabel").bind("mouseover", $._data($("#inventoryLabel")[0]).events['mouseover'][0]['handler']);
$("#mapLabel").bind("mouseout", $._data($("#inventoryLabel")[0]).events['mouseout'][0]['handler']);

(I've given up on working around the bugs in multiOpenAccordion, and manually copied the event handler functions out of jQuery's internal data structure onto my new pane)
Note that you could do the same trick for the picture code I posted above, to let the player show/hide the picture like all the other sidebar panes.


(also noting that if you do that after the grid has initially been displayed, it won't scroll the map, so the initial room will be off the right hand side of the map. You need to call Grid_Redraw() to get the player's position to scroll back to the center)


it shouldn't be that hard to move the picture and the map into sidebar panes, and let the
player "maximise" whichever they want back up to usual size.

OK, I'm doing this :D
But also doing campNanoWrimo, and trying to get a novel released by the end of the month, and do all the promotion for it. So must force myself to stop coding now, and work on those. Javascript hacking will resume either when I met all my goals for today, or in the morning.


@mrangel
lol!
Go work on your novel man! Stop spoiling me :)


@mrangel
Yes, go pay the bills first!


You can play with this while waiting on mrangel:

  <!-- You must add SetupMapWindow to your User Interface Initialisation script!!! -->

  <function name="SetupMapWindow"><![CDATA[
    JS.eval ("$('#gamePanelSpacer').height(0);")
    msg ("<div id='mapHolder' style='display:none;'></div>")
    JS.eval ("$('#gridPanel').appendTo($('#mapHolder')).css({'left':'63%','position':'absolute'});var mh = $('#mapHolder');mh.dialog({height: 400, width: 700,close: function(){mh.dialog('close');$('#txtCommandDiv').focus();}});mh.dialog('option', 'title', 'Map');mh.dialog('open');$('.ui-dialog').css('position', 'fixed');openMap = function(){mh.dialog('open');};")
    JS.setCommands ("SHOW MAP")
  ]]></function>
	
  <command name="view_map_command">
    <pattern>view map;open map;map;show map</pattern>
    <script>
      JS.openMap ()
      game.notarealturn = true
    </script>
  </command>

...and here is a paste-able version of mrangel's current code:

JS.eval ("$('<h3 id=\"mapLabel\" class=\"ui-accordion-header ui-helper-reset ui-state-active ui-corner-top\"><span class=\"ui-icon ui-icon-triangle-1-s\"></span><span class=\"accordion-header-text\">Map</span></h3><div id=\"mapAccordion\" class=\"ui-accordion-content-active ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom\"></div>').insertBefore(\"#inventoryLabel\");$('#gridPanel').hide();$('#gamePanelSpacer').height('0');var size = $(\"#mapAccordion\").innerWidth();$('#gridCanvas').width(size).height(size).appendTo($('#mapAccordion'));paper.view.viewSize.width = size;paper.view.viewSize.height = size;$(\"#gridPanel\").hide();$(\"#mapLabel\").bind(\"click\", $._data($(\"#inventoryLabel\")[0]).events['click'][0]['handler']);$(\"#mapLabel\").bind(\"mouseover\", $._data($(\"#inventoryLabel\")[0]).events['mouseover'][0]['handler']);$(\"#mapLabel\").bind(\"mouseout\", $._data($(\"#inventoryLabel\")[0]).events['mouseout'][0]['handler']);")

That belongs in the "User Interface Initialisation" script.

It works for me in the desktop player and online in Firefox and Chrome.

image


That's nice, mrangel!

I like it like this. The grid click function even still works!

Would the grid clicks still work with the hover thing you mentioned? (If not, I'd vote for adding a MAP command which switches it from the pane to the old style.)


PS

I had to add $('#gamePanelSpacer').height('0'); to make it look right on the desktop player. (It looked right without that online for some reason.)


I was thinking of giving the map pane a button in the title bar that reverts to Quest's default layout.


That sounds better than a command.


Two things:

#1: Sweet cheeeesus! Look at you guys go! This is amazing!

#2: Just realized I opened this thread in the wrong forum. My apologies!


... this is why I never made it as a software developer. I can't just move things around, the popout option has to animate the map/picture moving from its standard big position to the sidebar. As a result, I've spent an hour working on this, got a hundred lines of javascript, but only the maximised→sidebar transition is done. Well, that's 1 out of 3; and the collapse/expand pane should be a lot easier.


The thing I'm struggling with now is getting the grid to redraw. As far as I can tell, it only actually recentres the grid if a new object is drawn; which means that after zooming, the player is outside the grid window until they move. There must be a way around that, but I only see redraw functions in Quest, not in JS.

I can do this though (:

Edit: Got that sorted now. I can animate the map moving to different parts of the screen, zooming in, and resizing, and have the player stay in the middle. I can have the map fly from its default position to a place in the sidebar, and then change from fixed to relative display so that it moves up and down as the size of panes above it changes. And I can have room.picture fly to the sidebar in the same way. Just tidying up now.

Once finished, you should just need to include the javascript and do:
JS.MapToSidebar("Mini Map", "inventory")
JS.PictureToSidebar("Room View", "placesObjects")
JS.CreateExtraPane("customPane", "map")
(the last argument in the previous three lines is which pane to insert it before; omit this to put your new pane at the end)
JS.SetExtraPaneContent("customPane", "Wow! I can have more than one custom pane now!")
(that was a bonus. Because to add the map pane, I had to pull apart the MultiOpenAccordion UI plugin, and deal with the issues that prevent you adding new panes once the game has started. So you're no longer limited to a single custom pane)


OK; I think I kind of burned out my brain now.

I don't even know if this works. I've been refactoring what I had before into a more sensible organisation, and fixing errors at the same time. I need to test and debug, but I can't face staring at this any more today. So, you want to try it and tell me how much I screwed up?

Sorry, you can't post that here.

I give up


Nothing simultaneously saddens and frustrates me more than "You can't post that here."


The thing I'm struggling with now is getting the grid to redraw. As far as I can tell, it only actually recentres the grid if a new object is drawn;

It seems to already be centered when I use this code, but my tester only has three rooms, so I may need more rooms to see that it doesn't center...


It seems to already be centered when I use this code, but my tester only has three rooms, so I may need more rooms to see that it doesn't center...

For me, the "player" dot remains the same distance from the top-left corner of the map (so off the right edge of the map) from the point that function is called, until the next time the player circle on the map is moved. If you're putting it in the UI initialisation, the map will recentre correctly when the first room is drawn, I think. But if you want to move the map around the screen once the game has started, you'd need to adjust it manually.

Here's my (untested, may have reintroduced bugs when refactoring) script.
http://mrangel.info/FancySidebar.js

EDIT: Ugh, 9 pairs of mismatched brackets.
I'll sort it out when I've actually written something today.

EDIT2: typos, extra/missing brackets, and missing quotes all sorted.

Next challenge: order of operations. I have it creating the elements, then triggering the script to animate the map moving into the newly-created space in the sidebar. Before the elements are actually inserted into the DOM. togglePopout and toggleVisibility need to be exposed to the main code, so the "actually display this" function can be called once the elements are in the document.


Progress… it works (ish), but somehow ends up at the wrong location. I've probably ended up confusing some of the coordinates.

Refactoring again, so I don't have two functions doing the same thing. This should work soon.


I wish I could do these stuff too!


I got distracted :p
The library Quest uses to display the sidebar (MultiOpenAccordion) has so many known bugs in it. Like you can't add panes after it's started. So I ended up throwing it out and using my own functions to expand/collapse the sidebar sections. Then added a function to destroy the existing accordion, and apply my commands to the default panes too, allowing the same commands to be used for rearranging any of them.


That's what I'm talking about... things like that... I wish I could do that too! :)


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums