matlabmatlab-figure

How to focus a matlab uifigure


I need to make my code so that when I close the popup window (which appears when the game is paused by pressing space) it re-focuses on the main window. I have tried many things such as using the figure(fig) function, using JavaFrame, minimizing and maximizing the window, making it invisible and visible, updating the window and nothing seems to work. It does not necessarily need to be the focused window if there is some other way so that it continues to receive keyboard inputs. This is my current code which has been trimmed down so that there is no longer a snake or anything else on the screen but instead it just prints out inputs in the console when it detects them.

function Main()
    clc;

    % Create a UIFigure and set its properties
    fig = uifigure('Name', 'Snake Game'); % Set the window title
    fig.Position = [100 100 620 620]; % Position and size of the window
    
    % Create axes inside the uifigure
    ax = uiaxes(fig);
    ax.Position = [10 10 600 600]; % Position of the axes within the window
    ax.XColor = 'none';
    ax.YColor = 'none';
    ax.Color = 'k'; % Background color
    ax.DataAspectRatio = [1 1 1]; % Ensure the plot is square
    
    screenSize = 600;
    ax.XLim = [-screenSize/2, screenSize/2];
    ax.YLim = [-screenSize/2, screenSize/2];
    hold(ax, 'on');
       
    % Set initial game state (paused)
    gameData.game_paused = false;
    fig.UserData = gameData;  % Store game state in figure's UserData

    % Control listeners
    fig.KeyPressFcn = @(src, event) keyDown(event.Key, fig);  % Pass the figure handle

    game_ongoing = true;

    while game_ongoing
        pause(0.05);
        
        % Retrieve game state from figure's UserData
        gameData = fig.UserData;
        
        if gameData.game_paused
            % Show a pause menu directly in the game window
            msg = "Continue the Game?";
            title = "Snake Game";
            selection = uiconfirm(fig, msg, title, ...
                "Options", ["Resume", "Open Settings", "Quit"], ...
                "DefaultOption", 1, "CancelOption", 2);
            
            switch selection
                case 'Resume'
                    gameData.game_paused = false;  % Resume the game
                    fig.UserData = gameData;
                    % Trick the system into refocusing the window by minimizing and restoring
                    fig.WindowState = 'minimized';  % Minimize the figure
                    pause(0.1);  % Small pause to ensure it registers
                    fig.WindowState = 'normal';  % Restore the figure to normal state

                case 'Open Settings'
                    disp("Opening Settings. . .");
                    
                case 'Quit'
                    delete(fig);  % Close the game window
                    return;
            end
        end
    end
end

function keyDown(key, fig)
    % Retrieve the current game state
    gameData = fig.UserData;
    
    switch key
        case {'uparrow', 'w'}
            disp("up")
        case {'downarrow', 's'}
            disp("down")
        case {'leftarrow', 'a'}
            disp("left")
        case {'rightarrow', 'd'}
            disp("right")
        case {'space'}
            % Toggle the pause state and display the pause menu
            if ~gameData.game_paused
                gameData.game_paused = true;  % Set game as paused
                fig.UserData = gameData;      % Save the updated state
            end
    end
end

Solution

  • I just figured it out. I just needed to use focus(fig). I have no idea how I didn't try that but at least I got it.