Page 1 of 2

mousedown problem

PostPosted: Wed Oct 11, 2023 2:17 pm
by John Robin Dove
Hi Clifton,
I have a problem concerning the mousedown event which in certain circumstances no longer functions. I have made a test app using the same objects as those in my program. I have included explanations in this app. The zip containing testAttempts.tbk and attempts1.xml is here https://www.mediacours.com/tb_examples/testAttempts.zip
Thanks for you time.
John

Re: mousedown problem

PostPosted: Thu Oct 12, 2023 5:48 am
by John Robin Dove
Hi Clifton,
Please do not waste time on this problem if you have more important things to do because I have found what seems to be a pretty good workaround. I have added a couple of fields that become visible when 1 or 10 is reached. They look just like the real thing.
Code: Select all
  <downDisabled>
  <pgStyleObject>
  <![CDATA[
  { theStyle : "background-image, cursor, background-size, box-shadow",
  propVal  : "url(../media/f.gif), default, cover, 1px 1px" }
  ]]>
  </pgStyleObject>
  </downDisabled>


I have also added this system (unrelated to the problem) which ensures that the buttons will still respond even if they are clicked rapidly.
Code: Select all
  <attemptsUp>
  <pgStyleObject>
  <![CDATA[
  { theStyle : "cursor",
  propVal  : "pointer"}
  ]]>
  </pgStyleObject>
 
  <function name="myMouseDown" event="mousedown" params="evt,undef,target" useTB="true">
  <![CDATA[
  sharedActions.done = false;
  sharedActions.attemptsUp = true;
  tbfunction_pgTimer(true, 300,"attemptsTimer");
  ]]>
  </function>
 
  <function name="myMouseUp" event="mouseup" params="evt,undef,target" useTB="true">
  <![CDATA[
    if (sharedActions.done == true)
    {
    tbfunction_pgTimer("", "", "attemptsTimer", true);
    sharedActions.modifyTrigger(true, true); //isLimited: true  isAttempts: true
    }
    else
    {
      var fct = function()
      {
      tbfunction_pgTimer("", "", "attemptsTimer", true);
      sharedActions.modifyTrigger(true, true); //isLimited: true  isAttempts: true
      sharedActions.done = true
      }
    setTimeout(fct, 400);
    }
  ]]>
  </function>
  </attemptsUp>

  <attemptsTimer>
  <function name="myUser" event="user" params="evt,value" useTB="true">
  <![CDATA[
    if (sharedActions.attemptsUp == true)
    {
      if (sharedActions.attempts < 10)
      {
      sharedActions.attempts += 1;
      tbfunction_pgTBObjSet("attempts", "text", sharedActions.attempts)
      sharedActions.done = true;
        if (sharedActions.attempts == 10)
        {
        tbfunction_pgTimer("", "", "attemptsTimer", true);
        tbfunction_pgTBObjSet("upDisabled", "visible", true);
        sharedActions.modifyTrigger(true, true); //isLimited: true  isAttempts: true
        }
      tbfunction_pgTBObjSet("downDisabled", "visible", false);
      }
    }
    else
    {
      if (sharedActions.attempts > 1)
      {
      sharedActions.attempts -= 1;
      tbfunction_pgTBObjSet("attempts", "text", sharedActions.attempts)
      sharedActions.done = true;
        if (sharedActions.attempts == 1)
        {
        tbfunction_pgTimer("", "", "attemptsTimer", true);
        tbfunction_pgTBObjSet("downDisabled", "visible", true);
        sharedActions.modifyTrigger(true, true); //isLimited: true  isAttempts: true
        }
      tbfunction_pgTBObjSet("upDisabled", "visible", false);
      }
    }
  ]]> 
  </function>     
  </attemptsTimer>

John

Re: mousedown problem

PostPosted: Thu Oct 12, 2023 12:11 pm
by Clifton
Hi John,

I reworked your XML file a bit and have a working result that you can play around with.

The main issue in your XML file is that you are setting up a listener for "mouseDown" that uses the useTB="true" parameter. This directs ToolBook to use its internal mousedown handler which is really not supported in a predictable way, especially when objects are grouped together. So I reworked the listener to use the native browser "mousedown" event.

Also you don't really need a mouseUp event, but you should use a mouseOut event. You can see all of this in the attached XML. It works really nice on my end no matter how fast or slow or whether the user holds the mouse down over the buttons.

I've commented the XML so you should be able to follow the logic. Also removed the sharedActions element as it isn't really needed and just adds complexity; though this is up to you.

Give it a look.
Clifton

Re: mousedown problem

PostPosted: Thu Oct 12, 2023 1:17 pm
by John Robin Dove
Many thanks Clifton. That looks a lot tidier. I didn't know that you could add a global variable to any object like this.attempts in <attemptsTimer>. Maybe global is the wrong word but it seems to me to be at least semi-global.
That means that there are thousands of references to sharedActions in my program that are unnecessary but I guess I'll just leave them because the computer doesn't seem to mind.
John

Re: mousedown problem

PostPosted: Thu Oct 12, 2023 2:28 pm
by Clifton
Technically, you could remove the field "attemptsTimer" as well and move the user event to the group "attemptsGroup" which contains the buttons, etc.
Then adjust pgTimer() to send its user events to group "attemptsGroup" instead of to field "attemptsTimer".

I would also set an additional style on the numeric field "attempts":
<pgStyleObject>
{ theStyle : "pointerEvents",
propVal : "none" }
</pgStyleObject>

What this does is make it impossible for a user to copy or manipulate the numeric field. After all, it is for display purposes only. Sometimes when the cursor changes when a user mouseovers on a field, it gives the impression that he has some control over the field or that the field serves some other purpose other than to just to display information.

Clifton

Re: mousedown problem

PostPosted: Thu Oct 12, 2023 3:51 pm
by John Robin Dove
Thanks again. I have a few other fields to which I should apply pointerEvents: none. Fortunately there are not that many.
John

Re: mousedown problem

PostPosted: Fri Oct 13, 2023 9:00 am
by John Robin Dove
Hi Clifton,

I have been studying your code and have learnt quite a lot. It's brilliantly concise and efficient. Not like my long-winded stuff. It took me a while to understand exactly how it works. I now see how you are using the click and mouseout events to achieve exactly what I wanted.

I was able to apply your technique to that particular part of my program i.e. changing the number of attempts the student is allowed to do a task but unfortunately it interferes with other things. There are three 'up/down timers': one to set attempts, one to position the task, relative to the media file timecode and one to vary the amount of time the student is allowed to make a recording (including unlimited time). The buttons to alter the position and those to alter the time allowed are in groups. So I have a structure like this: mousedown for the group sends the target.name to a function which sets global variables according to requirements (up/down, big/small) which in turn starts a timer which changes values and moves objects accordingly.

The problem is it seems I can't use target.name if I use the native browser mouse events so my system is unworkable. I suppose I would have to write code for each individual button or is there a better way?

Anyway, don't waste time on it if you're busy. My clunky system apparently produces the same results from the user's point of view. What I fail to understand is why does disabling one button affect all the others?

I thought it might be a good idea to show you what I'm trying to do so I've put a video here https://youtu.be/Z7idkTxW2ow

UPDATE I've just had a brainwave. :idea: What about using tbfunction_userProperty to retrieve mouseup and mousedown? I don't have time to do it right now but I'll have a try tomorrow.

John

Re: mousedown problem

PostPosted: Sat Oct 14, 2023 7:30 am
by John Robin Dove
Hi Clifton,
My idea seems to work! :) Please take a look at my latest version of attempts1.xml and let me know if you think it's OK. If it is, I'll apply it to my program. I've put a zip here: https://www.mediacours.com/tb_examples/attempts1.zip
John

Re: mousedown problem

PostPosted: Sat Oct 14, 2023 8:18 am
by Clifton
If that method works, then go for it. Basically, userProperty() installs native browser mouseup/down events on the target object.

Please note that you will have to wrap your mouseout functions in <![CDATA[ . . . ]]> tags. If they are compiling right now, it is likely an anomally as all functions generally require the tags in order for the content of the function to be preserved and acknowledged by the interpreter.

Clifton

Re: mousedown problem

PostPosted: Sat Oct 14, 2023 10:18 am
by John Robin Dove
Oops, didn't spot that. I don't often forget because I usually paste in a spare block of code. But I notice you don't use <![CDATA[ . . . ]]> for pgStyleObject.
Many thanks. John