Hi I wrote a script with the "undotext" widget,
and I'm looking for a way to get the line index of the palce where the mouse cursor is standing.
and similarly when the user has select part of the line.
To get the current location of the mouse cursor in text coordinates (not just x,y) you need to do either this:
$txt->index("current");
or this (where $x and $y give the mouse cursor location relative to the text widget):
$txt->index("#$x,$y");
The first is definitely more convenient, but the second is needed if you're in the middle of a drag (the current mark isn't updated while any mouse button is down).
Related
I created a uitable (new version using appdesigner) in MATLAB and wanted to support right clicking on cells and showing a cell specific context menu. Much to my surprise there seemed to be no way to support this.
The context menu only seems to trigger with right click on the uitable, but there is no way of knowing which cell was selected (I think, maybe not?). I created a workaround where I left clicked to select a cell, and during that selection I right clicked using a Java Mouse robot to trigger the context menu. This is super ugly but sort of works. Except, if you need to bring up the menu twice on the same cell. Apparently the cell selected callback only fires once for the cell, until a new cell is selected. I tried literally putting two tables in the same spot and upon selecting one toggling to the other, but the memory of cell selection is table specific, so this only worked for two clicks before both tables had been clicked on the same cell, and toggling visibility back to the first resulted in the cell selection callback not firing (since the cell had not changed) . I tried various approaches to try and deselect the cell (disable/enable, visibility change, data change, etc.), but the cell selection callback never changed.
I even tried having duplicate columns, where the goal was to hide a column, where normally columns 1 and 2 would be visible (column 3 out of view due to size), and then on clicking on column 2, column 2 would hide itself (0 width) and column 3 (an exact duplicate) would move into its place, thus seeming to the user like multi-clicking was supported. Unfortunately I can't set the column width to 0 -- or rather, setting it to 0 doesn't completely hide the column. Instead there seems to be some minimal width to the column and the whole thing looked awful.
I wanted to do something similar with a listbox (right click support), but again I couldn't figure out how to identify where I was right clicking. I eventually settled on left clicking on a listbox and using the mouse robot approach to right click to bring up the context menu. Unlike the uitable, it was fairly easy to clear the selection on the listbox (set listbox.Value = {}). However, I strongly dislike the left click instead of right click approach and I'd rather have multiple columns.
Any suggestions would be much appreciated!!!
So I found an approach that is better than using a robot. I had tried this but was missing a critical portion which I will describe below.
Upon selecting a row in the table, the open command can be used to launch a context menu. My problem was that I didn't know where to launch the menu. I tried CurrentPoint for the figure, but it was 0,0 (or in general not valid)
Here's the current documentation for CurrentPoint:
Current point, returned as a two-element vector. The vector contains
the (x, y) coordinates of the mouse pointer, measured from the
lower-left corner of the figure. The values are in units specified by
the Units property.
The coordinates update when you do any of the following:
Press the mouse button within the figure.
Release the mouse button after pressing it within the figure.
Press the mouse button within the figure, and then release it outside
the figure.
Rotate the scroll wheel within the figure.
Move the mouse within the figure (without pressing any buttons),
provided that the WindowButtonMotionFcn property is not empty.
If the figure has a callback that responds to mouse interactions, and
you trigger that callback faster than the system can execute the code,
the coordinates might not reflect the actual location of the pointer.
Instead, they are the location when the callback began execution.
If you use the CurrentPoint property to plot points, the coordinate
values might contain rounding error.
Here's the critical line again:
"Move the mouse within the figure (without pressing any buttons), provided that the WindowButtonMotionFcn property is not empty."
So when a selection of a cell happens, the CurrentPoint is not valid. However, if we simply define a WindowButtonMotionFcn, then it is!
So the general idea is to have a callback for the table when a cell is selected (SelectionChangedFcn) and to set a dummy callback for WindowButtonMotionFcn
The final point is that a context menu can be launched with the open function if you specify a given location to launch it at. This is different from attaching it to an object and having it automatically launch on right click.
Here's some example code. If you comment out the callback for windows motion then the whole thing doesn't work! Unfortunately it is a left click for targeting the cell but at least it avoids the non-sense I was using with a java robot right click.
classdef wtf < handle
properties
h %struct, this was an appdesigner handle
cm %context menu
end
methods
function obj = wtf()
h = struct;
h.UIFigure = uifigure();
h.UITable = uitable(h.UIFigure);
obj.h = h;
obj.h.UITable.CellSelectionCallback = #obj.tableCall;
%obj.h.UITable.SelectionChangedFcn = #obj.tableCall;
%Some data ...
s = struct;
s.a = (1:4)';
s.b = (5:8)';
obj.h.UITable.Data = struct2table(s);
%Our context menu
cm = uicontextmenu(obj.h.UIFigure);
m = uimenu(cm,'Text','Menu1');
obj.cm = cm;
%WTF ... without this we don't get a valid CurrentPoint
obj.h.UIFigure.WindowButtonMotionFcn = #obj.mouseMove;
end
function tableCall(obj,x,y)
%y - event info
%x - impacted object
cp = get (obj.h.UIFigure, 'CurrentPoint');
open(obj.cm,cp(1),cp(2));
selected_cell = y.Indices;
%selected_cell = y.Selection;
x.Selection = []; %allows reselecting same cell without
%needing to select another cell first
%Now we can run something on the context menu
%that targets the selected cell
end
function mouseMove(obj,x,y)
%we could store a point here
end
end
end
For example, assume you are at the start of a new line. Pressing LEFT on the keypad does not move the cursor to the end of the previous line.
Similarly assume you are at the end of a line, pressing RIGHT on the keypad doesn't move the cursor to a new line.
How do I enable this behavior? Note this is the default behavior in Sublime Text 3.
Here LEFT and RIGHT are simply <- and ->, on the keyboard and not the numeric ones.
Is there an autohotkey function which brings the mouse pointer to the active cursor?
(assume that the active window has a active cursor, e.g., in notepad, etc.)
MouseMove, A_CaretX, A_CaretY, 0
A_CaretX and A_CaretY are the current X and Y coordinates of the caret (text insertion point). The coordinates are relative to the active window unless CoordMode is used to make them relative to the entire screen. If there is no active window or the caret position cannot be determined, these variables are blank.
https://www.autohotkey.com/docs/Variables.htm#misc
Is there a way to make Emacs preserve my cursor's horizontal position, when going up and down between lines of varying widths in a file?
I'll explain what I mean by example. Say I have 3 lines of text:
1: ------a
2: --b
3: --c---d
Say the cursor is at the position marked above by a. If I move down a line, the cursor will be at b. If I move down again, it will be at c. But I actually want to end up at d.
Is there a way to make Emacs do that automatically, so that I can go from a to b to d just by pressing the down arrow twice? Emacs would have to remember my horizontal position from my most recent horizontal movement, and try to restore that horizontal position each time I move vertically.
Customize user option goal-column to nil.
(You can also use command set-goal-column anytime to set goal-column to the current column.)
In AutoHotkey, I want to click my mouse at position X,Y where X and Y are known but then I want it to return to the original position (arbitrary)
Right now I just have:
f::
Click 987,851
MouseMove,661,506
return
I would like to replace the 3rd line with a new method that returns it to the original position
Thanks
You need to use MouseGetPos to save the previous position, then restore it.
I think this should do it:
f::
MouseGetPos,xpos,ypos
Click 987,851
MouseMove,%xpos%,%ypos%
return
This has already been answered, but just an FYI, make sure to use SendMode Input for instant mouse movements.