Here is my code which blinks 'Welcome' after user enter his name.
'Welcome' does not blink when user is writing his name. As user hits enter then caret goes into the while loop. Then caret position is set back to the coordinates of 'Welcome' & cout prints 'Welcome' with 5 colors again & again so it seems that 'Welcome' is blinking.
But I want that 'Welcome' blinks continuously as the program starts.
So more likely this question also ask - can we have two caret/cursor at the same time ?
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
int main(int argc, char** argv)
{
int x,y,i;char name[10];
textcolor(10);
x=wherex();y=wherey(); //corrdinates of caret will be stored in x & y.
cout<<"\t\t\t\tWelcome\n";
textcolor(15);
cout<<"\nEnter your name\n";
gets(name);
while(1)
{
for(i=10;i<15;i++)
{
textcolor(i);
gotoxy(x,y); //Transferring caret to the coordinates stored in x & y.
cout<<"\t\t\t\tWelcome";
Sleep(300);
}
}
return 0;
}
I wrote a small code for this question , it's not 100% correct answer. I am just posting this answer just for giving little bit idea to newbie.
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
int x,y,b,l,n=0;
char c;
void blink()
{
{
int m;
for(m=10;m<15;m++)
{
textcolor(m);
gotoxy(x,y);
cout<<"\t\t\t\tWelcome";
Sleep(60);
}
}
}
int main(int argc, char** argv)
{
char i;int key_stroke;
textcolor(10);
x=wherex();y=wherey();
cout<<"\t\t\t\tWelcome\n";
textcolor(15);
cout<<"\nEnter your name\n";
l=wherex();b=wherey();
z:
{
while (1)
{
if(!(_kbhit()))
{
blink();
goto z;
}
else
{
i=_getch();
if(i==13)
{
gotoxy(l+n,b+1);
return 0;
}
textcolor(10);
gotoxy(l+n,b);
cout<<i;n=n+1;
}
}
}
return 0;
}
No we cant have two caret/cursor at the same time. User inputs name first.
It begins to blink right after the user has pressed the enter key
by first displaying the text in a given color and time delay.
Then after it sets the color to black and overwrites the text wth black color.
Windows code:
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
void gotoxy(int x, int y);
void setcolor(WORD color);
void clrscr();
int main(int argc, char** argv){
int x,y,i;char name[10];
setcolor(10);
cout<<"Welcome\n";
setcolor(15);
cout<<"\nEnter your name ";
gets(name);
i=0;
x=22;
y=12;
while(1) {
// counter for text color
i++; if (i>15) i=1;
// print colored text
setcolor(i);
gotoxy(x,y);
cout<<"Welcome "<<name;
Sleep(100);
// Print black text to simulate blink
setcolor(0);
gotoxy(x,y);
cout<<" ";
Sleep(100);
}
setcolor(7);
gotoxy(1,24);
return 0;
}
void setcolor(WORD color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
return;
}
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x; coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
return;
}
void clrscr()
{
COORD coordScreen = { 0, 0 };
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole, &csbi);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
SetConsoleCursorPosition(hConsole, coordScreen);
return;
}
Instead of such Codes you can use BLINK in textcolor() function. the only problem is that you cannot control its speed. thats it. otherwise its easy to use and you can also set text color.
Eg.
textcolor ( RED + BLINK ) ;
cprintf ( " /t/t WELCOME " ) ;
thats it. I didn't had time to read your full question and program. Also I am just a newbie. So I hope this helps you and others.
Related
I'm new to Ncurses and I tried to make a program in C++ that makes a window then displays a box and text on both the box and standard screen.
Here is my code
#include <iostream>
#include <ncurses.h>
using namespace std;
int main(){
initscr();
int h,w,y,x;
h = 10;
w = 25;
y = 15;
x = 20;
WINDOW * win = newwin(h ,w, y, x);
box(win,0,0);
wrefresh(win);
printw("Hello");
wprintw(win,"hi");
wrefresh(win);
getch();
refresh();
endwin();
return 0;
}
Any help is greatly appreciated.
It's possible that the problem is with the window's position (y and x coordinates). Set y=0 and x=0 to position the window in the upper-left corner of the screen and see if it appears.
You can also check if ncurses is properly initialised by adding if (!initscr()) endwin(); return 1;} at the beginning of the main function to ensure that ncurses has been successfully initialised.
The updated code is as follows:
#include <iostream>
#include <ncurses.h>
int main() {
if (!initscr()) {
endwin();
return 1;
}
int h = 10, w = 25, y = 0, x = 0;
WINDOW *win = newwin(h, w, y, x);
box(win, 0, 0);
wrefresh(win);
printw("Hello");
wprintw(win, "hi");
wrefresh(win);
getch();
refresh();
endwin();
return 0;
}
Here is the main file of the game snake I am developing. It uses OpenGL and ncurses. Everything runs exactly like I want it too, but I can only input my key presses to play the game if my command line terminal is the top level process of my computer. Currently, when I run the program, the OpenGL window spawns ontop of my command line prompt and then I need to re select my command line prompt and bring it to the front to play my game.
I want my terminal to recognize my key presses when the terminal is behind the openGL window. How do I do this if it is possible? I am using Ubuntu Linux.
#include <chrono>
#include <thread>
#include <unistd.h>
#include <ncurses.h>
#include "Snake.h"
#include <GL/glut.h>
int khbit(void)
{
int ch = getch();
if (ch != ERR)
{
ungetch(ch);
return 1;
}
else
{
return 0;
}
}
int main(int argc, char **argv)
{
std::unique_ptr<GameBoxes::Box> squareBackground(new GameBoxes::Box(std::stoi(argv[1]), std::stoi(argv[2]),
std::stoi(argv[3]), std::stoi(argv[4])));
int cArgs[4];
(*squareBackground).getSizeArray(cArgs);
glutInit(&argc, argv);
(*squareBackground).createBackGroundTexture();
glClear(GL_COLOR_BUFFER_BIT); //new
// initialize random seed:
srand (time(NULL));
// start ncurses
initscr();
// Line buffering disabled
cbreak();
// Don't echo while we do getch
noecho();
// Allows checking for Keypress
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
bool play = true;
while (play == true)
{
bool alive = true;
std::unique_ptr<GameBoxes::Snake> snake(new GameBoxes::Snake(*squareBackground, cArgs)); //new
int direction;
char directionTwo = 't';
flushinp();
while (alive == true)
{
if (khbit())
{
direction = getch();
directionTwo = direction;
alive = (*snake).moveSnake(*squareBackground, direction, cArgs); // Grow into a loop
flushinp();
}
else
{
alive = (*snake).moveSnake(*squareBackground, directionTwo, cArgs); // Grow into a loop
}
if (direction == 'k')
{
endwin();
return 0;
}
std::chrono::milliseconds dura( 40);
std::this_thread::sleep_for( dura );
}
}
glutMainLoop();
return 0;
}
I am using the setMouseCallBack function to extract pixel coordinate. It can work if the for-loop change to while(1).
Now, I would like to run and record the pixel coordinate value only for 24 times. But, the for-loop doesn't work. How should I do by using setMouseCallBack function?
Thanks!
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
void mouse_call(int event, int x, int y, int flag, void *param)
{
if (event == EVENT_LBUTTONDOWN)
{
Point *p = (Point*)param;
p->x = x;
p->y = y;
}
if (event == EVENT_LBUTTONUP)
{
Point *p = (Point*)param;
p->x = x;
p->y = y;
}
}
int main(int argc, char** argv)
{
static Point p;
int cor[24][2] = {0};
string filename;
cout << "Filename: ";
cin >> filename;
img = imread(filename);
resize(img, img, Size(), 0.5, 0.5, 1);
namedWindow("Image");
imshow("Image", img);
for(int i = 0; i < 24; i++)
{
setMouseCallback("Image", mouse_call);
cor[i][0] = p.x
cor[i][1] = p.y
}
waitKey(0);
return(0);
}
You need to set the callback only once. And you need to tell which variable you're passing as param.
I modified a little your code in order to keep it simple:
the coordinates are stored in a vector<Point>
the vector of coordinates is a global variable. This make a toy program like this easier. For real application, it will probably be a class member.
I pass a status flag as parameter of the callback, and it turns true when I reached the required number of points
I added a loop that waits for the given number of points to be collected
I collect a point only on mouse down event.
Here the code:
#include <opencv2\opencv.hpp>
#include <vector>
#include <iostream>
using namespace cv;
using namespace std;
vector<Point> coords;
int N = 3;
void mouse_call(int event, int x, int y, int flag, void *param)
{
if (event == EVENT_LBUTTONDOWN)
{
coords.push_back(Point(x,y));
// Debug
copy(coords.begin(), coords.end(), ostream_iterator<Point>(cout, " "));
cout << endl;
if (coords.size() == N)
{
bool* exitflag = static_cast<bool*>(param);
*exitflag = true;
}
}
}
int main()
{
bool bExit = false;
string filename;
cout << "Filename: ";
cin >> filename;
Mat3b img = imread(filename);
resize(img, img, Size(), 0.5, 0.5, 1);
namedWindow("Image");
// Set callback
setMouseCallback("Image", mouse_call, static_cast<void*>(&bExit));
imshow("Image", img);
while (!bExit)
{
waitKey(30);
}
cout << "Found " << N << " points... Exit" << endl;
return(0);
}
Altough your question is a bit unspecific I think your actual problem is quite simple.
Your for loop does work, but you have to keep in mind that there are a lot more mouse events.
Your mouse_call handler also gets spammed with movements events which are neglected by your handler. And since the loop only runs 24 times it has no actual chance to capture a button down event before it's finished.
How can I detect if a click on a (x,y) coordinates point will create any action?
For example is there any bool function (in c++) or something like that which can tell me if a double-click on (200,200) coordinates point will create any action before actually making the click?
Use ReadConsoleInput for mouse event.
You can check out microsoft domentation. http://msdn.microsoft.com/en-us/library/windows/desktop/ms685035(v=vs.85).aspx
Sample code again:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
using namespace std;
int main()
{
cout<<"click anywhere in console window to write - hello world -\n\n\n\n\n\n\n\n\n\n\n\n\n"
"Press Ctrl+C to Exit";
HANDLE hout= GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD InputRecord;
DWORD Events;
COORD coord;
CONSOLE_CURSOR_INFO cci;
cci.dwSize = 25;
cci.bVisible = FALSE;
SetConsoleCursorInfo(hout, &cci);
SetConsoleMode(hin, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
while(1)
{
ReadConsoleInput(hin, &InputRecord, 1, &Events);
if(InputRecord.EventType == MOUSE_EVENT)
{
if(InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
coord.X = InputRecord.Event.MouseEvent.dwMousePosition.X;
coord.Y = InputRecord.Event.MouseEvent.dwMousePosition.Y;
SetConsoleCursorPosition(hout,coord);
SetConsoleTextAttribute(hout,rand() %7+9);
cout<<"Hello world" ;
}
}
FlushConsoleInputBuffer(hin);
}
return 0;
}
So, after following the advise from the stackexchange users about mouse event, I was able to understand and implement some simple task using mouse clicks. So, the next goal was to draw a simple line using the mouse left click and mouse right click. Unfortunately, I can't see any line after I implemented my program.
int x,y;
Point p(0,0);
Point q(0,0);
Mat xal;
void drawimage()
{
a = q.x - p.x; //i am just checking out the values of a and b to see if the drawimagefunction is being called in the rightmouse click event
b = q.y - p.y;
cout<<" a is :"<<a<<endl;
cout<<"b is:"<<b<<endl;
line(xal,Point(p.x,p.y),Point(q.x,q.y),Scalar(0,0,255),2,8);
}
void onMouse( int event, int x, int y, int f, void* )
{
switch (event)
{
case EVENT_LBUTTONDOWN:
cout<<"Left button was pressed"<<x<<" "<<y<<" "<<endl;
{
p.x = x;
p.y = y;
cout<<"p is:"<<p.x<<p.y<<endl;
}
break;
case EVENT_RBUTTONDOWN:
cout<<"Right button was pressed at :"<<x <<" "<<y<<endl;
{
q.x = x;
q.y = y;
drawimage();//no line is being drawn though i can see that i get the values of a and b in the drawimage function.
}
break;
default:
break;
}
}
int main()
{
xal = imread("pic.JPG);
namedWindow("Picture",1);
setMouseCallback("Picture",onMouse,NULL);
imshow("Picture",xal);
cvwaitkey(0);
}
Add the following after your "line(..)" call in your drawLine() function:
imshow("Picture", xal);
The problem is that you are writing the line to the xal matrix, but you have not updated the image on the screen, which is what the imshow(..) call will do.
Try this one code. It is useful for you.
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
void drawimage()
{
line(xal,Point(p->x,p->y),Point(q->x,q->y),Scalar(0,0,255),2,8);
}
void CallBackFunc(int event, int x, int y, int flags, void *ptr )
{
if ( event == EVENT_LBUTTONDOWN )
{
Point*p = (Point*)ptr;
p->x = x;
p->y = y;
drawimage();
}
else if ( event == EVENT_RBUTTONDOWN )
{
Point*q = (Point*)ptr;
q->x = x;
q->y = y;
drawimage();
}
}
int main(int argc, char** argv)
{
// Read image from file
Point p;
Point q;
Mat xal = imread("MyPic.JPG");
//if fail to read the image
if ( xal.empty() )
{
cout << "Error loading the image" << endl;
return -1;
}
//Create a window
namedWindow("My Window", 1);
//set the callback function for any mouse event
setMouseCallback("My Window", CallBackFunc,&p);
setMouseCallback("My Window", CallBackFunc,&q);
//show the image
imshow("My Window", xal);
// Wait until user press some key
waitKey(0);
return 0;
}