Why aren't my windows being displayed? (Ncurses) - c++

I'm trying to create this program where I print two windows side by side on the stdscr. I've created the class 'menu' to declare everything about the whole screen in one place, I create a 'menu' object ('menu_principal') in main but nothing happens. I added two functions to see if my object is being created and it is.
Why aren't the windows being displayed?
Here is the class 'menu':
class menu{
public:
menu(int row, int col){
display = newwin((row-4), (col/2), 2, 0);
getmaxyx(display, drow, dcol);
help = newwin((row-4), (col/2), 2, (col/2));
getmaxyx(help, hrow, hcol);
refresh();
box(display, 0, 0);
wrefresh(display);
box(help, 0,0);
wrefresh(help);
refresh();
}
int prueba1(){
return (this->drow);
}
int prueba2(){
return (this->hrow);
}
private:
int y, x, drow, dcol, hrow, hcol;
WINDOW * display;
WINDOW * help;
};
Here's part of the main:
int main(int argc, char const *argv[]) {
int row=0, col=0;
initscr();
refresh();
cbreak();
getmaxyx(stdscr, row, col);
menu* menu_principal = new menu(row, col);
refresh();
cout << row;
cout << menu_principal->prueba1();
cout << menu_principal->prueba2();

The plain refresh() calls are overwriting the window-specific wrefresh(display) and wrefresh(help). If the sample were complete, someone could point to the specific line of code which is doing this.
(The cout calls don't help much: you should write that information to a file rather than to the screen).

Related

One of two instances not getting initialized

I am working with ncurses and i am trying to create a class that will print a box.
My class
class CMenu{
public:
CMenu( int x , int y){
this -> x = x;
this -> y = y;
createMenu();
}
void createMenu(){
start_color();
cbreak();
noecho();
keypad(stdscr, TRUE);
my_menu_win = newwin(30, 60, x, y);
keypad(my_menu_win, TRUE);
/* Print a border around the main window and print a title */
box(my_menu_win, 0, 0);
mvprintw(LINES - 2, 0, "F2 to exit");
refresh();
wrefresh(my_menu_win);
while(true){
switch(c = wgetch(my_menu_win)){
case KEY_F(2):
endwin();
exit(1);
case KEY_DOWN:
break;
case KEY_UP:
break;
case 10:
move(20, 0);
clrtoeol();
wrefresh(my_menu_win);
refresh();
break;
}
wrefresh(my_menu_win);
}
}
private:
int n_choices;
int i;
int index;
int c;
int x;
int y;
WINDOW *my_menu_win;
};
And class where I want to create instance of said class
class CUI{
public:
CUI(){
min_X = 200;
min_Y = 50;
}
void printBackground(){
start_color();
init_pair(1,COLOR_GREEN,COLOR_BLACK);
attron(COLOR_PAIR(1));
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(1));
mvhline( (y/5) - 1, (x/6), ACS_BOARD , 140);
mvhline( (y/5)*4, (x/6), ACS_BOARD , 140);
}
void initMenu(){
initscr();
printBackground();
left = new CMenu(10,35);
right = new CMenu(10,115);
refresh();
endwin();
}
private:
int min_X;
int min_Y;
int x;
int y;
CMenu *left;
CMenu *right;
};
And main
int main() {
CUI one;
one.initMenu();
return 0;
}
The problem is that only one of the box gets printed. I added cout to a constructor of a CMenu class to see if both of them gets invoked. Only one of the instance gets invoked the second one gets ingored. What is causing this? Why arent both instances being invoked?
After you created the first menu (left = new CMenu(10,35);), its constructor called createMenu()...and this one starts an infinite loop (while(true) statement) that will never end.
So the second menu won't be created. right = new CMenu(10,115); statement will never be reached...untill CMenu::createMenu() returns... and by reading your code there's apparently no action that will exit this loop. So your program will never create more than one CMenu instance...

How do I draw lines on a image using mouse clicks in opencv?

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;
}

OpenCV: How to get data in main() from MouseCallback function?

I am printing the pixel location on mouse left button click like this:
void CallBackFunc(int event, int x, int y, int flags, void* values)
{
if ( event == EVENT_LBUTTONDOWN )
{
cout << "Left button clicked at (" << x << ", " << y << ")" << endl;
}
}
int main(int argc, char** argv)
{
Mat img = imread("yava.bmp");
namedWindow(" Window", 1);
setMouseCallback(" Window", CallBackFunc, NULL);
position(x,y); //to be implemneted
imshow(" Window", img);
waitKey(0);
return 0;
}
Now I want to get this location, i.e x and y from CallBackFunc to back in main(), which will be processed by my position(x,y) function.
How do i do this?
First of all, read the documentation on setMouseCallback, etc.
This is what I would do (this is the typical example) without changing your code too much:
vector<Point> points; // Store the points as global variables
void CallBackFunc(int event, int x, int y, int flags, void* values)
{
if ( event == EVENT_LBUTTONDOWN )
{
points.push_back(Point(x,y));
}
}
int main(int argc, char** argv)
{
Mat img = imread("yava.bmp");
namedWindow(" Window", 1);
setMouseCallback(" Window", CallBackFunc, NULL); // Add the pointer to the callback
while (1)
{
//Draw your points
for (int i=0;i<points.size();i++) circle(img,points.at(i),3,CV_RGB(255,0,0),-1);
imshow(" Window", img);
waitKey(10);// -> This is when your callback is called everytime you click
}
return 0;
}
For a better solution, consider avoiding global variables and use a class for storing those "clicks".

FLTK simple animation

I can successfully compiled and run the Hello World code.
Now I want to do something like animation.
I first create a rectangle class to implement draw() from Fl::widget
class myRect: public Fl_Widget {
private:
Fl_Color color;
void draw(){
fl_color(color);
fl_rectf(x(),y(),w(),h(),color);
}
public:
myRect(int X,int Y,int W,int H, Fl_Color c) : Fl_Widget(X,Y,W,H),color(c) {}
};
int main (int argc, char ** argv)
{
Fl_Window *window = new Fl_Window (300, 180, "FLTK Test");
vector<myRect*> allRect;
for(int i=0; i<10; ++i){
allRect.push_back(new myRect ((i*10)%100,100,50,50,i%256));
}
window->end();
window->show();
return Fl::run();
}
The code above can run as I expected.
But Now I want to show the rectangles one by one, with some time interval such as 1 second.
Make it just like animation.
I have read the official document but I still have no idead about that.
Please give me some information. Thanks !!
Thanks to DejanLekic, I revised my code as below:
#include <iostream>
#include <vector>
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
using namespace std;
class myRect: public Fl_Widget {
private:
Fl_Color color;
void draw(){
fl_color(color);
fl_rectf(x(),y(),w(),h(),color);
}
public:
myRect(int X,int Y,int W,int H, Fl_Color c)
:Fl_Widget(X,Y,W,H),color(c) {}
};
vector<myRect*> allRect;
void winUpdate(void *data)
{
static unsigned i = 0;
Fl_Double_Window *o = (Fl_Double_Window*)data;
if(i < allRect.size()){
o->add(allRect[i]);
if(i>=3) o->remove(allRect[i-3]);
o->redraw();
Fl::add_timeout(0.5,winUpdate,data);
++i;
}
}
int main (int argc, char ** argv)
{
for(int i=0; i<8; ++i){
allRect.push_back(new myRect(i*30,i*30,50,50,i));
}
Fl_Double_Window *window = new Fl_Double_Window (400, 400, "FLTK Test");
Fl::add_timeout(2,winUpdate,window);
window->end();
Fl::visual(FL_DOUBLE|FL_INDEX);
window->show();
return Fl::run();
}
It seems to run well, but I'm not sure whether it is correct or not.
If there is any problem, please let me know. Thanks.
Cory, you are on the right path.
Here is a complete example how to do a simple 2D animation using FLTK's drawing capabilities: http://seriss.com/people/erco/fltk/#AnimateDrawing
Similar thing using OpenGL: http://seriss.com/people/erco/fltk/#OpenGlInterp
The key, in both examples is in the Fl::add_timeout(0.25, Timer_CB, (void*)this); line, and in the Timer_CB() static (callback) method. Both examples are nice and easy and I am confident you will understand them instantly.

Class field resets to zero

im trying to make a simple game engine, it consists of 2 classes, Game
class Game
{
protected:
SDL_Event event;
vector<Sprite> render_queue;
void render();
public:
int SCREEN_WIDTH,
SCREEN_HEIGHT,
SCREEN_BPP,
FPS;
SDL_Surface *screen;
Game(int width, int height, int fps);
void reset_screen();
void set_caption(string caption);
bool update();
void quit();
void add_sprite(Sprite spt);
};
and Sprite
class Sprite
{
public:
float x,y;
SDL_Surface* graphics;
Sprite();
void draw(SDL_Surface *target);
void loadGraphics(string path);
};
when im trying to change x or y of sprite it resets to 0 on next frame!
main.cpp
int main(int argc, char* args[])
{
Game testing(640, 480, 50);
testing.set_caption("Test");
Sprite s1;
Sprite s2;
s1.loadGraphics("img1.png");
s2.loadGraphics("img1.jpg");
testing.add_sprite(s1);
testing.add_sprite(s2);
while(!testing.update())
{
s1.x = 100;
s2.y = 200;
}
return 0;
}
You make copies of the sprites when adding them to the Game:
class Game
{
/* ... */
void add_sprite(Sprite spt);
};
That's why the lines s1.x = 100; and s2.y = 200; (operating on a different copy in the main()) have no effect.
I think the method should be instead defined like that:
class Game
{
/* ... */
void add_sprite(Sprite &spt);
};
That way Game would be using the Sprite objects from the main().
testing.add_sprite(s2); makes a copy of sprite, so changing the value of s1,s2 in the main code has no effect on the copy in testing.
You need to pass by reference or pointer to to add_sprite()