I am trying to disable double clicking a Help label which is an anchor to open the Help window.
<p:a id="helpClick" onClick="help()">
<label value="Help" style="color:#FFFFFF;" />
</p:a>
When onClick() event is triggered once, either by Mouse click or Tapping the touchpad once, the help() method is being invoked.
void help() {
flag = true;
this.helpClick.setDisabled(true);
Window popupWindow = null;
popupWindow = (Window) Executions.createComponents("/zul/mainHelp.zul",
null, null);
this.popupWindow.setClosable(true);
popupWindow.addEventListener("onClose", new EventListener() {
void onEvent(Event event) throws Exception {
this.helpClick.setDisabled(false);
}
});
}
is the code which i added to handle the anchor tag with the id helpClick.
This is working perfectly fine when i use mouse clicks. For the first click, the window gets opened and simultaneously the Label is not taking any more click events.
When i try the same with mouse tap(using the touchpad), two single clicks are being triggered.
I have used onClick() to capture the event.
I am trying to disable the Label once it is clicked and the window is opened. Only after the window gets closed, i am enabling the label.
This is working totally fine when i use mouse clicks but not when i use tap.
With tapping, the label is taking multiple clicks which isnt the case with Mouse Click.
Without seeing code it's difficult to provide advice but maybe you can capture the onDoubleClick event and ignore it or forward it to the to the same listener as your onClick event.
... forward="onClick=onHelpClick,onDoubleClick=onHelpClick" ...
After question edit:
It sounds like a bug if you can double click a disabled component. One thing you could try is set your link to autodisable <p:a id="helpClick" onClick="help()" autodisable="self"> as per A component documentation
Related
I am creating an application that should work on desktop and some mobile platforms.
The following example creates and connects my portrait/landscape buttons, in a group, to a slot, on the release signal.
m_landscapeRadio = new QRadioButton(QObject::tr("Landscape "));
m_portraitRadio = new QRadioButton(QObject::tr("Portrait "));
m_orientationGroup.addButton(m_landscapeRadio, 0);
m_orientationGroup.addButton(m_portraitRadio, 1);
m_orientationGroup.setExclusive(true);
m_landscapeRadio->setChecked(true);
connect(&m_orientationGroup, SIGNAL(buttonReleased(int)), this, SLOT(orientationSlot(int)));
But I found a weird situation:
Assume landscape button is checked. If I press and drag away from the portrait radio button, the slot action is performed (for the portrait option) but the portrait button is not checked.
I would like the action not to be performed.
For now...
In the orientationSlot I test the argument and set the checked value myself... Though I really expected the buttons to know to do that themselves.
But I think it is more expected by users that, if the press a button and change their mind, to be able to drag away from the button and not have the action be performed.
I can handle verifying if the check really happened in the action slot, and either check or discard the action depending on how I will think the user experience is better...
If I want the buttons to be checked and to perform the action as well:
void MyWidget::orientationSlot(int checked)
{
if(checked) m_portraitRadio->setChecked(true);
else m_landscapeRadio->setChecked(true);
.... actual actions
}
If I want the action not to be performed when the user drags away from the button (my preferred option):
void MyWidget::orientationSlot(int checked)
{
if(m_orientationGroup.checkedId() != checked) return;
.... actual actions
}
I use QRadioButton and handle mouse button being released event for reacting
on radio button being switched. It causes problems altogether with dragging event. I would like to either get the button
to be checked, or the action not to be performed.
http://doc.qt.io/qt-5/qradiobutton.html
Whenever a button is switched on or off, it emits the toggled()
signal. Connect to this signal if you want to trigger an action each
time the button changes state. Use isChecked() to see if a particular
button is selected.
Either you connect the radio button to the handler explicitly or the whole group: http://doc.qt.io/qt-5/qbuttongroup.html#buttonToggled
void QButtonGroup::buttonToggled(QAbstractButton *button, bool
checked)
This signal is emitted when the given button is toggled. checked is
true if the button is checked, or false if the button is unchecked.
Note: Signal buttonToggled is overloaded in this class. To connect to
this one using the function pointer syntax, you must specify the
signal type in a static cast, as shown in this example:
connect(buttonGroup, static_cast<void(QButtonGroup::*)
(QAbstractButton *, bool)>(&QButtonGroup::buttonToggled),
[=](QAbstractButton *button, bool checked) {
if (button == m_portraitRadio) {
// Portrait (un)checked
if (checked)
{
// checked!
}
}
/* ... */ });
I am wondering how i can distinguish wheel click event from mouse press event. Because i want to do different handling for these two events in pyside. Currently, every time I click the wheel button, the event is catched by mousepressevent. Can anyone explain ?
Edit: I want to implement this in a subclass of
qglwidget class
From its name, the mousePressEvent is responsible for mouse clicks while the wheelEvent is for scrolling solely. The wheelEvent will not catch the wheel button click. It is how the Qt's API is designed when it comes to mouse events processing.
In order to separate which mouse button is pressed (right, wheel or left), use button property of QMouseEvent.
This is how the code would look like using C++ (I imagine it is easy to translate it to pyside)
void GLWidget::mousePressEvent(QMouseEvent *event) // redefine the mouse event
{
switch( event->button() ) {
case Qt::LeftButton:
// do stuff for left button pressed
break;
case Qt::MiddleButton:
// do stuff for wheel button pressed
break;
// ...
}
}
So, for pyside, you only need to compare the button property of event in mousePressEvent and see whether it is Qt.LeftButton , Qt.RightButton or Qt.MidButton. Hope that helps.
I took the JQuery UI dialog form sample from JQuery UI website.
Since I wanted that, once the dialog is opened and the form is displayed, that pressing the key submits the form, I added the following in the onReady() :
$.extend($.ui.dialog.prototype.options, {
open: function() {
var $this = $(this);
// focus first button and bind enter to it
$this.parent().find('.ui-dialog-buttonpane button:first').focus();
$this.keypress(function(e) {
if( e.keyCode == 13 ) {
$this.parent().find('.ui-dialog-buttonpane button:first').click();
return false;
}
});
}
});
This does perfectly the trick (I mean the click() is triggered when it has to), but the following occurs :
When the form is first submited through a press on the key, the submission is performed once.
If I reopen the dialog, and submit it again with a press on the key, the form is submitted twice.
If I reopen the dialog, and submit it again with a press on the key, the form is submitted three times, and so on...
This can be tested with the following fiddle :
http://jsfiddle.net/fWW2E/
Let me add that doing so by clicking on the dedicated "Submit" button works properly, this fails only when pressing the key is involved.
Any ideas ?
Thank you !
Because since you're assigning this on "open" and your buttons are "closing" the dialog.
When this gets called though:
$('something').dialog('close');
doesn't actually remove the element, it just hides it. So the next time you click to open up a "new" dialog, you're really just showing the first one again. However the "open" event is getting fired again every time it's opened, which is adding a new keypress handler onto it.
Here's the fiddle. I actually write out to the console an array of the current handlers on that element. You'll see everytime you open the dialog that there is another keypress handler.
DEMO
I have two buttons viz. save and update. On both buttons, I am opening pop-up window using Model Pop-up extender. The Pop-up has "ok" as close button. Now what I want is when user clicks on the "Ok" button in the pop-up, it should call the OnClick_save() or OnClick_update() depends on the button who called pop-up.
That means, when user clicks on save button, it will open pop-up window. After entering password in the pop-up window when user click on the Ok button, it should go to the OnClick_save() event. Same thing should happen for update button. How can I do so...???
You can use hidden controls for pop up's OK and Cancel button, and show/hide modal popup programatically. before/after doing so you can call your desired methods or whatever you want to do.
You can do this using event handler..
public delegate void MyEventHandler(object sender, EventArgs e);
MyEventHandler handler = MyEvent;
if(handler != null)
{
handler(this, e);
}
or
this.button1.Click += new System.EventHandler(this.button1_Click);
Or
Write a common method which can invoke from save_click event or ok_click
If you find it useful, please mark it as your answer else let me know...
I have a datagrid that I want the user to sort the rows on. To make it obvious that it's sortable I am implementing some custom cursors. But I'm having a problem when I actually drag an item.
here's a pseudo demonstration of the problem
Application = normal cursor // fine
Rollover datagrid = open hand cursor // good so far
mousedown on datagrid = closed hand cursor // good
dragging item around = closed hand cursor // switches back to normal cursor (if I move it around real fast I can see my custom curser for an instant)
mouse up on datadrid = open hand cursor // not sure, after I drop it goes back to open hand but if I mouse down, dont move and mouse up I have a closed hand
rollout of datagrid = normal cursor //good
datagrid code:
<mx:DataGrid id="sectQuestionsDG" x="10" y="204" width="558" height="277" headerHeight="0" selectable="{editMode}"
dragMoveEnabled="{editMode}" dragEnabled="{editMode}" dropEnabled="{editMode}"
dragDrop="sectQuestReOrder(event);" rollOver="over();" mouseDown="down();" mouseUp="up();" rollOut="out();"/>
functions:
public function over():void{
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,0,0);
}
public function down():void{
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.HIGH,0,0);
}
public function up():void{
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,0,0);
}
public function out():void{
CursorManager.removeAllCursors();
}
Edit 12/17/09:
I've made a little bit of progress, I'm now doing this on rollOver
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor", grabbingCursor);
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW);
This is giving me the correct rollover and correct drag, but if I try to add any
function to rollOut it screws up again, so now I'm stuck with the grabCursor. It
seems like when I set a rollOut on the dataGrid it's firing for each row, same
with mouseOut, is there any way to avoid that?
Edit 12/21/09:
It is a confirmed thing that roll/mouse out/over fire for every item in the datagrid. The solution I need is how to prevent that and only fire it when the user mouses out of the datagrid as a whole. I need flex to see the forest, not the trees.
PS. the rollout only fires on every item when I am dragging. mouseout fires on every item regardless
EDIT 12/21/09, End of the day:
I have managed to answer my own question so my bounty rep is lost to me :-( Anyway since my answer solves my problem I will award the bounty to anyone that can answer this. My solution uses AS to remove the the rollOut/rollOver while a user is dragging. In a dataGrid. How can you get the same result without removing the rollOut/rollOver (so that rollOut is not firing for each item as you drag another item over it)?
Why not use the property isDragging of DragManager if you are doig a drag you dont need to change the cursor. And dont forget to check for the dragExit event in case you drop outside the datagrid.
N.B
sometimes the cursor keep with the dragging shape after the drop so you can in your sectQuestReOrder remove the cursor and set it back to over state.
sample:
public function over(evt:Event):void{ //on mouse over, added with AS
if (DragManager.isDragging) // you are dragging so no cursor changed
return;
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor",grabbingCursor); //style set for the drag cursor
}
public function down(evt:Event):void{ // on mouse down
CursorManager.removeAllCursors();
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.LOW,-7,-7);
}
public function up(evt:Event):void{
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
}
public function out(evt:Event):void{
if (DragManager.isDragging) // you are dragging so no cursor changed
return;
CursorManager.removeAllCursors();
}
public function sectQuestReOrder(e:Event):void{
// sometime you will be stuck with the moving cursor
// so after the drop done reset cursor to what you want
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
...
}
public function onDragExit(e:Event):void {
// in case you go out of the datagrid reset the cursor
// so when you do a drop outside you ll not get one of your dragging cursor
CursorManager.removeAllCursors();
}
And in your grid add dragExit
<mx:DataGrid
id="sectQuestionsDG"
x="10" y="204" width="558" height="277" headerHeight="0"
selectable="{editMode}"
dragExit="onDragExit(event)"
dragMoveEnabled="{editMode}"
dragEnabled="{editMode}"
dropEnabled="{editMode}"
dragDrop="sectQuestReOrder(event);"
rollOver="over(event);"
mouseDown="down(event);"
mouseUp="up(event);"
rollOut="out(event);"/>
I would look at the mouseOut event and determine if its firing when you're moving the mouse during a drag. I have seen cases where the dragged object doesn't move exactly with the mouse, and for a short while, the mouse is actually hovering over another object (causing the mouseOut event to fire, thus changing the cursor).
OK some props to Gabriel there for getting my mind out of a rut and back into this problem in full mode. I had to go through a few steps to get to my answer
1)remove the listeners for rollOver, rollOut, and mouseUp from the mxml and add rollOver and rollOut through the addEventListener method in AS
2) add the listener dragComplete to the mxml and assign the function previously assigned to mouseUP to it
3) change the main function to this:
public function over(evt:Event):void{ //on mouse over, added with AS
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor",grabbingCursor); //style set for the drag cursor
}
public function down(evt:Event):void{ // on mouse down
CursorManager.removeAllCursors();
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.LOW,-7,-7);
sectQuestionsDG.removeEventListener(MouseEvent.ROLL_OVER,over);
sectQuestionsDG.removeEventListener(MouseEvent.ROLL_OUT,out);
//this is why I had to take it off the mxml, can only remove listeners
//added with the addEventListener, I don't remember where I read that.
}
public function up(evt:Event):void{
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
sectQuestionsDG.addEventListener(MouseEvent.ROLL_OVER,over);
sectQuestionsDG.addEventListener(MouseEvent.ROLL_OUT,out);
}
public function out(evt:Event):void{
CursorManager.removeAllCursors();
}