Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Key binding to a button?

Basically what the title says :)
Is it possible to "click" on a link created with the <<click>> macro with a key?

If it can't be done, a supplementary question:

How can I call custom macros (I'm thinking mainly <<replace>>) directly in javascript? Is it possible at all?

Thanks a lot in advance :)

Comments

  • edited June 2015
    Saw it before I asked. It seems it's not relevant to my question, since the <<click>> macro doesn't produce the same kind of links. I couldn't reproduce any effect.
  • edited June 2015
    Fairly sure it should work with the <<click>> function. You just have to reference the correct css selector. Or maybe wrap the click in a <span> that you reference?

    In any case, try changing #story-caption in that code to #passages.
  • edited June 2015
    Trip wrote: »
    Is it possible to "click" on a link created with the <<click>> macro with a key?
    Not easily, no. If duplicating the functionality of the <<click>> isn't really an option for whatever reason, then the easiest thing would probably be to wrap the <<click>> in an ID bearing <span>, or something similar, and target it that way.

    Beyond that, depending on what you're doing, you're may also need to remove the keyboard handlers. For example, if the key bind shouldn't change (e.g. 'Escape' always opens the same dialog), then you can set it and forget it. On the other hand, if the key bind changes routinely (e.g. 'A' might always mean "go left", generally, but what "go left" means changes from passage to passage), then you'll need to ensure that the previous handlers are removed.

    Trip wrote: »
    How can I call custom macros (I'm thinking mainly <<replace>>) directly in javascript? Is it possible at all?
    Possible? Yes. Easy and/or desirable. No, generally not.

    If you're writing JavaScript, the <<replace>> macro offers you nothing which you don't already have. Simply use the native JavaScript built-ins or jQuery (which SugarCube includes) to perform your replacements.
  • I tried a few of the things I suggested. I could easily get it to activate on normal links but not on anything in a click, sorry.

    I'd recommend trying to design it without using click if possible.
  • edited June 2015
    Not easily, no. If duplicating the functionality of the <<click>> isn't really an option for whatever reason, then the easiest thing would probably be to wrap the <<click>> in an ID bearing <span>, or something similar, and target it that way.

    I tried wrapping it in a span, yes, but the problem is, sorry to say, I don't know how to target html elements in JQuery like you and greyelf showed in Claretta's topic, neither do I know which ones make up the click link... Otherwise, if I could duplicate <<click>>'s effects without using <<click>> specifically, that would solve it as well.

    What I need it for: I'm brainstorming ways to create a WASD 2D movement on a grid, and the
    <<click foo>><<set $bar to X>><<replace #somediv>><<print $bar>><</replace>><</click>>
    

    functionality you describe in Sugarcube's documentation seemed to me a good idea. (With keys substituting for actual clicking.)

    @Claretta: I have another way to do it, using the timedcycle macro to continually refresh the div that would be influenced by key presses, but I'm not sure if it won't put a strain on the browser, refreshing every half second or so, even when it's not necessary. Does anyone know, actually, if it does? Is it as heavy-handed as I think?

    Oh, and thank you all for helping out :)
  • edited June 2015
    By the way, I found a script online, called Mousetrap, and I can use it for binding keys to set different variables. (In conjunction with timedcycle's constant refresh, described above.) When I tried to make it do double duty, however - set a variable AND change a particular div id's inner HTML, so I wouldn't have to use timedcycle, - it didn't work. It's either not possible, or I'm doing something wrong...

    Here's how I tried it, with some pseudocode-ish stuff substituted:
    <<set Mousetrap.bind('w', function(){ state.active.variables["movement"] = "up"; document.getElementById("map").innerHTML = "somechangeinthemap"})>>
    
  • Trip wrote: »
    I tried wrapping it in a span, yes, but the problem is, sorry to say, I don't know how to target html elements in JQuery like you and greyelf showed in Claretta's topic, neither do I know which ones make up the click link... Otherwise, if I could duplicate <<click>>'s effects without using <<click>> specifically, that would solve it as well.

    What I need it for: I'm brainstorming ways to create a WASD 2D movement on a grid, and the
    <<click foo>><<set $bar to X>><<replace #somediv>><<print $bar>><</replace>><</click>>
    
    Something like the following should work to allow targeting of a specific <<click>>:
    <span id="foo"><<click "move foo">>
    <<set $movement to "foo">>
    <<replace "#map">>$movement<</replace>>
    <</click>></span>
    
    n.b. You really should be quoting most of the strings you're passing into the macros (as you can see I did above with <<click>> and <<replace>>).

    And the code (using Mousetrap) to trigger a click on it from the keyboard when "f" is pressed:
    Mousetrap.bind("f", function () {
    	$("#passages #foo a.macro-click").trigger("click");
    });
    

    Trip wrote: »
    By the way, I found a script online, called Mousetrap, and I can use it for binding keys to set different variables. […]
    FYI: The <<set>> and <<run>> macros evaluate TwineScript, so you don't need to access variables via state.active.variables["…"], you can just access them normally. You only need to use it when you're evaluating pure JavaScript code (e.g. when using the <<script>> macro). For example:
    <<run Mousetrap.bind("w", function () {
    	$movement = "up";
    	document.getElementById("map").innerHTML = "move was " + $movement;
    })>>
    

    Beyond that, Mousetrap simply calls the given callback when the keyboard event is fired, so your element modifying code should have worked, assuming an element with the ID map actually existed within the page at the time.

    As a test I put the following in the StoryInit special passage:
    <<set $movement to "No player movement attempted yet.">>
    <<run
    Mousetrap.bind("w", function () {
    	$movement = "up";
    	$("#map").html("Player <em>attempted</em> to move " + $movement + ".");
    });
    Mousetrap.bind("a", function () {
    	$movement = "left";
    	$("#map").html("Player <strong>attempted</strong> to move " + $movement + ".");
    });
    Mousetrap.bind("s", function () {
    	$movement = "down";
    	$("#map").html("Player <em>attempted</em> to move " + $movement + ".");
    });
    Mousetrap.bind("d", function () {
    	$movement = "right";
    	$("#map").html("Player <strong>attempted</strong> to move " + $movement + ".");
    });
    >>
    
    n.b. $("#map").html("…") is the jQuery equivalent to document.getElementById("map").innerHTML = "…".

    Then I put the following in the Start passage:
    <div id="map">$movement</div>
    

    And it worked as expected.
  • edited June 2015
    Thanks a lot! A great blueprint for further work :)
    (So clean and tidy to look at too.)

    And speaking of further work: As far as I can gather from experimentation, Twine macros don't work in innerHTML, correct? Even when I manage to construct something that looks like a macro, using >/< instead of > and <, it just sits there, plain unexecutable text. Is there a way for this to happen, possibly not using innerHTML at all?

    Edit: @TheMadExile: No matter! Didi it. Thanks for all the help! Have to say, Sugarcube is a great piece of work and you're doing an amazing work supporting it.
  • Trip wrote: »
    And speaking of further work: As far as I can gather from experimentation, Twine macros don't work in innerHTML, correct? Even when I manage to construct something that looks like a macro, using >/< instead of > and <, it just sits there, plain unexecutable text. Is there a way for this to happen, possibly not using innerHTML at all?
    For any Twine markup to work, you have to use the story format's markup processing engine. For SugarCube, that is a new Wikifier(element, source) call. For example:
    Mousetrap.bind("w", function () {
    	$movement = "up";
    	new Wikifier(document.getElementById("map"), "Player <em>attempted</em> to move " + $movement + ".");
    });
    
  • Ah, great to know, thanks again!
Sign In or Register to comment.