What does this expression do? Gui % (MainGui:=!MainGui) ? "Hide" : "Show" - if-statement

I find this code on this thread: Suspending, Pausing, Hiding, Pulling Up GUI Window:
Gui % (MainGui:=!MainGui) ? "Hide" : "Show"
What does it do? I guess it's a kind of a simple if expression for hotkeys, but checking the examples on the two pages I don't see where it locates.
If SetTimer is used, the counter will only increase if that code is put inside the subroutine. If put outside, the counter stops.
Gui +LastFound +AlwaysOnTop +ToolWindow -Caption
Gui, Add, Text, vcounter, 00000
Gui, Show, NoActivate
SetTimer, Update, 100 ; 100 ms
Update:
counter++
GuiControl,, counter, %counter%
^esc::Gui % (MainGui:=!MainGui) ? "Hide" : "Show"
Return

It is a kind of operator in expressions:
Ternary operator [v1.0.46+]. This operator is a shorthand replacement
for the if-else statement. It evaluates the condition on its left side
to determine which of its two branches should become its final result.
For example, var := x>y ? 2 : 3 stores 2 in Var if x is greater than
y; otherwise it stores 3. To enhance performance, only the winning
branch is evaluated (see short-circuit evaluation).
The command ^esc::Gui % (MainGui:=!MainGui) ? "Hide" : "Show" has two parts.
(MainGui:=!MainGui) Switches the value of the variable MainGui
to it's oposite, usually from True to False and vice versa.
Uses the standard form of the ternary operator to check the value of
the variable MainGui. If it is True it uses the value Hide,
if it is False it uses the value Show.
^esc::Gui % (MainGui:=!MainGui) ? "Hide" : "Show" translates to one of the following after all evaluations:
1. If MainGui is True ==> Gui Hide
2. If MainGui is False ==> Gui Show
Short explanation: The ^esc hotkey hides the Gui if it is active, shows it if it is hidden.

Related

Is there a suitable pattern to combine key bindings?

Making a RTS logic on UE4. I can bind class methods or lambdas to "OnPressed", "OnReleased", and "Axis" signals. Thinking about using the Guarded State Machine pattern with the Command pattern to define key conjunctions, but there is no trivial way to determine a final command at the last step. Need something like morphs.
For e.g.:
LeftClick = Nothing
LeftClick + Unit under cursor = Select unit
Shift + LeftClick = Nothing
Shift + LeftClick + Unit under cursor = Add unit to selection
Shift + LeftClick + Moving cursor + Units under cursor = Add units to selection
Ctrl + LeftClick + Unit under cursor = Remove unit from selection
RightClick = Nothing
RightClick + Units selected = Move units
Perhaps I should use the Behavior Tree pattern instead of the State Machine pattern? But the tree will be so big (the example just has been simplified).
Heyo, good first question! Apologies for the sloppy answer but a few key points:
For inputs to be used in conjunction, you'll need to manually handle the state yourself. For example, if you wanted Ctrl then LeftClick to do something different from LeftClick, then you'll need to remember that Ctrl was clicked earlier and do different behavior. In practice, this tends to be...
In Ctrl OnPressed, set a bool to true (and OnReleased set it to false)
In LeftClick OnPressed, check if that bool is true. If it is, do X behavior. Otherwise do Y behavior
Note that this is independent of your design pattern of choice. ie, regardless of whether you use a behavior tree or a state machine, you'll need to remember what happened with prior keys in order to do behavior in conjunction
On a final point - and apologies if I misunderstood the question - but you seem to be overcomplicating determining input combinations vs corresponding behavior with a given set of inputs. ie, LeftClick + "Unit under cursor" (assuming "Unit under cursor" isn't already stored state) isn't a separate input from LeftClick but rather what you check after the LeftClick OnPressed event occurs
No matter what design pattern you choose, you'll need to handle this on a case by case basis as coding/implementation normally goes. ie, "Did my raycast hit a unit or not?" -> { choose behavior } will occur either way. I'm assuming this is what you're referring to as "morphs" and "final command"

QProgressDialog: problems about MinimumDuration

I'm using QT 4.8.5. I met some problems on QProgressDialog with MinimumDuration.
Here is the documentation: http://doc.qt.io/qt-4.8/qprogressdialog.html#minimumDuration-prop.
1.Test with the following code. The dialog is not displayed at all. But the documentation says: "the dialog will pop up after the minimumDuration time or as soon as any progress is set".
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
2.Test with the following code. The dialog is displayed in 8 seconds. But the documentation says: "the dialog will pop up after the minimumDuration time or as soon as any progress is set". Though the behavior is different with the documentation, I think the current behavior is acceptable.
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
dlg->setValue(0);
3.Test with the following code. The dialog is never displayed. But the documentation says: "the dialog will pop up after the minimumDuration time or as soon as any progress is set".
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
dlg->setValue(1);
4.Test with the following code. The behavior is same as item 2.
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
dlg->setValue(0);
dlg->setValue(1);
5.Test with the following code. The dialog is displayed as soon as set the progress value to 1. Why does Sleep() function affect the behavior here?
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
dlg->setValue(0);
::Sleep(static_cast<DWORD>(1000));
dlg->setValue(1);
6.Test with the code below. The dialog is displayed immediately, but I set MinimumDuration to 5. Is it a problem?
QProgressDialog* dialog = new QProgressDialog("Message", "Close", 1, 10);
dialog->setMinimumDuration(5000);
dialog->setValue(0);
dialog->setValue(1);
I test on Windoes 7. What are the issues? What are the correct behaviors?
Indeed the information is scattered around so it seems to make no sense. But there is a precious hint in the doc :
QProgressDialog ... estimates the time the operation will take
(based on time for steps), and only shows itself if that
estimate is beyond minimumDuration() (4 seconds by default).
The dialog seems to use the value property to approximate the time required for steps. And it is seems that value property by default is not set
value property :
For the progress dialog to work as expected, you should initially set
this property to 0 and finally set it to QProgressDialog::maximum();
Indeed, dialog->value() returns -1 in my machine after construction.
To wrap up :
Not setting value is an issue. You have to set value sometimes to make it work.
The dialog is shown as soon as it interpolates that the total amount of work is going to take more than minimumDuration
Setting a value to anything lower than QProgressDialog::minimum(), which is the case by default, causes the progressbar to stay hidden.
Your second cases set the value to 0 = minimum. After 8 seconds, you still havent updated that value. which means the processing of a single item take more than 8 seconds. Should show.
You should modify the value from 0 -> minimum -> maximum for proper behavior. Your third case, fail to do this because value goes from -1 to 1, without being set to 0 = minimum. Unspecified, in this version doesnt show.
Your 4th case means "the first processing took 0 second, the second is not done yet". So the minimumDuration behavior kicks in. Should show.
Now that there is one second duration for the first task (case 5), the dialog approximates that 10 tasks are going to take 10s, which is bigger than 8s, so the dialog is shown as soon as dlg->setValue(1); is executed.
I tested this on OS X, with Qt 5 and get the same results
Looking closer at the documentation for setValue, it states: -
For the progress dialog to work as expected, you should initially set this property to QProgressDialog::minimum() and finally set it to QProgressDialog::maximum(); you can call setValue() any number of times in-between.
With this in mind, it works as expected, as can be seen when you first set the value to zero, then another value.
QProgressDialog* dlg = new QProgressDialog("Test", "cancel", 0, 10);
dlg->setMinimumDuration(8000);
dlg->setValue(0);
dlg->setValue(1);
So, I think the documentation for setMinimumDuration should probably link to this too, but the behaviour is correct according to the documentation, when taking setValue into account.

MFC's CTabCtrl::HitTest function returns "1" for any tab clicked

Hi (although greeting usually gets deleted),
I'm using the MFC's CTabCtrl control and try to determine which tab was clicked (to drag & drop it later). Should be quite easy I thought - anyway got stuck with the HitTest function which returns "1" for whichever tab is clicked.
As I started the project very recently, it's literaly just a handful of lines. The mentioned HitTest function is used in Tdi.cpp file in CHlavniOkno::CTdi::OnLButtonDown function (full source code at http://nestorovic.hyperlink.cz/cpp_mfc.zip ):
afx_msg void CHlavniOkno::CTdi::OnLButtonDown(UINT flagy,CPoint bod){
if (::DragDetect(m_hWnd,bod)){
TCHITTESTINFO hti={bod};
if (int idZalozky=HitTest(&hti)>=0)
parametryTazeneZalozky=new TParametryTazeneZalozky(this,idZalozky);
}
CTabCtrl::OnLButtonDown(flagy,bod);
}
I definitely must have omitted something tiny, as is almost always the case...
Thanks for your time by having a look at the problem.
Tomas
The statement int idZalozky=HitTest(&hti)>=0 is setting idZalozky to the result of the test HitTest(&hti)>=0. As a boolean test this will always return either 0 or 1.
You probably want:
int idZalozky=HitTest(&hti);
if (idZalozky>=0)
{
...
}

Order and manner of property binding evaluations in QML

From what I understand, when properties are used in binding expressions, their NOTIFY signals are connected to signal the reevaluation of the expression every time a property value is changed.
So consider this trivial example:
Rectangle {
width: 200
height: width - 100
Text {
text: "value is " + (parent.width + parent.height)
}
}
In it the height property is bound to the width property, and the text property is bound to both.
In this example, it is not clear what is the order of operation. I mean if width changes, it will emit to reevaluate both of the expressions which reference it. But width will also change height which itself will trigger evaluation of text as well.
Is the text property therefore evaluated twice? Once when width changes, and once again when width changes height? Or maybe QML has some mechanism of optimizing that behavior away, like for example the notification signals do not trigger actual reevaluation but only mark the expressions "dirty" and they are reevaluated on the next event loop iteration, when all signaling has been propagated? And even so, how would the engine know to update height before updating text to avoid the double reevaluation of the latter? Or maybe the connection is direct rather than queued, and some more complex mechanism is used to figure out the order of reevaluation? Or maybe there is nothing of the sort and text might actually reevaluate twice if it just so happens to be the arbitrary order?
I really need to understand how this works, because I have a project where I modify multiple properties of multiple QML objects on the C++ side in a imperative manner which are bound on the QML side and I get very inconsistent and erratic behavior, so I definitely need to take into consideration the way those work.
Yes. it looks that you are right and text will be update twice. The simple example:
Rectangle {
id: testRect
width: 200
height: width - 100
Text {
text: "value is " + (parent.width + parent.height)
onTextChanged: {
console.log("text was changed (" + parent.width + "," + parent.height + ")");
}
}
MouseArea {
anchors.fill: parent
onClicked: {
testRect.width = 300
}
}
}
output:
qml: text was changed (200,100)
qml: text was changed (300,100)
qml: text was changed (300,200)
I guess it's simple behavior and updates relevant property when changes some properties this item based on.
Qt docs advices to avoid such situation - However, if a binding is overly complex - such as involving multiple lines, or imperative loops - it could indicate that the binding is being used for more than describing property relationships. Complex bindings can reduce code performance, readability, and maintainability. It may be a good idea to redesign components that have complex bindings, or at least factor the binding out into a separate function.

Proper way to get 'infinite loading' progress bar with minimum duration delay using QProgressDialog

Problem
I am trying to use QProgressDialog to display a modal dialog window that shows an 'infinite loading' progress bar, but which also takes advantage of the minimum duration which can be specified before showing the window. I am able to do it using a bit of hacky code, but wanted to ask if there is a more correct way to do it.
Use case
A query is made to some back-end service and the results may come quickly or may take a little more time. If the results are returned 'quickly', eg < 500ms, no dialog should show (to avoid a dialog box flickering on screen). If the results take 'more time', the modal dialog should appear (allowing the user to potentially cancel the operation, etc).
Code
Initialization
m_progress = new QProgressDialog(this);
m_progress->setWindowModality(Qt::WindowModal);
m_progress->setLabelText("Looking up data...");
m_progress->setMinimumDuration(500);
connect(m_progress, SIGNAL(canceled()), this, SLOT(onProgressCanceled()));
'Look up data' button onClicked slot (sends request to back-end and shows dialog)
// HACKY CODE ----------
//
m_progress->setMaximum(100); // some value != 0 (0 is the value passed to setValue)
m_progress->setValue(0); // starts the minimum duration timer
m_progress->setMaximum(0); // set maximum to 0 to get 'infinite loading' progress bar
//
// HACKY CODE ----------
onProgressCanceled slot
m_progress->reset();
onResults method (callback that handles returned results)
m_progress->reset();
That is the entirety of the relevant code.
The reason for the hack is that in the Qt source, there is this explicit check:
(d->bar->value() == -1 && progress == d->bar->maximum())
If the maximum is set to 0 (for 'infinite loading') before the value is set to 0 (which starts the minimum duration timer), then QProgressDialog::setValue simply returns. The d->bar->value is initialized to -1 and reset to -1 when QProgressDialog::reset is called. It's almost as if this specific use case of QProgressDialog ('infinite loading' but with a minimum duration delay) is being singled out.
Question
Is there a way to achieve the same result but without the use of the hacky code that I'm missing? I feel like I'm missing something simple.