按钮处理(伪代码/c)
我有一个按钮,我希望它能根据用户的动作做出反应。 这是: 你可以看到它有4种不同的状态。第一个是当没有执行任何特定操作时(按钮处理(伪代码/c),c,button,pseudocode,C,Button,Pseudocode,我有一个按钮,我希望它能根据用户的动作做出反应。 这是: 你可以看到它有4种不同的状态。第一个是当没有执行任何特定操作时(NONE),第二个是当鼠标指针悬停在按钮上时(HOVER),第三个是当鼠标当前正在单击按钮时(ONCLICK),最后一个是当按钮被单击时(已选择) 即使我们不太在意,按钮图如下所示: 这些状态显示为枚举: enum button_states { NONE, HOVER, ONCLICK, SELECTED, BSTATE_LAST }; 现在我尝试了一些代码来更改按
NONE
),第二个是当鼠标指针悬停在按钮上时(HOVER
),第三个是当鼠标当前正在单击按钮时(ONCLICK
),最后一个是当按钮被单击时(已选择
)
即使我们不太在意,按钮图如下所示:
这些状态显示为枚举:
enum button_states { NONE, HOVER, ONCLICK, SELECTED, BSTATE_LAST };
现在我尝试了一些代码来更改按钮的状态,这些代码是在无限循环中执行的。我有一个变量prevState
,它保存最后一次单击之前的状态,还有一个变量previouslyClicked
,如果单击在最后一次循环迭代中处于活动状态,则值1,否则值0
if (CursorIsOnTheButton()) {
if (LeftClickIsActive()) {
if (actualState != ONCLICK)
prevState = actualState ;
previouslyClicked = 1;
actualState = ONCLICK;
}
else if (prevState == SELECTED && previouslyClicked) {
actualState = HOVER;
prevState = NONE;
previouslyClicked = 0;
}
else if (prevState == HOVER && previouslyClicked) {
actualState = SELECTED;
prevState = NONE;
previouslyClicked = 0;
}
else
actualState = HOVER;
}
else if (actualState != SELECTED)
actualState = NONE;
除了选定的状态外,它工作正常:按钮永远不会进入该状态
我做错了什么?编写代码是为了将所选内容从任何一个块中排除:
if (CursorIsOnTheButton()) {
if (LeftClickIsActive()) {
//if execution flow ever goes into this section...
//(i.e. if SELECTED is set here, because you are in this block, it cannot be recognized by the
//else if block, because it can only go in there if it did NOT go into this one.)
}
}
//...it will never go into the else if
else if (actualState != SELECTED)
actualState = NONE;
修改代码以将选定状态包括在与其他状态相同的块中
将此代码段添加到if块:
else if (actualState == SELECTED) {
//do something
}
解决问题 编写代码是为了将所选内容从任何一个块中排除:
if (CursorIsOnTheButton()) {
if (LeftClickIsActive()) {
//if execution flow ever goes into this section...
//(i.e. if SELECTED is set here, because you are in this block, it cannot be recognized by the
//else if block, because it can only go in there if it did NOT go into this one.)
}
}
//...it will never go into the else if
else if (actualState != SELECTED)
actualState = NONE;
修改代码以将选定状态包括在与其他状态相同的块中
将此代码段添加到if块:
else if (actualState == SELECTED) {
//do something
}
解决问题 创建这样一个函数。。。无论何时,只要您将某个对象标记为选定对象,就可以将最近选定的按钮作为第三个参数来调用它
void ClearOthers("Array of buttons" buttons[], int amountOfButtons, int selected)
{
for(int i = 0; i < amountOfButtons; i++)
if(i != selected)
button[i].State = NONE
}
创建一个这样的函数。。。无论何时,只要您将某个对象标记为选定对象,就可以将最近选定的按钮作为第三个参数来调用它
void ClearOthers("Array of buttons" buttons[], int amountOfButtons, int selected)
{
for(int i = 0; i < amountOfButtons; i++)
if(i != selected)
button[i].State = NONE
}
好吧,我也要试一试。我建议重新组织状态变量。去掉实际的和以前的状态,只使用一个
state
作为按钮外观,这将在我们的伪代码片段中设置。摆脱先前点击的按钮(相当于状态==ONCLICK
),并引入按下的按钮,如果按下按钮则为true,如果未按下则为false:
if (CursorIsOnTheButton()) {
if (LeftClickIsActive()) {
if (state != ONCLICK) pressed = !pressed;
state = ONCLICK;
} else {
state = (pressed) ? SELECTED : HOVER;
}
} else {
state = (pressed) ? SELECTED : NONE;
}
ONCLICK
状态在这里起双重作用;它标记了“刚刚点击”的状态,并确保在长时间按下鼠标按钮时不会打开和关闭按钮。所有其他状态由一个简单的逻辑确定:
pressed? in button? clicking? state
------------ ------------ ------------ ------------
true dontcare dontcare SELECTED
false true true ONCLICK
false true false HOVER
false false dontcare NONE
这种方法的优点是,您可以在按下时检查按钮的按下状态,否则必须检查状态
它仍然只是伪代码,这意味着我当然还没有测试它。好吧,我也要试试。我建议重新组织状态变量。去掉实际的和以前的状态,只使用一个state
作为按钮外观,这将在我们的伪代码片段中设置。摆脱先前点击的按钮(相当于状态==ONCLICK
),并引入按下的按钮,如果按下按钮则为true,如果未按下则为false:
if (CursorIsOnTheButton()) {
if (LeftClickIsActive()) {
if (state != ONCLICK) pressed = !pressed;
state = ONCLICK;
} else {
state = (pressed) ? SELECTED : HOVER;
}
} else {
state = (pressed) ? SELECTED : NONE;
}
ONCLICK
状态在这里起双重作用;它标记了“刚刚点击”的状态,并确保在长时间按下鼠标按钮时不会打开和关闭按钮。所有其他状态由一个简单的逻辑确定:
pressed? in button? clicking? state
------------ ------------ ------------ ------------
true dontcare dontcare SELECTED
false true true ONCLICK
false true false HOVER
false false dontcare NONE
这种方法的优点是,您可以在按下时检查按钮的按下状态,否则必须检查状态
当然,这仍然只是伪代码,这意味着我还没有测试它。基于vmp答案和您的大力帮助,我解决了这个问题
我使用vmp的变量actualSelected
和beingClicked
,但不是布尔值,来存储所选按钮和单击按钮的ID
让我解释一下,我想我没有给你留下足够的信息来解决这件事。我不仅有一个按钮,还有一组按钮,按钮[NBUTTONS]
是它们的状态,它们的行为应该和单选按钮完全一样
for (int i = 0; i < NBUTTONS; i++) {
if (IsMouseOnButton(button[i]) {
if (LeftClickIsActive()) {
beingClicked = i;
buttons[i] = ONCLICK;
}
else if (beingClicked == i) {
actualSelected = i;
beingClicked = -1;
for (int j = 0; j < NBUTTONS; j++)
buttons[i] = NONE;
buttons[i] = SELECTED;
}
else if (actualSelected != i) {
buttons[i] = HOVER;
}
}
else if (selected != i)
buttons[i] = NONE;
}
for(int i=0;i
基于vmp答案和您的大力帮助,我解决了这个问题
我使用vmp的变量actualSelected
和beingClicked
,但不是布尔值,来存储所选按钮和单击按钮的ID
让我解释一下,我想我没有给你留下足够的信息来解决这个问题。我不仅有一个按钮,还有一系列按钮,按钮[NBUTTONS]
是它们的状态,它们的行为应该和单选按钮一模一样
for (int i = 0; i < NBUTTONS; i++) {
if (IsMouseOnButton(button[i]) {
if (LeftClickIsActive()) {
beingClicked = i;
buttons[i] = ONCLICK;
}
else if (beingClicked == i) {
actualSelected = i;
beingClicked = -1;
for (int j = 0; j < NBUTTONS; j++)
buttons[i] = NONE;
buttons[i] = SELECTED;
}
else if (actualSelected != i) {
buttons[i] = HOVER;
}
}
else if (selected != i)
buttons[i] = NONE;
}
for(int i=0;i
可能是因为在一个分支中设置了先前单击的,然后在另一个互斥分支中选中了左键单击