GTK+ / GTKMM Signal on "changed" on a textbuffer does not receive data - gtk

On the same window, I have 20 text views and I need to handle in only one callback the "changed" signal coming from the text buffers under them.
What is the best way to implement this? I mean, how to retrieve the text view widget concerned by the text change ?
I tried to pass the text view widget object itself on connect for the signal "changed" but it is not working. I also tried the same kind of implementation for buttons and it works perfectly for the "clicked" signal. Why isn't it working for text views with underlying text buffers?
The code for connect:
g_signal_connect(G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(WidgetSecret))), "changed", G_CALLBACK(on_SecretText_changed), WidgetSecret);
and the callback:
void on_SecretText_changed(GtkWidget *p)<

I found another way to make it work. First is to conform to Gtkmm only, and not to mix up Gtk and Gtkmm:
Gtk::TextView* pSecret[21];
Then, retrieve all objects from Glade:
for (int i=1; i<=20; i++) {
sprintf(Bidon, "tvCh%0d", i);
pBuilder->get_widget(Bidon, pSecret[i]);
}
Finally, use sigc::bind to transmit an integer:
int id = 1; // this is the Id to pass to callback for this TextView
pSecret[id]->get_buffer()->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(&on_SecretText_changed), id));
with the following callback:
void on_SecretText_changed(int id)
{
// id is retrieved and used here
}

Related

Controller lifecycle: when to call table.autoResizeColumn()

I'm currently using onAfterRendering() hook to auto adjust the layout of a table like this:
onAfterRendering: function() {
var table = this.getView().byId('table');
for (var i = 0; i < table.getColumns().length; i++) {
table.autoResizeColumn(i);
}
}
The result is not usable: all columns are sized 100% of the parent's width.
If I add a simple button to invoke the exact same logic the table gets drawn nicely. It looks like the complete table needs to be present in the DOM before autoResizeColumn() works properly.
My question: is there a suitable hook/event I can use to invoke the resizing once the table is in the document?
You can use the onAfterRendering of the table as suggested and add an if statement with bResized boolean or some kind of counter to prevent the endless loop.
As others have answered you can put add a function to oTable.onAfterRendering but the trick is if you do any rendering in that function it will trigger another rendering event that will again trigger onAfterRendering.
The problem here is where to hang the boolean switch that determine you have done the thing you have done.
One way to get around that is to add some customer data to the table with oTable.addCustomData.
The pattern becomes :
```
oTable.onAfterRendering = function () {
// check the prototype
// read the custom data
var customData = this.getCustomData();
// confirm *your* custom data is in the array (and not some other custom data)
// if not do your rendering operation and then
// set a switch to custom data
this.addCustomData(new sap.ui.core.CustomData({
key: "myRenderingCheck",
value: "true",
"writeToDom": true
}));

Crossrider : Using mouse position in context menu

We would like to use appAPI.openURL but in place of sending the data.selectedText I woould like to send the text of the element under the mouse. But I can't find the way of getting the mouse position. My idea was to add in the appAPI.ready the following
$().mousemove(function(event) {
myPositionX = event.pageX ;
myPositionY = event.pageY ;
}
And to have two global variable myPositionX and myPositionY which I could access in my background code to transmit as parameters of my URL.
But this doesn't seem to work.
Is what I'm doing crazy?
You'll be pleased to note that your are not crazy but simply missed the selector required to attach the handler to the page. Hence, to make you code work, bind the mousemove handler to the document object per the following tried and tested code:
$(document).mousemove(function(event) {
myPositionX = event.pageX ;
myPositionY = event.pageY ;
});

gtkentry focus behaviour

Is there any existing mechanism for a GtkEntry to simply position the cursor at the end of the text when focused, rather than selecting its contents to be overwritten by the next key? It seems odd to have to add a signal handler to do something this basic, but I can't find anything in the properties.
Edit: The signal handler doesn't work; whatever I do the default behaviour gets triggered after my handler runs. Here's my gtkd code; note that I am appending some text in the focus-in-event handler, and the appended text gets selected as well:
class NoteView : Entry
{
this(string text) {
if (text) {
setText(text);
}
setEditable(true);
setCanFocus(true);
addOnFocusIn(delegate bool(GdkEventFocus* f, Widget w) {
// clear selection
selectRegion(0, 0);
// test to see whether the appended text gets selected too
appendText("hello");
setPosition(-1);
// don't let any other handlers run
return 1;
}, ConnectFlags.AFTER);
}
}
The addOnFocusIn method is in the gtkd Gtk.Widget api; it calls g_signal_connect_data internally, which should in theory be honouring the G_CONNECT_AFTER flag I'm passing it, but doesn't seem to be.
Edit2: Solved - the grab-focus handler was doing the text selection, and being handled after focus-in-event
Turns out GtkEntry was selecting the text on the grab-focus signal, not focus-in-event. Working code:
class NoteView : Entry
{
this(string text) {
if (text) {
setText(text);
}
setEditable(true);
setCanFocus(true);
setHasFrame(false);
addOnGrabFocus(delegate void(Widget w) {
selectRegion(0, 0);
setPosition(-1);
}, ConnectFlags.AFTER);
}
}
Can't find anything in the docs.
I guess they figured that diverging from the default behavior is that uncommon that they just let people do it with signals, rather than provide a property for it.
Consider creating a subclass of GtkEntry that exhibits the behavior you require.

How to add a GWT click listener to an Image?

I want to click on an image and therefore want to register (e.g.) a ClickHandler. The image I get from a ClientResource. This works so far to set the image into a table cell:
MyResources.INSTANCE.css().ensureInjected();
Image colorImage = new Image( MyResources.INSTANCE.colorImage() );
Element colorImageElement = colorImage.getElement();
colorImage.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println( event );
}
} );
TableElement table = Document.get().createTableElement();
TableRowElement headRow = table.insertRow(-1);
headRow.insertCell(-1).appendChild( colorImageElement );
RootPanel.get().getElement().appendChild( table );
How can I add a listener to the icon? I tried ClickHandler and to put the image on a PushButton and get the Element from this PushButton but all don't work.
But mind, if I add the widget (Image is a Widget) to a panel it works!
RootPanel.get().add( colorImage );
But I am not working with widgets here but with the Element. So the handler disappears and that's the point I don't get how to preserve this added handler information.
In the end I would like to build a table with different rows where I can click on the icon I get a popup menu and thereby change the colour of the row.
You should be able to just add a ClickHandler (or a MouseDownHandler if that fits your needs better).
Like this:
colorImage.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// Do something....
}
});
Don't unwrap your widget and append only the DOM elements. The Widget class allows your code to refer to both elements and events at the same time, and deals with possible memory leaks, as well as grouping your code in logical ways.
This might make sense for other frameworks, but in GWT you almost always want to work with the Widgets directly, adding them together, then appending them to the RootPanel.
If you really want to use a html table to build this up, look at the com.google.gwt.user.client.ui.HTMLTable subclasses, com.google.gwt.user.client.ui.Grid and com.google.gwt.user.client.ui.FlexTable. This probably should never be necessary, unless you are adding multiple items to the table - when trying to specify layouts, use actual layout classes.
did you tried to add image.sinkEvents( Event.ONCLICK | Event.MOUSEEVENTS )?
The image has to be inside a focus widget. I don't know why that is, but somewhere the events don't get propagated right and the DOM events don't fire.

Using the Selection service on something that is *not* a JFace view

I am building an image Editor as an Eclipse plugin.
I would like to use the Properties view to view & edit properties of the model underneath the image. Accordingly I am calling ..
getSite().setSelectionProvider( this );
.. within createPartControl, and implementing the ISelectionProvider interface in my EditorPart implementation, so that the model is returned as the selection (which must therefore implement the ISelection interface).
The next step is for the Editor to implement IAdaptable to supply an adapter for the selected object.
My problem however is that getAdapter is never called with IPropertySource.class, and therefore the Properties View never gets what it needs to make sense of the image model.
Your help is much appreciated.
M.
The answer in the end broke down into a few pieces ...
1.) When your selection does change (if a user has zoomed into the image, for example) be sure to tell Eclipse this. It won't happen otherwise.
2.) When sending your SelectionChangedEvent, wrap up your IAdaptable in a StructuredSelection object - otherwise the Properties view will ignore it.
This boiled down to the following method
public void fireSelectionChanged()
{
final SelectionChangedEvent event = new SelectionChangedEvent( this, new StructuredSelection( this ) );
Object[] listeners = selectionChangedListeners.getListeners();
for (int i = 0; i < listeners.length; ++i)
{
final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
SafeRunnable.run(new SafeRunnable() {
public void run() {
l.selectionChanged( event );
}
});
}
}
... on an class that implemented ISelectionProvider & IAdaptable.
M.