Open antwin opened 1 year ago
Hello @antwin , why are you using a TextInput to do so? wouldn't it be better to use a Link widget?
Thank you for the reply - much appreciated !
The reason is that I have an editable diary/notebook entry like:
-----------------------
remi diary part 1
https://github.com/rawpython/remi
https://remi.readthedocs.io
To tablet:
:~>adb push py/remi/rem.py
termux script:
python storage/external-1/rem.py
exec am start --user 0 -a android.intent.action.VIEW -n org.mozilla.firefox/org.mozilla.fenix.IntentReceiverActivity -d "http://localhost:8082" >/dev/null
--20230419--
-------------------
This combines my notes, urls and other information. I want to set it up so that when I right-click on a url it loads the browser. Much more flexible than bookmarks! But I have to be able to edit and save the entry.
I can use remi to run on android with termux - it looks like the best way of running Python on android!
However, I can't find how to incorporate clickable urls into an editable bit of html that can then be saved.
Any suggestions?
Hello @antwin ,
This is an example for you ;-)
import remi.gui as gui
from remi import start, App
"""
This TextInputAdvanced class allows to get the caret position on click event.
"""
class TextInputAdvanced(gui.TextInput):
@gui.decorate_event_js("""
var params={};
params['caretPositionStart'] = -1;
params['caretPositionEnd'] = -1;
if (document.activeElement == this)
{
try{
params['caretPositionStart'] = document.activeElement.selectionStart;
params['caretPositionEnd'] = document.activeElement.selectionEnd;
}catch(e){console.debug(e.message);}
}
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s', params);
""")
def onclick(self, caretPositionStart, caretPositionEnd):
# The onclick event returns the text selection start and end
# If no text is selected, -1 is returned.
caretPositionStart = int(caretPositionStart)
caretPositionEnd = int(caretPositionEnd)
return (caretPositionStart, caretPositionEnd)
class MyApp(App):
def main(self):
# creating a container VBox type, vertical (you can use also HBox or Widget)
main_container = gui.VBox(style={'margin': '0px auto'})
self.lblSelectionStartCaption = gui.Label("Selection start: ", width=100)
self.lblSelectionEndCaption = gui.Label("Selection end: ", width=100)
self.lblSelectionStart = gui.Label("", width=100)
self.lblSelectionEnd = gui.Label("", width=100)
main_container.append(gui.HBox(children=[self.lblSelectionStartCaption, self.lblSelectionStart]))
main_container.append(gui.HBox(children=[self.lblSelectionEndCaption, self.lblSelectionEnd]))
self.txtInput = TextInputAdvanced(False, width = 150, height = 100)
self.txtInput.set_text("This is the url https://github.com/rawpython/remi of the remi repository.")
self.txtInput.onclick.do(self.on_text_input_click)
main_container.append(self.txtInput)
# returning the root widget
return main_container
def on_text_input_click(self, emitter, caretPositionStart, caretPositionEnd):
"""
Since you have the caretPositionStart, you can get the text in that position
and if it is an url, open the url
"""
self.lblSelectionStart.set_text(str(caretPositionStart))
self.lblSelectionEnd.set_text(str(caretPositionEnd))
#splitting the text by using the spaces before and after the caret
text = self.txtInput.get_text()
spaceBefore = -1
try:
spaceBefore = text.rindex(" ", 0, caretPositionStart)
except:
pass
spaceAfter = len(text)
try:
spaceAfter = text.index(" ", caretPositionStart)
except:
pass
textPointed = text[spaceBefore+1:spaceAfter]
print("The text below the cursor is: " + textPointed)
if __name__ == "__main__":
# starts the webserver
start(MyApp, address='0.0.0.0', port=0, start_browser=True)
Thank you very much! That is a very useful bit of code. I have tried modding it so that a right-click (that would normally trigger a context menu) can be used instead of a left-click, but I haven't made that work yet...
Hello @antwin ,
Here is the working code using the right mouse button:
import remi.gui as gui
from remi import start, App
"""
This TextInputAdvanced class allows to get the caret position on click event.
"""
class TextInputAdvanced(gui.TextInput):
@gui.decorate_event_js("""
var params={};
params['caretPositionStart'] = -1;
params['caretPositionEnd'] = -1;
if (document.activeElement == this)
{
try{
params['caretPositionStart'] = document.activeElement.selectionStart;
params['caretPositionEnd'] = document.activeElement.selectionEnd;
}catch(e){console.debug(e.message);}
}
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s', params);
""")
def oncontextmenu(self, caretPositionStart, caretPositionEnd):
# The onclick event returns the text selection start and end
# If no text is selected, -1 is returned.
caretPositionStart = int(caretPositionStart)
caretPositionEnd = int(caretPositionEnd)
return (caretPositionStart, caretPositionEnd)
class MyApp(App):
def main(self):
# creating a container VBox type, vertical (you can use also HBox or Widget)
main_container = gui.VBox(style={'margin': '0px auto'})
self.lblSelectionStartCaption = gui.Label("Selection start: ", width=100)
self.lblSelectionEndCaption = gui.Label("Selection end: ", width=100)
self.lblSelectionStart = gui.Label("", width=100)
self.lblSelectionEnd = gui.Label("", width=100)
main_container.append(gui.HBox(children=[self.lblSelectionStartCaption, self.lblSelectionStart]))
main_container.append(gui.HBox(children=[self.lblSelectionEndCaption, self.lblSelectionEnd]))
self.txtInput = TextInputAdvanced(False, width = 150, height = 100)
self.txtInput.set_text("This is the url https://github.com/rawpython/remi of the remi repository.")
self.txtInput.oncontextmenu.do(self.on_text_input_click, js_stop_propagation=True, js_prevent_default=True)
main_container.append(self.txtInput)
# returning the root widget
return main_container
def on_text_input_click(self, emitter, caretPositionStart, caretPositionEnd):
"""
Since you have the caretPositionStart, you can get the text in that position
and if it is an url, open the url
"""
self.lblSelectionStart.set_text(str(caretPositionStart))
self.lblSelectionEnd.set_text(str(caretPositionEnd))
#splitting the text by using the spaces before and after the caret
text = self.txtInput.get_text()
spaceBefore = -1
try:
spaceBefore = text.rindex(" ", 0, caretPositionStart)
except:
pass
spaceAfter = len(text)
try:
spaceAfter = text.index(" ", caretPositionStart)
except:
pass
textPointed = text[spaceBefore+1:spaceAfter]
print("The text below the cursor is: " + textPointed)
if __name__ == "__main__":
# starts the webserver
start(MyApp, address='0.0.0.0', port=0, start_browser=True)
Have a nice day, Davide
Thank you again for the code. I have tried the context menu version, and - following your example - a double-click version. These work fine on my debian desktop, but not on Android.
But the first (onclick) version works ok. I create a url which I can then click on, as below:
def onRecTxtClick(self, emitter, caretPositionStart, caretPositionEnd):
''' splitting the text by using the spaces before and after the caret
https://github.com/rawpython/remi/issues/514 '''
text = self.recTxt.get_text()
spaceBefore = -1
try:
spaceBefore = text.rindex(" ", 0, caretPositionStart)
except:
pass
spaceAfter = len(text)
try:
spaceAfter = text.index(" ", caretPositionStart)
except:
pass
txt = text[spaceBefore+1:spaceAfter]
if 'http' in txt or 'www' in txt:
txt = txt.split('\n') # clean up if not enough spaces around, but linefeeds instead
for line in txt:
if 'http' in line or 'www' in line:
textPointed = line.strip()
break
# print("The text below the cursor is: " + textPointed)
#d self.lbl.set_text(f'{textPointed}')
self.lbl.set_text('')
url = gui.Link(textPointed,textPointed, open_new_window=True)
self.urls.empty()
self.urls.append(url)
else:
return
I need to find one of several urls in a TextInput (say with a double-click) so I can open it in a browser. I've tried
self.recTxt = gui.TextInput(single_line=False, margin='10px') self.recTxt.ondblclick.connect(self.onDblClick) self.recTxt.onmousemove.connect(self.onMouseMove)
I can get all the text, but not find the particular url that was clicked on. Or I can get the mouse position in x,y coordinates.
How do I get the text?