I have a GTK Entry called task_input. When the user types something and presses enter, it should "click" start_button. I have tried using connect_activate, which works, but it leaves me with the following error:
Gtk-WARNING **: 01:04:12.779: GtkText - did not receive a focus-out event.
If you handle this event, you must return
GDK_EVENT_PROPAGATE so the default handler
gets the event as well
Here is the code:
fn setup_settings(&self) {
let imp = imp::MyWindow::from_instance(self);
imp.task_input.connect_activate(clone!(#strong imp.start_button as start => move |_| {
start.emit_clicked();
}));
}
I believe there is also another way to do this by using imp.task_input.set_activates_default(true); but I have not been able to figure out how to get that to work.
What is the best way to activate a button by pressing Enter from an Entry widget?
Related
I'm trying to capture up a right click event on a TreeView I have in my application using Rust and gtk4-rs. I don't see a specific EventController for mouse buttons events. I do see EventControllers for things like keyboard presses and motion events. I ended up using the EventControllerLegacy and just detecting the event type inside the closure, but I feel like I'm missing something here. Is there some other way I should be getting button press events from the mouse? Here's my code:
pub fn build_tree_view() -> TreeView {
let tree_view: TreeView = TreeView::new();
tree_view.set_headers_visible(false);
let event_controller = EventControllerLegacy::new();
event_controller.connect_event(|controller, event| {
if event.event_type() == ButtonPress {
let button_event = event.clone().downcast::<ButtonEvent>().unwrap();
if button_event.button() == GDK_BUTTON_SECONDARY as u32 {
println!("got mouse button: {}", button_event.button());
}
}
return Inhibit(false);
});
tree_view.add_controller(&event_controller);
return tree_view;
}
The reason I believe I am missing something is that the documentation for EventControllerLegacy states the following:
EventControllerLegacy is an event controller that provides raw access to the event stream. It should only be used as a last resort if none of the other event controllers or gestures do the job.
I am using Rust 1.56.0 and gtk4-rs 0.4.2
Thanks
If you look into the examples, normally in such a case gtk::GestureClick is used.
To detect right clicks, you can use it like so:
pub fn build_tree_view() -> TreeView {
let tree_view: TreeView = TreeView::new();
tree_view.set_headers_visible(false);
// Create a click gesture
let gesture = gtk::GestureClick::new();
// Set the gestures button to the right mouse button (=3)
gesture.set_button(gtk::gdk::ffi::GDK_BUTTON_SECONDARY as u32);
// Assign your handler to an event of the gesture (e.g. the `pressed` event)
gesture.connect_pressed(|gesture, _, _, _| {
gesture.set_state(gtk::EventSequenceState::Claimed);
println!("TreeView: Right mouse button pressed!");
});
// Assign the gesture to the treeview
tree_view.add_controller(&gesture);
return tree_view;
}
Note: Example is for Rust 1.58 and gtk4 0.4.4 but the differences should be minor if any.
Ive got a working grid, using in-line editing thanks to this example
https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-row-click/
What I need to do now, is force the saving upon a user hitting the enter key, instead of clicking away onto another row or away from the current row. I suppose I could add a "save" button in the header?
You could probably use cellClose event in your html (cellClose)="cellCloseHandler($event)" - API Documentation
You could then write your own code (in typescript) in cellCloseHandler() to modify and save the updated items accordingly.
From Kendo UI for Angular Documentation:
In-Cell Editing
You could capture the Enter key hits and force executing cellCloseHandler() like that:
#HostListener('keydown', ['$event'])
public keydown(event: any): void {
console.log("keydown event", event);
if (event.keyCode === 13) {
this.cellCloseHandler();
}
}
Similar to Giannis answer but with small modifications:
Add keydown event to kendo-grid tag.
Call grid.closeCell() instead of calling the closeHander directly.
Template
<kendo-grid #grid
[data]="data$ | async"
(cellClose)="cellCloseHandler($event)"
(keydown)="onKeydown(grid, $event)"
>
Class
onKeydown(grid: GridComponent, e: KeyboardEvent) {
if (e.key === 'Enter') {
grid.closeCell();
}
}
cellCloseHandler(args: CellCloseEvent) {
const { formGroup, dataItem } = args;
// save to backend etc
}
Calling grid.closeCell(); will make the grid to call cellCloseHandler
You dont have to implement a HostListener for Keydown by yourself. If you set the input navigable to true, the cellClose event will get triggered when pressing Enter while editing a cell or row. This way you get the data of the row in your cellCloseHandler aswell for saving it.
<kendo-grid [navigable]="true" (cellClose)="cellCloseHandler($event)"></kendo-grid>
I'd like to have multiple buttons on HeroCard
and be able to press all buttons one after another
but when I press click button program jumps to next function in waterfall
and expects next action instead of button action again
what should I do in this case?
bot.dialog("/showCards", [
(session) => {
const msg = new Message(session)
.textFormat(TextFormat.xml)
.attachmentLayout(AttachmentLayout.carousel)
.attachments([{
title: "title",
url: "https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png"
}].map(obj =>
new HeroCard(session)
.title(obj.title)
.images([
CardImage.create(session, obj.url)
.tap(CardAction.showImage(session, obj.url)),
])
.buttons([
CardAction.openUrl(session, obj.url),
CardAction.imBack(session, `click`, "Click"),
CardAction.imBack(session, `clack`, "Clack")
])
));
Prompts.choice(session, msg, ["click", "clack"]);
},
(session, results) => {
// todo use results.response.entity
}
]);
You could also use CardAction.dialogAction and link every button to a beginDialogAction.
let card = new builder.HeroCard(session)
.title(title)
.subtitle(subtitle)
.buttons([builder.CardAction.dialogAction(session, 'dialogAAction', 'dataYouNeedInDialogA', 'ButtonTitleA'), builder.CardAction.dialogAction(session, 'dialogBAction', 'dataYouNeedInDialogA', 'ButtonTitleB')]);
let msg = new builder.Message(session)
.attachments([card])
session.endDialog(msg);
// use one of these two to either end the dialog and start a new one or to stay in the current dialog and wait for user input
session.send(msg);
// don't forget to add the dialogs to your bot / library later in your code (outside your current dialog)
bot.dialog('dialogA', dialogA); // initialized somewhere in your code
bot.dialog('dialogB', dialogB);
bot.beginDialogAction('dialogAAction', 'dialogA');
bot.beginDialogAction('dialogBAction', 'dialogB', {
onSelectAction: (session, args, next) => {
// you might want to clear the dialogStack if the button is pressed. Otherwise, if the button is pressed multiple times, instances of dialogB are pilled up on the dialog stack.
session.clearDialogStack();
next();
}
});
In my opinion, this is the best way to achieve the behaviour you described so far. All buttons work whenever the user presses them, even if they scroll back in the conversation and press the same button again. The only trade-off is that you have to pass data to the new dialog and can not use dialogData throughout the whole flow. Nevertheless, I think it's worth it because ensures consistent UX throughout the usage of the bot.
Hope this helps. You can build click and clack dialogs, link them to actions and pass the data that you need. The user would be able to press click, clack, click and the bot would still work. :)
Use a switch-case in the ResumeAfter function, in the default case send the user to the previous function.
I have a flash movie I am making that has a search box and a search button. The button has this code:
on (release, keyPress "<Enter>") {
searchbox.execute();
/*the function above processes searches*/
}
Clicking on the button works just fine. Pressing Enter doesn't do a bean! Does anyone know why this is, and any ways I can work around it? I'd prefer not to use listeners if I can possibly avoid it at all.
Using on() is a deprecated AS1 practice, so maybe you should just stop using it. Thanks to the onKeyDown event handler of the MovieClip class, it is possible to use proper code to do it without listeners, so you don't have to worry about them. ;)
Anyway, on with the code. Type this into the timeline which contains the button:
//Enable focus for and set focus to your button
searchButton.focusEnabled = true;
Selection.setFocus(searchButton);
//The onRelease handler for the button
searchButton.onRelease = function(){
//You need this._parent this code belongs to the button
this._parent.searchbox.execute();
}
//The onKeyDown handler for the button
searchButton.onKeyDown = function(){
//Key.getCode() returns the key code of the last key press
//Key.ENTER is a constant equal to the key code of the enter key
if(Key.getCode() == Key.ENTER){
this._parent.searchbox.execute();
}
}
I have a modal dialog box presented in Yahoo UI. The user selects a value from dialog "A", and then I want to present another modal dialog box to collect some more data in dialog "B".
I have been using the YAHOO.widget.Dialog successfully. The problem seems to be that you can't initiate dialog window "B" from the handler function of dialog "A". So, how can you programmatically launch a second dialog window after the user hits the "OK" button on the first ?
(I had tried to create an additional Listener for a field that is updated in dialog "A" to trigger dialog "B" but this doesn't work either.)
Thanks..
Check out the documentation: http://developer.yahoo.com/yui/container/dialog/#events. The following code should do the trick:
var firstDialog = new YAHOO.widget.Dialog('firstDialog', { postmethod: "manual" });
firstDialog.manualSubmitEvent.subscribe(function (type, args) {
var nextDialog = new YAHOO.widget.Dialog('nextDialog', { });
/* more configuration stuff... */
nextDialog.render();
nextDialog.show();
});
firstDialog.render();
firstDialog.show();
This handles when the form is to be submitted, which I think what you mean by selects a value, but if not let me know and I can give some help on that situation.