XNA button hovering - button

I have a button in my game. and I want to make it to change to other button image when mouse hover on it and change back when the mouse not in the button.
the problem is when the mouse went out from the button rectangle area, it not change back to the first image
my code like this :
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
MouseState mouseState;
mouseDiBack = false;
mouseState = Mouse.GetState();
if (new Rectangle(mouseState.X, mouseState.Y, 1, 1).Intersects(backButtonRectangle))
{
backButton = backButtonHilite;
}
if ((mouseState.LeftButton == ButtonState.Pressed) &&
(new Rectangle(mouseState.X, mouseState.Y, 1, 1).Intersects(backButtonRectangle)))
{
mouseDiBack = true;
}
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Draw(ScoreBG, ScoreBGRectangle, Color.White);
spriteBatch.Draw(backButton, backButtonRectangle, Color.White);
base.Draw(gameTime);
}
}
}
any idea how I to do it...?

Fairly simple solution, you didn't set the image back on the case where the mouse is not hovering.
if (new Rectangle(mouseState.X, mouseState.Y, 1, 1).Intersects(backButtonRectangle))
{
backButton = backButtonHilite;
}
else
{
backButton = originalImage; //whatever your Texture2D object may be called
}
Don't expect the machine to know that you want to switch back! Machines are stupid! ..Ok, it's actually because you overwrote the value of the variable and didn't reset it.

You are not setting your backButton back to what it used to be when the mouse moves out of the scope area. Take a look at the code below, and notice the added ELSE statement in your Update function.
defaultBackButton = backButton; //Save the default back button somewhere outside your update function
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
MouseState mouseState;
mouseDiBack = false;
mouseState = Mouse.GetState();
if (new Rectangle(mouseState.X, mouseState.Y, 1,1).Intersects(backButtonRectangle))
{
backButton = backButtonHilite;
}
else
{
backButton = defaultBackButton;
}
if ((mouseState.LeftButton == ButtonState.Pressed) && (new Rectangle(mouseState.X, mouseState.Y, 1, 1).Intersects(backButtonRectangle)))
{
mouseDiBack = true;
}
}

As mentioned by Jon you need to set your original texture back when the mouse has left the rectangle.
bool mouseOverBackButton =
mouseX >= buttonRectangle.Left && mouseX <= buttonRectangle.Right &&
mouseY >= buttonRectangle.Top && mouseY <= buttonRectangle.Bottom;
backgroundTexture = mouseOverBackButton ? mouseOverTexture: mouseAwayTexture;
mouseDiBack = mouseState.LeftButton == ButtonState.Pressed && mouseOverBackButton;

Related

How can I change the color of a rectangle?

Where am i going wrong with my logic to simply change the color of the rectangle when clicked?
square.setFill(null);
square.setStroke(Color.BLACK);
setAlignment(Pos.CENTER);
getChildren().addAll(square);
setOnMouseClicked(event ->{
if(event.getButton() == MouseButton.PRIMARY) {
square.setFill(Color.BLUE);
}
else if(square.getFill().equals(Color.BLUE)) {
square.setFill(Color.BLACK);
}
});
I think you dont require a boolean flag. What you are doing can be done as below:
setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.PRIMARY) {
square.setFill(square.getFill() == Color.BLUE ? Color.BLACK : Color.BLUE);
}
});
I ended up using a boolean to flag if the rectangle is blue or not.
square.setFill(null);
square.setStroke(Color.BLACK);
setAlignment(Pos.CENTER);
getChildren().addAll(square);
setOnMouseClicked(event ->{
if(event.getButton() == MouseButton.PRIMARY) {
if(!isBlue) {
square.setFill(Color.BLUE);
isBlue = true;
}
else if(isBlue) {
square.setFill(Color.BLACK);
isBlue = false;
}
}
});
The problem you might find with using a variable is that you have to have a variable which you track for each object that you want to support changing color on or your objects that change color will all be triggered on the same variable.
I think you can keep your original code, I think the issue is your if statement:
setOnMouseClicked(event ->{
if(event.getButton() == MouseButton.PRIMARY) {
square.setFill(Color.BLUE);
}
else if(square.getFill().equals(Color.BLUE)) {
square.setFill(Color.BLACK);
}
If you look at it, the condition is if the getButton is the Primary and if true, it will always set it to blue and if the user didn't use the primary button, it will only set to black if the color is blue.
You want something like:
setOnMouseClicked(event ->{
if(event.getButton() == MouseButton.PRIMARY) {
if(!square.getFill().equals(Color.BLUE)) {
square.setFill(Color.BLUE);
}
else
square.setFill(Color.BLACK);
}
}
}

Qt text editor project: auto-indenting when Enter is pressed after an opening curly brace

I'm working on a text editor project in Qt, and I've added the following method override to a class that's of type QPlainTextEdit:
/* Custom handler for events. Used to handle the case of Enter being pressed after an opening brace.
*/
bool Editor::eventFilter(QObject* obj, QEvent* event)
{
bool isKeyPress = event->type() == QEvent::KeyPress;
if(isKeyPress)
{
QKeyEvent *key = static_cast<QKeyEvent*>(event);
if(key->key() == Qt::Key_Enter || key->key() == Qt::Key_Return)
{
QString documentContents = document()->toPlainText();
if(documentContents.length() >= 1)
{
int indexToLeftOfCursor = textCursor().position() - 1;
if(indexToLeftOfCursor >= 0 && indexToLeftOfCursor < documentContents.length())
{
bool hitEnterAfterOpeningBrace = documentContents.at(indexToLeftOfCursor) == '{';
if(hitEnterAfterOpeningBrace)
{
// TODO determine indentation level of the opening brace
insertPlainText("\n\t\n}");
QTextCursor cursor = textCursor();
cursor.setPosition(cursor.position() - 3);
setTextCursor(cursor);
}
}
}
}
else
{
return QObject::eventFilter(obj, event);
}
}
else
{
return QObject::eventFilter(obj, event);
}
return false;
}
Without the code for setting the text cursor's position, the result looks like this:
The cursor ends up on line 4, and there's a tab on line 2. My intent is to move the cursor so it sits to the right of the tab, so I tried to do that with the code I've written. But that gives me this:
Here, the indent is still on line 2, but now there's an extra line between the tab and the closing brace, which is a little odd.
Even more strange is that this happens regardless of what new position I enter. I tried doing cursor.position() - 2 and cursor.position() - 1 out of curiosity, for example, but I still got the same result.
What am I misunderstanding here about inserting the text and moving the cursor?

Simple Button using DRAW GUI in GameMaker

This is my button under DRAW GUI.
if point_in_rectangle(window_mouse_get_x(),window_mouse_get_y(),790,317,943,385)
{ var hover=1; } else { var hover=0; }
draw_sprite(spr_mainmenu_smallbutton,hover,865,360);
if (distance_to_point(mouse_x,mouse_y)<=0)
{
if mouse_check_button(mb_left)
draw_sprite(spr_mainmenu_smallbutton,2,865,360);
}
draw_set_color(make_colour_rgb(163,190,240));
draw_set_font(fnt_mainmenu_text);
draw_text(865,350,"New Game");
Fairly simple. It draws a rectangle and the text "New Game" on it.
When the mouse hovers over it, it lights up. When you click it, the graphic changes. It's a good button.
The problem occurs when I enter the area of the button while HOLDING the mouse button.
See how it behaves? Instead of lighting up, it gets pressed.
All because I am holding the mouse button as I come in. Any way to avoid this and have it light up instead?
You need use mouse_check_button_pressed() instead mouse_check_button().
Something like this:
Create event:
button_pressed = false;
mouse_over = false;
button_x = 865;
button_y = 350;
button_width = 153;
button_height = 68;
button_left = button_x - button_width div 2;
button_right = button_left + button_width - 1;
button_top = button_y - button_height div 2;
button_bottom = button_top + button_height - 1;
Step end event:
mouse_over = point_in_rectangle(device_mouse_x_to_gui(0), device_mouse_y_to_gui(0), button_left, button_top, button_right, button_bottom);
if !mouse_over
button_pressed = false;
else
{
if mouse_check_button_pressed(mb_left)
{
button_pressed = true;
}
else if mouse_check_button_released(mb_left) and button_pressed
{
// action
show_message("pressed");
}
}
Draw GUI event:
if button_pressed
draw_sprite(sprite_index, 0, button_x, button_y);
else if mouse_over
draw_sprite(sprite_index, 1, button_x, button_y);
else
draw_sprite(sprite_index, 2, button_x, button_y);

Mouse Button click wont register

var note : String = "blah"
function OnGUI()
{
if (IsPaused)
{
GUI.Box (Rect (580,20,100,210), "Pause");
if (GUI.Button (Rect (590,130,80,20), "Info"))
{
Debug.Log("I pressed it");
GUI.Button (Rect (450, 200, Screen.width/2, Screen.height/2), info);
}
else if (GUI.Button (Rect (590,160,80,20), "Quit"))
{
Application.Quit();
}
else if(GUI.Button (Rect(590,190,80,35), "Back"))
{
IsPaused = false;
GetComponent(LookAtMouse).enabled = true;
}
}
This is my function for my GUI, as you can see, i have three buttons within it. The quit and back buttons work fine but when i click the info button, nothing will register.
I put GUI.Button (Rect (450, 200, Screen.width/2, Screen.height/2), info); This line of code outside the if statement to check if it works and it will but when its inside the statement i get nothing.
Can anyone tell me why?
var displayInfo : boolean = false;
if (IsPaused)
{
GUI.Box (Rect (580,20,100,210), "Pause");
displayInfo = GUI.Toggle(Rect (590,130,80,20), displayInfo, "Info");
{
if(displayInfo)
{
GUI.Button (Rect (450, 200, Screen.width/2, Screen.height/2), info);
}
}
#rutter thanks for the idea, i used the boolean idea you had and created a toggle to check, if the info is displayed, create the instance of the textfield when it was toggled on

How to prevent tree items from being dragged into themselves?

I have a flex tree with dragMoveEnabled = true. I want to find out, when an item is dragged into itself or it's children. I'd like to use DragManager.showFeedback(DragManager.NONE) in the tree's onDragOver handler, but can't find out how get this to work. I'm using an ArrayCollection of nested objects as dataSource for the tree.
private function onDragOver(event:DragEvent):void {
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
var index:int = tree.calculateDropIndex(event);
tree.selectedIndex = index;
var subCategory:CategoryVO = CategoryVO(tree.selectedItem);
var currentCategory:CategoryVO = subCategory;
while(currentCategory.parent != 0) {
if (currentCategory.parent == _draggedItem.id) {
DragManager.showFeedback(DragManager.NONE);
return;
}
currentCategory = tree.getParentItem(currentCategory);
if (currentCategory == null) {
break;
}
DragManager.showFeedback(DragManager.MOVE);
tree.showDropFeedback(event);
}
That's how I solved it.
_draggedItem holds the currently dragged item, set in the tree's onDragEnter handler. CategoryVO is the value object I use.
can you do something like:
if(event.currentTarget == event.target){
//item is being dropped on itself
}

Resources