MouseEvent Plugin

Questions and comments specific to a particular plugin should go here.
User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Fri Jun 02, 2017 3:32 am

no worries m8. i'm just messin with ya.


But are you running this plugin also? and if you are have you tried the script and does it work?
If you like the work I have been doing then feel free to Image

Diz
Experienced User
Posts: 121
Joined: Tue Jan 10, 2017 4:49 pm

Re: MouseEvent Plugin

Post by Diz » Fri Jun 02, 2017 4:18 am

i do use the plugin and your event method does work perfectly for me but i actually dont need it as i very slightly altered the code for the pugin so that no extra events in the tree were needed. i only chimed in because of the paste into tree issue

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Fri Jun 02, 2017 4:32 am

well TY for testing the script and letting me know that it did in fact work. and TY for chiming in about the pasting XML. i am still trying to decide on how to go about fixing it. because technically it's an issue with phpbb but then again it really isn't either. if i change it at the phpbb end of things it will start working properly right away on all version of EG that have this mechanism in it. but then the problem may arise of on another forum for some reason and the data gets copied that way it would fail.
If you like the work I have been doing then feel free to Image

Diz
Experienced User
Posts: 121
Joined: Tue Jan 10, 2017 4:49 pm

Re: MouseEvent Plugin

Post by Diz » Fri Jun 02, 2017 4:58 am

no worries... glad i could help out just a little! i dont really understand your point. surely its just simply wrong to add any extra data into the copied text that isnt really there! why should it behave differently to copying manually? lol... anyway i leave it in your capable hands :)

justahotbag2
Posts: 48
Joined: Fri Jan 27, 2017 8:16 pm

Re: MouseEvent Plugin

Post by justahotbag2 » Sat Jun 17, 2017 8:31 pm

@kgschlosser My apologies for taking so long, but for the record I try to be thorough when testing, so as not to waste your time, or anyone else's. Your code is working great and I can no longer reproduce the error I was getting, I had always tried both self-selecting the code and both the built-in select all button. However, I don't know if you've change something web-side, but no errors either way. On my side, the only thing I've changed is reset a config file on the software I'm trying to replace and improve upon which is "Volume2 by Alexandr Irza". So for any other users out there it is possible this plugin and that will conflict somehow.

However, I'm still one step away from my mission accomplished, of having the mouse wheel event be acknowledged only when near a screen edge. So far I have the screen edges registering an event, and I could rework the code to produce only one event, however, I'm thinking keeping these events separate, leaves the most flexibility and hence is a best practice, am I wrong? If I am not, then how do you have a macro go off when two events are true? Oddly a forum search pulls nothing. I've tried putting them both in a folder and some tinkering with the jump statement, but still no dice. Am I close?

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Sat Jun 17, 2017 11:25 pm

Ok I think I know what you are after. Give me 20 to key something up for ya.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Sun Jun 18, 2017 12:23 am

ok this is what i gather you want.

you will have to enable the wheel events and that is all..


then create a macro with the event MouseEvent.MouseWheel and a python script action. add the code below to the python script. please read the comments at the top

Code: Select all

# ------------ User Settings ------------

# if you have a multi monitor setup. enter the monitor number you would like it to appear on
MONITOR = 1

# which edge of the screen you want it to work on 'LEFT', 'RIGHT', 'TOP' and 'BOTTOM'
EDGE = 'TOP'

# The number below is a percentage of the overall screen size for that monitor
# to use as a buffer zone. You do not want to use a single pixel 
# for the edge as this would be to hard to hit. so instead we 
# create a virtual strip that the cursor has to be in. 
EDGE_BUFFER = 2

# ---------------------------------------

wheel_event = eg.plugins.MouseEvent.GetLastWheelEvent()
wheel = wheel_event['Wheel']
move = wheel_event['Position']

from eg.WinApi.Utils import GetMonitorDimensions

try:
    x, y, w, h = GetMonitorDimensions()[MONITOR - 1]
except IndexError:
    x, y, w, h = GetMonitorDimensions()[0]
    
buf_w = w * (EDGE_BUFFER / 100.0)
buf_h = h * (EDGE_BUFFER / 100.0)

if EDGE.upper() in ('TOP', 'BOTTOM'):
    if EDGE.upper() == 'TOP':
        stop_y = y + buf_h
        start_y = y - buf_h
    else:
        stop_y = y + h + buf_h
        start_y = y + h - buf_h
        
    stop_x = x + w
    start_x = x
        
elif EDGE.upper() in ('LEFT', 'RIGHT'):
    if EDGE.upper() == 'LEFT':
        stop_x = x + buf_w
        start_x = x - buf_w
    else:
        stop_x = x + w + buf_w
        start_x = x + w - buf_w
        
    stop_y = y + h
    start_y = y
   
else:
    start_y = 0
    stop_y = 0
    start_x = 0
    stop_x = 0
    
if (start_x, stop_x, start_y, stop_y) != (0, 0, 0, 0):
    
    if start_x <= move[0] <= stop_x and start_y <= move[1] <= stop_y:
        if wheel == 1:
            eg.TriggerEvent(prefix='Edge', suffix='Wheel.Up')
        elif wheel == -1:
            eg.TriggerEvent(prefix='Edge', suffix='Wheel.Down')
    else:
        if wheel == 1:
            eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Up')
        elif wheel == -1:
            eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Down')
    
else:
    if wheel == 1:
        eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Up')
    elif wheel == -1:
        eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Down')
        
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Sun Jun 18, 2017 1:44 am

The above will generate an event if your cursor is at the edge of the screen and the wheel is moved. this event is different then the MouseEvent.MouseWheel events it will be Edge.Wheel.Up and Edge.Wheel.Down. with the new events for the wheel being moved while the cursor is on the edge of the screen you can have those events run any macro you want. including the volume up and down which is what i am assuming you want to do.

Volume 2 is a nice program. except when you accidentally scrape the edge of the screen causing the volume to shoot up. I myself might end up using this code as well in place of volume 2. i only use volume 2 because of that edge thing but it is rather annoying at times.

That is how i understood what you wanted.. but I might be incorrect. and if so please explain.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Sun Jun 18, 2017 2:49 am

ok So i did another version...

read the code comments for use

Code: Select all

# ------------ User Settings ------------

# if you have a multi monitor setup. enter the monitor number you would like
# it to appear on
MONITOR = 1

# which edge of the screen you want to work on 'LEFT', 'RIGHT', 'TOP'
# and 'BOTTOM'
EDGE = 'LEFT'

# The number below is a percentage of the overall screen size for that monitor
# to use as a buffer zone. You do not want to use a single pixel for the edge
# as this would be to hard to hit. so instead we create a virtual strip that
# the cursor has to be in.
EDGE_BUFFER = 2

# Enter the amount you would like to change the volume by with each turn of the
# mouse wheel
VOLUME_CHANGE = 0.5

# This is the volume device that you want to change. This can be gotten by
# creating the action Change Master Volume By and selecting the device you want
# to change then right click on that new action and click on copy as python.
# Paste into a text editor. and then copy the device name into here.
VOLUME_DEVICE = u'Speakers (5- High Definition Au'

# (red, green, blue)
BAR_COLOR = (0, 255, 0)

# 0-255
TRANSPARENCY = 160

# ---------------------------------------

wheel_event = eg.plugins.MouseEvent.GetLastWheelEvent()
wheel = wheel_event['Wheel']
move = wheel_event['Position']

import wx
import VistaVolEvents
from eg.WinApi.Utils import GetMonitorDimensions
from eg.WinApi import SoundMixer


try:
    x, y, w, h = GetMonitorDimensions()[MONITOR - 1]
except IndexError:
    x, y, w, h = GetMonitorDimensions()[0]

buf_w = w * (EDGE_BUFFER / 100.0)
buf_h = h * (EDGE_BUFFER / 100.0)

if EDGE.upper() in ('TOP', 'BOTTOM'):
    f_size = (w, buf_h)
    if EDGE.upper() == 'TOP':
        stop_y = y + buf_h
        start_y = y - buf_h
        f_pos = (x, y)
    else:
        stop_y = y + h + buf_h
        start_y = y + h - buf_h
        f_pos = (x, start_y)

    stop_x = x + w
    start_x = x

elif EDGE.upper() in ('LEFT', 'RIGHT'):
    f_size = (buf_w, h)

    if EDGE.upper() == 'LEFT':
        stop_x = x + buf_w
        start_x = x - buf_w
        f_pos = (x, y)
    else:
        stop_x = x + w + buf_w
        start_x = x + w - buf_w
        f_pos = (start_x, y)

    stop_y = y + h
    start_y = y

else:
    start_y = 0
    stop_y = 0
    start_x = 0
    stop_x = 0

if (start_x, stop_x, start_y, stop_y) != (0, 0, 0, 0):

    if start_x <= move[0] <= stop_x and start_y <= move[1] <= stop_y:
        if wheel == 1:
            increment = VOLUME_CHANGE
            suffix = 'Wheel.Up'
        else:
            increment = -VOLUME_CHANGE
            suffix = 'Wheel.Down'

        eg.TriggerEvent(prefix='Edge', suffix=suffix)

        eg.plugins.System.ChangeMasterVolumeBy(
            increment,
            VOLUME_DEVICE
        )

        if hasattr(eg.globals, 'VolumeFrame'):
            wx.CallAfter(eg.globals.VolumeFrame.update)
        else:

            class VolumeFrame(wx.Frame):

                def __init__(self, device, size, pos):
                    self.device = SoundMixer.GetDeviceId(device, True)
                    volume = VistaVolEvents.GetMasterVolume(self.device) * 100
                    width, height = size
                    self.pos = pos

                    if width > height:
                        width = int((width / 100.0) * volume)
                    else:
                        height = int((height / 100.0) * volume)
                        y_pos = 0
                        while y_pos + height != size[1] + pos[1]:
                            y_pos += 1

                        pos = (pos[0], y_pos)

                    self.max_size = size

                    wx.Frame.__init__(
                        self,
                        None,
                        -1,
                        size=(width, height),
                        pos=pos,
                        style=(
                            wx.FRAME_NO_TASKBAR |
                            wx.BORDER_NONE |
                            wx.CLIP_CHILDREN |
                            wx.STAY_ON_TOP
                        )
                    )

                    def on_close(evt):
                        self.timer.Stop()
                        self.Hide()
                        self.Destroy()
                        delattr(eg.globals, 'VolumeFrame')

                    self.timer = wx.Timer(self)
                    self.Bind(wx.EVT_TIMER, on_close)
                    self.Bind(wx.EVT_PAINT, self.OnPaint)
                    self.SetTransparent(TRANSPARENCY)
                    self.OnPaint(None)
                    self.Show()
                    wx.CallAfter(self.timer.Start, 3000)

                def update(self):
                    v = VistaVolEvents.GetMasterVolume(self.device) * 100

                    width, height = self.max_size

                    if width > height:
                        width = int((width / 100.0) * v)
                    else:
                        height = int((height / 100.0) * v)
                        y_pos = 0
                        while y_pos + height != self.max_size[1] + self.pos[1]:
                            y_pos += 1

                        pos = (self.pos[0], y_pos)
                        self.SetPosition(pos)
                        
                    self.SetSize((width, height))
                    self.Refresh()
                    self.timer.Stop()
                    wx.CallAfter(self.timer.Start, 3000)

                def OnPaint(self, evt):
                    bmp = wx.EmptyBitmap(*self.GetSizeTuple())
                    dc = wx.MemoryDC()
                    dc.SelectObject(bmp)
                    dc.SetBrush(wx.Brush(wx.Colour(*BAR_COLOR)))
                    dc.SetPen(wx.Pen(wx.Colour(0, 0, 0), 1))
                    dc.DrawRectangle(0, 0, *self.GetSizeTuple())

                    dc.Destroy()
                    del dc
                    if evt is not None:
                        dc = wx.PaintDC(self)
                        dc.DrawBitmap(bmp, 0, 0)


            def run_frame():
                eg.globals.VolumeFrame = VolumeFrame(
                    VOLUME_DEVICE, f_size, f_pos
                )


            wx.CallAfter(run_frame)

    else:
        if wheel == 1:
            eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Up')
        elif wheel == -1:
            eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Down')

else:
    if wheel == 1:
        eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Up')
    elif wheel == -1:
        eg.TriggerEvent(prefix='MouseEvent', suffix='MouseWheel.Down')
If you like the work I have been doing then feel free to Image

justahotbag2
Posts: 48
Joined: Fri Jan 27, 2017 8:16 pm

Re: MouseEvent Plugin

Post by justahotbag2 » Sun Jun 18, 2017 3:16 am

You sir, are prolific.

BTW, you do know that Volume 2 has a setting to change the volume on wheel scroll and not the edge rub you're frustrated by. But now perhaps you won't need to find it.

Still, I'd like to know if a macro being qualified by two events is even possible, just for future reference. I'm trying to learn how to do things and also best practices.

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Sun Jun 18, 2017 6:08 am

no worries m8.

I never really went digging into the Volume 2 thing. I am not one to consume resources. tho I did like it. it has a bunch of crap in it I would never use. I smply like the edge thing.. and now I have it.



OK here goes one of my really messed up answers.

the answer is yes and no at the same time.


The reason for this is Yes you can with some EG back end snooping from a script. but Technically speaking No because the event has not been triggered yet. LOL

I am going to explain this as simple as i can. and hopefully not drag it out to much.

EG has been set up with multiple threads. one being the Main thread (all the GUI stuff runs in this), the message receiver thread (handles any incoming messages from the Windows API.), the event thread (it's not for the events)
it's purpose looks to be for the only purpose of managing memory. even the methods for triggering and event are located here and those methods take the event and wrap it into a function that passes off the running of the event to the actionThread. and that function then gets placed into a queue for the event thread to run. It's really crazy why it is done this way.. I do not see the purpose to it. but essentially this is what happens

Code: Select all

Event Created by whatever thread
event thread wrapper
event thread wrapper gets placed in a line to be run by the event thread
    wrapper passes event
        event gets wrapped again
        action thread wrapper gets placed in line to get run by the action thread  
            wrapper gets called and executes event


and the action thread, this is where the meat and potatoes run in EG. well in all actuality i would have to say that 80% of EG runs in this thread. don't know why it's made that way... But at any rate... the action thread is what actually triggers the event and sorts through the tree to see if an event is matched and then runs the macro.. and because a thread can only do one thing at a time guess what.. everything that deals with the action thread comes to a standstill until it is done going what it is doing. but because other threads are what do the actual creation of the event and hand it off to the action thread. that event now has to wait in line. and what we can do is go out the back door and see if the event is in the line and if it is let it in through the back door. now this seems really really complicated.. and it is and it doesn't have to be. but when EG was made it was during the days of Windows 2000 and Windows XP. and computers had very limited resources. So i am pretty sure it was done this way to limit the number of threads as well as limit the amount of memory used.

But there is a nice little spot that when an event gets created it gets stored in there. and we can go and poke into that place to grab the event out of it. but we have to use threading locks before we even touch it. this is because if by chance we are snooping around in there and the event actually gets run. there could be some issues. and if we wanted to stop the event generation we would need to add a function to a notification list that gets called first if the event is getting run. and if we reply to the call with a False it will stop the event from running right then and there. If we are only going to peek at the data that is in the event. then we do not have to do the locks. But if we have to change anything then you would need to lock it out. and that gets complicated to do.

we can only grab the event and talk to it and then kick it back into the line. but we can stop it from generating later on if we need to.

or what you can do is if an event has a state change.. kind of like the MouseEvent plugin with the movement of the mouse. we can capture that event and store it's last position into an eg.global. that would be one macro. and in a second we have the wheel event that takes place. so in that macro we go and check that eg.globals to see what the position is and we go from there..

But being as how the Author was nice enough to give you the ability to call up the last batch of mouse data for the wheel event. and in that data was 2 bits of information we needed one being the wheel direction.. the second being the position of the cursor. there was no need to do either of the previous things.
If you like the work I have been doing then feel free to Image

justahotbag2
Posts: 48
Joined: Fri Jan 27, 2017 8:16 pm

Re: MouseEvent Plugin

Post by justahotbag2 » Mon Jun 19, 2017 11:25 pm

I think you just told me to fuck myself...
and in 400 words or more.
Next time, I ask if EG can rub it's belly, and tap it's head at the same time, you can just tell me to fuck myself in less than three words.
I think you shoved it in, and jumped on it.

I kid, I kid, I love you very much sir.

I would have thought, a simple EG command or If statement could be applied to/inside events and perhaps an adjustable time window under 1000ms for the second event or something like that. Would be noob-lear friendly I think.

For those that had the same question, the TL~DR answer is no EG cannot qualify two events for one macro, unless you tickle it's backdoor. But don't tickle it, if you can't rub it.

So I suppose one macro to fill a global variable, and a second to check that variable and run something would be 'best practice' in most cases, then.
But in the case of this plugin there are already an array of variables to scrub through.

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Tue Jun 20, 2017 5:54 am

as far as wanting to control various bits of EG you can do all of it from a script. right down to changing the icons in it or moving the tree items around if you want. there are only a very small number of things that are locked out.
here is a nice example of just how open it is

viewtopic.php?f=10&t=9715
If you like the work I have been doing then feel free to Image

farbox
Posts: 37
Joined: Fri Jul 18, 2008 1:44 am

Re: MouseEvent Plugin

Post by farbox » Thu Jul 06, 2017 12:32 am

I need to trigger a macro with the side button of a logitech mouse, and I cant get it to register with HID etc etc
I'm trying to use this plugin, but cant get it to work...

I have a lib27 folder instead of a lib26!
I tried putting the pyhook folder in lib27/sitepackage, no joy; tried creating a lib26/sitepackage folder, still no joy...

I get this error:

Error loading plugin file: C:\Program Files (x86)\EventGhost\plugins\MouseEvent
Traceback (most recent call last) (0.5.0-beta5):
File "C:\Program Files (x86)\EventGhost\plugins\MouseEvent\__init__.py", line 85, in <module>
import pyHook
ImportError: No module named pyHook

AM i doing something wrong?
Has an update messed up the directories the plugin is looking for?

User avatar
kgschlosser
Site Admin
Posts: 2891
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MouseEvent Plugin

Post by kgschlosser » Thu Jul 06, 2017 12:41 am

ok so the windows API is written for a specific set of mouse buttons to work. left, right wheel up, wheel down, wheel button(middle button) wheel left and wheel right. Now i do not know if the windows API has concessions for all of the "special" buttons that exist. But I can go and have a look see at what is available and alter the plugin if additional button presses are.
If you like the work I have been doing then feel free to Image

Post Reply