Search code examples
c++ncurses

ncurses library I want to know the cause of poor mouse response


[I'm Japanese using google translate]

what I want to know

I want to know the cause of poor mouse response

Current status

When you release the key by implementing the long press judgment of the mouse The detection is not working properly. It is the code of the comment ///// part.
※The problem is the comment part of the Edit.cpp part.

Edit.hpp

#include <stdlib.h>
#include <iostream>

#include "../lib/ncurses/include/curses.h"


#include "../header/Log.hpp"
#include "../header/Vector.hpp"
#include "../header/Edit.hpp"
#include "../header/Screen.hpp"
#include "../header/Character.hpp"
#include "../header/Color.hpp"

#define UP_KEY ((int)259)
#define LEFT_KEY ((int)260)
#define RIGHT_KEY ((int)261)
#define DOWN_KEY ((int)258)

#define ESC_KEY ((int)27)

#define TERMIMAL_DEFAUT_COLOR ((int)8)

// ######################## コンストラクタ ######################## 
Edit::Edit() : Scene()
{
    holdPressed = 0;

    position.x = 0;
    position.y = 0;
    
    int t = 1;
    for(int i = 0; i < TERMIMAL_DEFAUT_COLOR; i++)
    {
        for(int j = 0; j < TERMIMAL_DEFAUT_COLOR; j++)
        {           
            init_pair(t, i, j);
            t++;
        }
    }


    screen = std::make_unique<Screen>();    //前景



    changeScene = Scene::SceneType::Edit;   //現在のシーン
}

// ######################## Keyboard Input ######################## 
void Edit::KeyInput()
{


    int key = getch();
    //Print("%d\n",key);
    switch(key)
    {
        case KEY_LEFT:
        {
            position.x--;
        }
        break;

        case KEY_RIGHT:
        {
            position.x++;
        }
        break;

        case KEY_DOWN:
        {
            position.y++;
        }
        break;

        case KEY_UP:
        {
            position.y--;
        }
        break;
    }


    //書き込み
    if(key == ' ')
    {
        screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});   
    }
    




    //ESCで終了
    if(key == ESC_KEY)
    {
        changeScene = Scene::SceneType::Exit;
    }
}

// ######################## Update ######################## 
void Edit::Update()
{
    screen->Update();   //スクリーン更新
    


    MouseInput();   //マウス入力
    KeyInput();     //キー入力

    move(position.y,position.x);    //カーソル移動
}

// ######################## Renderer ######################## 
void Edit::Renderer()const
{
    screen->Renderer();
}


// ######################## Mouse Input ######################## 
void Edit::MouseInput()
{
    
    //マウス移動イベント
    if(getmouse(&mouseEvent) == OK)
    {
        //マウス座標
        if(mouseEvent.bstate & REPORT_MOUSE_POSITION)
        {
            position.x = mouseEvent.x;
            position.y = mouseEvent.y;
        }           
    }
    
////////////////////////////////////////////////////////////////////////////////////
    //長押し判定
    if(prevClickEvent.bstate & BUTTON1_PRESSED)
    {
        holdPressed++;
        if(holdPressed > 5)
        {
            prevClickEvent.bstate = BUTTON1_PRESSED;
            screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
            holdPressed = 21;
        }
    }
    else
    {
        prevClickEvent.bstate = 0;
        holdPressed = 0;
    }
    

    //クリックイベント
    if(getmouse(&clickEvent) == OK)
    {
        //Left Click
        if(clickEvent.bstate & BUTTON1_PRESSED )
        {
            prevClickEvent.bstate = BUTTON1_PRESSED;
            screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        else if(clickEvent.bstate & BUTTON1_RELEASED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
            prevClickEvent.bstate = 0;
        }       
        else if(clickEvent.bstate & BUTTON1_CLICKED)
        {
            ///screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        else if(clickEvent.bstate & BUTTON1_DOUBLE_CLICKED)
        {
            ///screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        else if(clickEvent.bstate & BUTTON1_TRIPLE_CLICKED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        

        //Right Click
        if(clickEvent.bstate & BUTTON1_PRESSED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        else if(clickEvent.bstate & BUTTON1_RELEASED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }               
        else if(clickEvent.bstate & BUTTON1_DOUBLE_CLICKED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }           
        else if(clickEvent.bstate & BUTTON1_TRIPLE_CLICKED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
        else if(clickEvent.bstate & BUTTON1_CLICKED)
        {
            //screen->Input(position.x,position.y,Character{Color::WHITE_BLACK,'@',0});
        }       
    }
    
///////////////////////////////////////////////////////////////////////////////////////
}


// ######################## デストラクタ ######################## 
Edit::~Edit()
{

}


Screen.cpp

#include "../header/Screen.hpp"


#include "../header/Character.hpp"
#include "../header/Color.hpp"
#include "../header/Vector.hpp"
#include "../header/Screen.hpp"



// ######################## コンストラクタ ######################## 
Screen::Screen()
{

      //ウインドウ初期化
    getmaxyx(stdscr,windowSize.y,windowSize.x);
    window = newpad(windowSize.y,windowSize.x);
    prefresh(window,0,0,0,0,windowSize.y,windowSize.x);


      size.x = windowSize.x;
      size.y = windowSize.y;
      maxSize = size.x * size.y;

      stage = std::make_unique<std::vector<Character>>(size.x * size.y);
      
      for(std::vector<Character>::iterator itr = stage->begin(); itr != stage->end(); itr++)
      {
            itr->chr = ' ';
            itr->color = Color::NONE;
            itr->type = 0;
      }
}



// ######################## 画面サイズ更新 ########################
void Screen::UpdateScreen()
{
      //画面サイズを取得
      getmaxyx(stdscr,windowSize.y,windowSize.x);
      
      //前のウインドウサイズをより大きければ要素を代入
      if((windowSize.x * windowSize.y) > maxSize) 
      {
            maxSize = windowSize.x * windowSize.y;
            size.x = windowSize.x;
            size.y = windowSize.y;

            for(int i = 0; i< (windowSize.x * windowSize.y); i++)
            {
                  stage->emplace_back(Character{Color::NONE,' ',0});
            }
      }
}



// ######################## Update ########################
void Screen::Update()
{
      UpdateScreen();   //画面サイズを更新
}

// ######################## 文字設定 ######################## 
void Screen::Input(int x,int y,Character c)
{
      stage->at((y * size.x) + x) = c;
}

// ######################## 文字削除 ######################## 
void Screen::Delete(int x,int y)
{
      stage->at((y * size.x) + x).chr = ' ';
      stage->at((y * size.x) + x).color = Color::NONE;
      stage->at((y * size.x) + x).type = 0;
}

// ######################## Renderer ######################## 
void Screen::Renderer()const
{

      for(int y = 0; y < size.y; y++)
      {
            for(int x = 0; x < size.x; x++)
            {
                attron(COLOR_PAIR(stage->at((y * size.x) + x).color));
                attron(stage->at((y * size.x) + x).type);

                  mvwaddch(window,y,x,stage->at((y * size.x) + x).chr);

                attroff(stage->at(y * x).type);
                attroff(COLOR_PAIR(stage->at((y * size.x) + x).color));
            }
      }

    prefresh(window,0,0,0,0,windowSize.y,windowSize.x);      
}

// ######################## デストラクタ ######################## 
Screen::~Screen()
{


}

Solution

  • The example is incomplete, but I don't see a check for KEY_MOUSE returned from getch. ncurses won't be ready to return useful information in getmouse until that happens.