B4J Tutorial Floating ContextMenu using jNativeHookB4j

This is an example of using @Roycefer 's jNativeHook to monitor all mouse events, even outside of the current app. It uses a ContextMenu to replicate the right click functionality. Default behaviour is overridden by the jNativeHook library and returning false from the relevant event sub.

It uses a dummy form to enable the context menu to be placed anywhere on the screen.

It's not been comprehensively tested and I can't guarantee it will work on Mac or Linux, but would be interested to know if it does.

Get the jNativehook files from here: https://www.b4x.com/android/forum/threads/jnativehookb4j-for-intercepting-system-input-events.55826/

Hope you enjoy it.

V 0.2 Update for Mac - see post #3
V 0.6 implements Tags, css styling of menu, checkmenuitem, submenus and a menutitle
V 0.7 Close all menus correctly
V 0.8 Added :
  • Ignore clicks on window (allows window to operate normally)
  • Multiple Floating Menus (Only one can be active at a time)
This update contains breaking code, MainForm has to be passed to the NativeHook initialization.

No version increment update fixed menu resize issue.
Demo only update to V0.8
V0.8.5 Added
ThRuST's latest css styles
Pause and Restart Mouse Listener
cmenu.css.zip contains the latest css.file
Tags : B4j Native Hook Floating Context Menu
12
 

Attachments

  • FloatingContextMenu-0-7.zip
    7.1 KB · Views: 474
  • cmenu.css.zip
    1 KB · Views: 470
  • FloatingContextMenu-0-8-6.zip
    10.3 KB · Views: 523
  • Test - cmenu.css.zip
    1 KB · Views: 442
  • FCMTest1.zip
    10.3 KB · Views: 447
Last edited:

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve05, the floatingmenu stays under open applications when running on Mac. It however works well on Windows 10. If you update it I can test it on my Macbook.
Or maybe this is related to the jNativeHook?
 

stevel05

Expert
Licensed User
Longtime User
I'm afraid i don't have a Mac to test it on, but try adding this line in the Initialize sub of the Floating menu class after the FM.setFormStyle("UNDECORATED") line:

B4X:
Utils.AsJO(FM).GetFieldJO("stage").RunMethodJO("setAlwaysOnTop",Array(True))
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Is it possible to exchange the floatingmenu into something equal to a contextmenu which allows submenu items? because I'd like to use that in the image.
At least one with menu names and menuitems would be useful. I hope there is something similar, and where in the class to add that call?

context-menu-toolbar.gif
 

stevel05

Expert
Licensed User
Longtime User
The floating menu is already a context menu, items other than text can be added using JavaObject. The attached show one possible way of doing so.
 

Attachments

  • FloatingContextMenu-0-3.zip
    6 KB · Views: 431

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve, I am impressed how nice you implemented this, it's really good. How to add a tag to each item to be able to identify each one instead of their text?
Perhaps check the size and loop through all items and set the int value to their tag.
 

stevel05

Expert
Licensed User
Longtime User
Here is a slightly nicer implementation, As it uses JavaObject there are no Tags available. You could create classes and wrap each item and provide a tag field, but it would make the code more complex. You could store each item in a map as it's added to the menu with a Tag as the data. I think the easiest way in this sort of situation is to use the Text and select it carefully.
 

Attachments

  • FloatingContextMenu-0-4.zip
    5.8 KB · Views: 367

stevel05

Expert
Licensed User
Longtime User
Correction, Tag is available for MenuItem, in v0.4 you could pass a tag object to the FM.MenuText and add it there. But not for the Checkbox.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I could not see a difference from v3 :) Actually what I need is one less submenu, so only topics and subgroups is enough, and also the checkmarks will not be neccessary. Possible a title on top of contextmenu like in .NET if possible but not neccessary. I also want a simple way to style the menu fom CSSutils at least prefferably from code. And font and size, background and foreground color. That's all I ask for. I have allready implemented the first version which works well, but the new contextmenu would be perfect. For example it will be good enough to list menunames, in this case I want to categorize them such as for example

just an example

B4J
Vars - Dim string
Dim int
Private string
Private int
Public string
Public int

Form - MainForm Init
MainForm_Close

Subs - Standard Sub
- Sub x as String
- Sub_Action

SQL - SQLite
- MySQL

and so on... I will probably hardcode these for the most famous programming languages and offer a custom preset.
Comments and suggestions are welcomed. I have allready implemented the first contextmenu modules and it works great on both PC and Mac, autopaste works too :)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
This keeps me busy, because I wanted to come up with a CSS theme for my project so I share this in case someone want to create their own style and post here. I should add the functionality to allow users to change style for personal taste, so I post my theme 'Mindcraft default' to help someone get started with their own theme.
If someone want to contribute then use this theme as a template, post the image and CSS. If it's good I will include it into my project for everyone to use.
I think it's a great way how we help eachother in this forum. This will also help Erel to promote his great products for a wider audience, if our work becomes a success. You did an awesome work on the menu Steve, and I hope you like my CSS styling. Why not create your own theme, it is great fun :p

css1.png


CSS
// Theme name: Mindcraft default
// Created by: Roger 'ThRuST' Lindfors
// Date: 2017-01-09
// Email: [email protected]


.context-menu {
-fx-background-color: #C8CFD7;
-fx-border-color: #BBC2CC;
-fx-text-fill: white;
}

.menu-item .label {
-fx-fill:red;
-fx-font-family:tahoma;
-fx-font-size: 11px;
-fx-font-weight: bold;
}

.menu-item: focused .label {
-fx-text-fill: white;
}

.menu-item{
-fx-border-color: #FFFFFF transparent #000000 transparent;
-fx-border-width:0.50px;
}

.menu-item: focused {
-fx-background: -fx-accent;
-fx-background-color: #86a1a5;
-fx-text-fill: -fx-selection-bar-text;
}

.menu-item: pressed {
-fx-background-color: #91b6bc;
}
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Please check the filename on v6 in the first post because the link does not work :(
 

stevel05

Expert
Licensed User
Longtime User
Works here, try it again.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
It works now, thanks. I'm trying to adjust my CSS theme to the .title, if you solve it from my template then share it.
or if you want to play around with interesting buttons to the menu you can go Here
It will be fun to see if someone creates a theme of their own. Such things is great fun :)
 

stevel05

Expert
Licensed User
Longtime User
.context-menu .title .label : will get the label.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Here's a template you can play with to correct the title, it should not be selected. Also the text should be lighter. Actually this theme is more suitable as the main theme for my project, so the first one was just a first attempt to create a nicer theme. Here's my second attempt.

css2.png


CSS
// Theme name: Mindcraft default v2 example
// Created by: Roger 'ThRuST' Lindfors
// Date: 2017-01-09
// Email: [email protected]


.context-menu {
-fx-background-color:
linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
linear-gradient(#020b02, #3a3a3a),
linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
-fx-background-insets: 0,1,4,5,6;
-fx-background-radius: 10,9,8,7,6;
-fx-padding: 7 10 7 10;
-fx-font-family: "Consolas";
-fx-font-size: 10px;
-fx-font-weight: bold;
-fx-text-fill: white;
-fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) , 1, 0.0 , 0 , 1);
}


.context-menu .title: focused {
-fx-background-color: transparent;
-fx-border-color: #BBC2CC;
-fx-text-fill: yellow;
}

.menu-item .label {
-fx-fill:red;
-fx-font-family:tahoma;
-fx-font-size: 11px;
-fx-font-weight: bold;
}

.menu-item: focused .label {
-fx-text-fill: white;
}

.menu-item{
-fx-border-color: #FFFFFF transparent #86A1A5 transparent;
-fx-border-width:0.50px;
}

.menu-item: focused {
-fx-background: transparent;
-fx-background-color: transparent;
-fx-text-fill: -fx-selection-bar-text;
}

.menu-item: pressed {
-fx-background-color: #91b6bc;
}
 

stevel05

Expert
Licensed User
Longtime User
With javaobject you can set tags to a node using :

Nice, I hadn't seen that before.

Got some updating to do :)

Thanks
 
Top