HPInc / HP-Digital-Microfluidics

HP Digital Microfluidics Software Platform and Libraries
MIT License
2 stars 0 forks source link

how will the modifiers be triggered? #190

Open EvanKirshenbaum opened 5 months ago

EvanKirshenbaum commented 5 months ago

The modifiers declared here are being used when a click on the board happens, here.

What kind of click do I have to do to not get a None value? How would I get "control"? I tested it by holding the control, shift and alt key but it always returned None.

Migrated from internal repository. Originally created by Mark Huber on Jul 13, 2022 at 1:24 PM PDT.
EvanKirshenbaum commented 5 months ago

I'm not sure I understand the question. Under matplotlib, at least, holding down control gives you "control", holding down shift gives you "shift", and holding down both gives you "ctrl+shift".

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 13, 2022 at 2:49 PM PDT.
EvanKirshenbaum commented 5 months ago

So I have to hold down control and click a pad with the mouse?

Migrated from internal repository. Originally created by Mark Huber on Jul 13, 2022 at 3:39 PM PDT.
EvanKirshenbaum commented 5 months ago

Yes. on_pick() is registered as a handler for "pick_event":

        def on_pick(event: PickEvent):
            artist = event.artist
            target = self.click_id[artist]
            if target.live:
                key = event.mouseevent.key
                with_control, with_shift = self.modifiers[key]
                # with_control = key == "control" or key == "ctrl+shift"
                # with_shift = key == "shift" or key == "ctrl+shift"
                print(f"Clicked on {target} (modifiers: {key})")
                self.click_handler.process_click(target,
                                                 with_control=with_control,
                                                 with_shift=with_shift)
            else:
                print(f"{target} is not live")

        self.figure.canvas.mpl_connect('pick_event', on_pick)

The key attribute for a mouseevent represents the (modifier) keys that are held down when the mouse is clicked.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 13, 2022 at 3:56 PM PDT.
EvanKirshenbaum commented 5 months ago

whatever combination I do (shift, alt, control), I always just get None in return. Can you confirm you get different results on your machine?

Migrated from internal repository. Originally created by Mark Huber on Jul 13, 2022 at 3:58 PM PDT.
EvanKirshenbaum commented 5 months ago

I can.

image

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 13, 2022 at 4:10 PM PDT.
EvanKirshenbaum commented 5 months ago

sorry, those commands actually don't work on my machine, I printed out the key event here and it always comes out to None no matter where or which keys (shift, ctrl, shift + ctrl), ie:

{'button': <MouseButton.LEFT: 1>, 'key': None, 'step': 0, 'dblclick': False, 'name': 'button_press_event', 'canvas': <matplotlib.backends.backend_tkagg.FigureCanvasTkAgg object at 0x0000023ACB584670>, 'guiEvent': <ButtonPress event state=Shift num=1 x=452 y=457>, 'x': 452, 'y': 343, 'inaxes': <AxesSubplot:>, 'xdata': 6.50232258064516, 'ydata': 3.7117647058823504}

I can't find it anymore but I think I read somewhere that those key presses are platform dependent, so that might be the reason.

I implemented my version of it and I get from the modifiers:

`ctrl` => True, False
`shift` => False, True
`shift+ctrl` => True, True

this seems to be consistent and works with all controls and shift buttons. And it seems to match with your modifiers here

I clicked around on my board a bit and it seems like only the shift button creates a new drop on the board. I get the following output in the terminal:

--------------
Blobs on board
--------------
Blob(unpinned, 1 μl of unknown: [Pad(3,11)])

After randomly clicking around a bit I realized that the matplotlib board and my board look a bit different:

matplotlib: image

mine:

image

so there seems to be something wrong in my code with creating the drops, they appear to have the wrong radius.

Other questions:

Migrated from internal repository. Originally created by Mark Huber on Jul 20, 2022 at 11:11 AM PDT.
EvanKirshenbaum commented 5 months ago

I implemented my version of it and I get from the modifiers:

`ctrl` => True, False
`shift` => False, True
`shift+ctrl` => True, True

this seems to be consistent and works with all controls and shift buttons. And it seems to match with your modifiers here

I'm confused. You said that you were always getting None, but this makes it sound as though these are what you're actually getting. In any case, If you find a modifier description that isn't currently in the dictionary, feel free to add it. Don't remove the ones that are there, though, as they are likely needed for other platforms.

I clicked around on my board a bit and it seems like only the shift button creates a new drop on the board. I get the following output in the terminal:

Only the shift button should create a drop.

--------------
Blobs on board
--------------
Blob(unpinned, 1 μl of unknown: [Pad(3,11)])
* How do you get it to be pinned?

A blob is "pinned" if any (and, by construction, all) of its pads are on.

After randomly clicking around a bit I realized that the matplotlib board and my board look a bit different:

matplotlib: image

mine:

image

so there seems to be something wrong in my code with creating the drops, they appear to have the wrong radius.

The drop radius is computed by PadMonitor.drop_radius(drop), which is called in DropMonitor.__init__() to get the initial size and by DropMonitor.note_volume() when the volume changes.

Also, I note that you're not setting the alpha channel on the colors in the reagent circles. I'd recommend setting it to about 0.5 so that you can see through them to the temperatures below and also so that you can see the pad edges change.

Other questions:

* what is supposed to happen when you click `ctrl`?

* what is supposed to happen when you click `shift+ctrl`

* how do you make the drop traverse via clicks? (or is that not possible?)

The logic is implemented by ClickHandler.process_click().

Basically:

  1. If you hold (only) shift, liquid is added to the location clicked on.
    • By default, it will be one drop's worth of unknown. You can change that by setting interactive reagent and interactive volume in the text box.
  2. If you hold shift and control, liquid is removed from the blob at the location clicked on.
    • As with adding, interactive volume (by default 1 drop) is removed.
    • If there isn't that much reagent in the blob, all of the reagent is removed. If there is no reagent, nothing happens.
  3. If you hold (only) control, the state of the pad clicked on is toggled.
    • Actually, it gets scheduled to be toggled. If the board is paused, its border will change to be thicker to show the intended change, but the change won't happen until the clock is restarted or stepped.
    • If the pad already has a scheduled change (i.e., the clock is stopped, and it's already been clicked on), that scheduled change is withdrawn.
  4. If you click without modifiers, if the clicked pad is on, it is handled just as if control had been pressed. Otherwise
    1. If the pad is not yet scheduled to turn on, it is scheduled to turn on, and any neighbors that are on are scheduled to turn off.
    2. If the pad is scheduled to turn on (i.e., the clock has stopped, and it's already been clicked on), that scheduled change is withdrawn and all neighbors that are scheduled to turn off get that change withdrawn unless they have another neighbor that's scheduled to turn on (and would therefore also have scheduled them to turn off).
      • Basically, we're undoing the prior, not-yet-actuated click.

The upshot is that if you click on a pad next to a drop, it should move the drop.

The actual drop motion is inferred based on the state of pads, but you shouldn't have to worry about that for the monitoring. It should all get taken care of by calls to PadMonitor.note_drop_change(), DropMonitor.note_reagent(), and DropMonitor.note_volume().

The physics that's being modeled says that if you turn on a pad next to a drop, the drop gets pulled toward that pad. If the pad it's on is off, it will move, and if the pad it's on is on, it will get stretched. If you pull in multiple directions, it will get split.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 21, 2022 at 11:20 AM PDT.
EvanKirshenbaum commented 5 months ago

I'm confused. You said that you were always getting None, but this makes it sound as though these are what you're actually getting.

Sorry, I meant, if I click the matplotlib board it always comes out to be None, so the key events don't work on my machine. But I got them to work on the Tkinter board (or mostly).

In any case, If you find a modifier description that isn't currently in the dictionary, feel free to add it. Don't remove the ones that are there, though, as they are likely needed for other platforms.

Sounds good. I might add special key events to that, with TKinter you can assign methods to a key such as <Shift Button>

If you hold (only) shift, liquid is added to the location clicked on

That works.

The drop radius is computed by PadMonitor.drop_radius(drop), which is called in DropMonitor.init() to get the initial size and by DropMonitor.note_volume() when the volume changes.

That does not work. The radius does not increase on my tkinter board. Additionally, I found the following:

By default, it will be one drop's worth of unknown. You can change that by setting interactive reagent and interactive volume in the text box.

If you hold shift and control, liquid is removed from the blob at the location clicked on

That doesn't work, because the drop is obstructing the pad that has the event on it.

The upshot is that if you click on a pad next to a drop, it should move the drop.

This works.

Migrated from internal repository. Originally created by Mark Huber on Jul 22, 2022 at 2:10 PM PDT.
EvanKirshenbaum commented 5 months ago

The drop radius is computed by PadMonitor.drop_radius(drop), which is called in DropMonitor.init() to get the initial size and by DropMonitor.note_volume() when the volume changes.

That does not work. The radius does not increase on my tkinter board.

Are you saying that drop_radius() always returns 1 or that note_volume() isn't changing the radius? In my code the latter is defined as

    def note_volume(self, _: Volume) -> None:
        pm = self.board_monitor.pads[self.drop.pad]
        radius = pm.drop_radius(self.drop)
        self.circle.radius = radius

with ReagentCircle's radius property defined as

    @radius.setter
    def radius(self, val: float) -> None:
        self._radius = val
        for s in self.slices:
            s.set_radius(val)

Have you changed things to make it change the radius on your board?

Additionally, I found the following:

  • If I hold shift and press on the pads directly to the left right, top and bottom, the volume/radius seems to increase on the matplot lib board, is this correct?

    image image

Yeah. (Although I had thought that it would only work like that if the pad under the original drop is on.) What's happening is that you're adding liquid to the pad next to the drop, and the two drops are merging to form one bigger drop.

By default, it will be one drop's worth of unknown. You can change that by setting interactive reagent and interactive volume in the text box.

  • what's the command for setting that?

Just a normal assignment, e.g.,

interactive reagent = reagent "foo"
interactive volume = 2uL

If you hold shift and control, liquid is removed from the blob at the location clicked on

That doesn't work, because the drop is obstructing the pad that has the event on it.

In my code, the PadMonitor.square Rectangle and the PathPatches that make up WellPadMonitor.shapes are the only patches that are created with picker=True, so they're the only things that respond to mouse clicks. I presume that there's something similar for your package.

The upshot is that if you click on a pad next to a drop, it should move the drop.

This works.

  • I noticed, that if I hold control and click next to a drop that is already created, it will create another drop next to it, is that correct? image

Sort of. What's actually happening is that the Blob is getting extended to include the new pad and the liquid is being stretched over it. If you look on the matplotlib display, you should see that each of the drops is smaller, since the overall Blob volume isn't getting changed. It's not a great way to display a multi-pad blob, but it was the easiest way I could think of when I added them.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 22, 2022 at 4:00 PM PDT.