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...
Related
I'm currently making a simple ncurses menu for executing terminal commands more quickly while working on projects. I'm new to the library and keep having the same issue. I've read the documentation for the relevant functions but it seems to reveal nothing. I was hoping someone more experienced would know why there's an issue.
The function which performs "make main" has been the main one causing the problems
void makeMain( WINDOW *window ) {
wrefresh(window);
mvwprintw( window, 1, 1, "test" );
wrefresh(window);
std::system("make main");
wrefresh(window);
refresh();
wmove( window, 1, 1 );
refresh();
wrefresh( window );
}
the function is run from another function
void coordinateUserInput( int max, std::vector<command> commandslist, WINDOW *output ) {
cbreak();
noecho();
wrefresh(stdscr);
//prep work
char key_pressed;
bool can_go_up;
bool can_go_down;
int y;
int x;
const int &start_line = 3;
const int &finish_line = commandslist.size() + 2;
bool keep_going{1};
//
wmove( stdscr, 3, 2 );
refresh();
while(keep_going) {
getyx( stdscr, y, x );
can_go_up = (!(y == start_line));
can_go_down = (!(y == finish_line));
key_pressed = getch();
switch(key_pressed) {
case 'j':
if(can_go_down) {
wmove( stdscr, y + 1, 2 );
refresh();
}
break;
case 'k':
if(can_go_up) {
wmove( stdscr, y - 1, 2 );
refresh();
}
break;
case '\n':
((commandslist[y - 3]).fcnpointer)(output);
wmove( stdscr, 3, 2 );
refresh();
break;
case 'q':
keep_going = 0;
break;
default:
break;
}
}
return;
}
I'm fairly certain that these would be the problem functions. Running with -Wall and -Wextra doesn't yield errors.
int main() {
bool *is_set_up = new bool;
initscr();
refresh();
//set up command ouput window pointer
int maxx;
int *maxy = new int;
getmaxyx(stdscr, *maxy, maxx);
delete maxy;
static WINDOW *command_output = newwin( 3, maxx, 0, 0 );
box(command_output, 0, 0);
wrefresh(command_output);
//
std::vector<command> commands = {defineCommands()};
writeMenu(commands, commands.size(), is_set_up);
refresh();
coordinateUserInput(commands.size()-1, commands, command_output);
std::cout << "worked" << std::endl;
endwin();
delete is_set_up;
return 0;
}
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).
Model class
class spaceshipModel {
private:
Vector2f position;
float speed, acceleration, energy, fuel;
public:
//Contructor
spaceshipModel() : position(0, 0), speed(0), acceleration(0), energy(0), fuel(0) {}
//Destructor
~spaceshipModel() {}
//Sets
void setPosition(float _x, float _y) { position.x = _x; position.y = _y; }
void setSpeed(float _speed) { speed = _speed; }
void setAcceleration(float _acceleration) { acceleration = _acceleration; }
void setEnergy(float _energy) { energy = _energy; }
void setFuel(float _fuel) { fuel = _fuel; }
//Gets
Vector2f getPosition() { return position; }
float getSpeed() { return speed; }
float getAcceleration() { return acceleration; }
float getEnergy() { return energy; }
float getFuel() { return fuel; }
};
View class
class spaceshipView {
private:
Texture* image;
Sprite sprite;
spaceshipModel model;
public:
//Constructor
spaceshipView() : image(0) {}
//Destructor
~spaceshipView() {}
//Setting the image
void setImage(Texture* _image) { image = _image; }
//Drawing the image
void drawImage(RenderWindow* _window) {
sprite.setTexture(*image);
sprite.setPosition(model.getPosition());
sprite.setScale(Vector2f(0.2f, 0.2f));
_window->draw(sprite);
_window->display();
}
};
Main
A left a lot of the code out, but I then call this in main:
int main() {
//Call instance of the Spaceship model
spaceshipModel shipModel;
//Call instance of the Spaceship view
spaceshipView shipView;
//Create the texture of the spaceship from file
Texture spaceship;
spaceship.loadFromFile("spaceship.png");
//Create the window
RenderWindow window(VideoMode(800, 600), "Spaceship with MVC");
//Run the program as long as the window is open
while (window.isOpen()) {
//Check all the window's events that were triggered since the last iteration of the loop
Event event;
while (window.pollEvent(event)) {
//"Close requested" event: we close the window
switch (event.type) {
//Window closed by pressing the X
case Event::Closed:
window.close();
break;
//Checking for key pressed event
case Event::KeyPressed:
//Pressing esc to close the window
if (event.key.code == Keyboard::Escape) {
window.close();
}
break;
//We don't process other types of events
default:
break;
}
//Clear screen with white BG
window.clear(Color::White);
//TESTING THE SETTING OF THE POSITION
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
shipModel.setPosition(100, 100);
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
//Set and draw the image
shipView.setImage(&spaceship);
shipView.drawImage(&window);
}
}
return 0;
}
The spaceship draws perfectly, but is only set at (0, 0). Even when setting the position to (100, 100) like it shows above. The image stays at (0, 0). As I'm using the getPosition function from the Model class in the View class, I don't think the data is being updated correctly, even when the cout test does show a change.
What am I doing wrong? Can someone give me some pointers?
In the code snippet above, shipModel object from main() and shipView.model are two distinct objects. You can either let your shipView be aware of the model using a setter in spaceshipView, or call shipView.model's methods directly.
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;
}
I'm a new person to C++, but i have learned a little Java and I/m working with SDL for the first time at the same time but my problem is I'm trying to create an object (paddle) p1 and p2.
this
#ifndef PONG_H_
#define PONG_H_
#undef main
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
class paddle{
private:
int y;
int yv;
int x;
public:
paddle(){
y = 0;
yv = 0;
x = 0;
}
paddle(int ex, int why, int vel){
y = why;
yv = vel;
x = ex;
}
void setY(int ycoord) {y = ycoord;}
void setV(int velocity){ yv = velocity;}
void setX(int xcoord) {x = xcoord;}
int getX() {return x;}
int getY() {return y;}
int update(){y += yv; return y;}
};
class Pong { //pong class where everythin gets its name and a purpose.
private:
SDL_Surface * Paddle;
SDL_Surface * Ball; //SDL_Surface pointer for Ball
SDL_Surface * screen; //SDL_Surface pointer to backbuffer
public:
int Running;
Pong(); //eh..
int OnExecute(); //another function returning a value.
int w; //width of screen
int h; //height of screen
bool OnInit();
void OnEvent(SDL_Event* Event);
void OnLoop();
void OnRender();
void OnCleanup();
void redraw( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { //Make a temporary rectangle to hold the offsets
SDL_Rect offset; //Give the offsets to the rectangle
offset.x = x; offset.y = y;
SDL_BlitSurface( source, NULL, destination, &offset );//Blit the surface
offset.x =0; offset.y=0; //resets the offsets sicne they apaprently dont reset per use.
};
};
#endif /* PONG_H_ */
is my header file, it contains the main functions of pong class also but I omitted those to make things less convoluted. Let me know if those are needed for a good answer.
and i declare the objects here...
#include <iostream>
#include <SDL/SDL.h>
#include "Pong.h"
paddle p1;
paddle p2;
Pong::Pong(){
h = 768;
w = 1024;
screen = NULL;
Paddle = NULL;
Ball = NULL;
Running = true;
atexit(SDL_Quit);
}
int Pong::OnExecute() {
if(OnInit() == false)
return-1;
SDL_Event Event;
while(Running) {
while(SDL_PollEvent(&Event)) {
OnEvent(&Event);
}
OnLoop();
OnRender();
}
OnCleanup();
return 0;
}
int main( int argc, char* args[]) {
Pong theApp;
return theApp.OnExecute();
}
but what sort of makes it difficult is i use it in...here:
#include "Pong.h"
void Pong::OnEvent(SDL_Event* Event) {
if(Event->type == SDL_QUIT)
Running = false;
switch(Event->type)
{
case SDL_KEYDOWN: //look for key holds
switch(Event->key.keysym.sym) //check key values and changes coords respectiely
{
default:
break;
case SDLK_UP:
p2.setV(-2);
break;
case SDLK_DOWN:
p2.setV(2);
break;
case SDLK_w:
p1.setV(-2);
break;
case SDLK_s:
p1.setV(2);
break;
case SDLK_ESCAPE:
Running = false;
break;
}
break;
case SDL_KEYUP:
switch(Event->key.keysym.sym)
{
default:
break;
case SDLK_UP:
p2.setV(0);
break;
case SDLK_DOWN:
p2.setV(0);
break;
case SDLK_w:
p1.setV(0);
break;
case SDLK_s:
p1.setV(0);
break;
}
break;
break;//break of Key holding event check
}
}
Its hard for me to ask the question because I don't know where to begin. I tried many different weird things and I'm just lost now. If you need any more info I'll be happy to provide.
void Pong::OnLoop(){
if(p1.getY()<=0){
p1.setV(0);
p1.setY(0);
}
if(p2.getY()<=0){
p2.setV(0);
p2.setY(0);
}
if(p1.getY()>=h - Paddle->h){
p1.setV(0);
p1.setY(h - Paddle->h);
}
if(p2.getY()>=h - Paddle->h){
p2.setV(0);
p2.setY(h - Paddle->h);
}
}
..\src\Pong_OnLoop.cpp:11:5: error: 'p1' was not declared in this scope
..\src\Pong_OnLoop.cpp:15:5: error: 'p2' was not declared in this scope
..\src\Pong_OnLoop.cpp:19:5: error: 'p1' was not declared in this scope
..\src\Pong_OnLoop.cpp:23:5: error: 'p2' was not declared in this scope
Since you haven't provided a clear question, it's difficult to provide the right answer, but my guess is that you can't access p1 and p2 in the OnEvent-/OnLoop-Method.
Is it absolutely necessary to let the two paddle-objects live in the global namespace? Because in this scenario I think it would be best to have 2 paddle-members as part of the Pong class, also I would use initialization lists like so:
class Pong {
private:
SDL_Surface * Paddle;
SDL_Surface * Ball; //SDL_Surface pointer for Ball
SDL_Surface * screen; //SDL_Surface pointer to backbuffer
paddle p1;
paddle p2;
public:
Pong() :
h(768),
w(1024),
screen(NULL),
Paddle(NULL),
Ball(NULL),
Running(true),
p1(10, 384, 0),
p2(1014, 384, 0) {
atexit(SDL_Quit);
};
// ...
};
You might not even need all initializers depending on the optimization settings and the default memory initialization but that's not the point. This way you should have access to p1 and p2 in all of Pongs own methods. Bo Perssons answer may work as well, but I think this is a more object- and thus C++-oriented approach.
On a side note: You said that the header file contains some more methods - seeing that your constructor is implemented in the cpp-file and the redraw-Method in the header-file you might want to learn a bit more about inlining. It won't be much of an issue in this example but it's usually best practice to move the more complex methods to the translation units (cpp-files), especially when creating libraries.
If you want the paddles visible in more than the file they are defined in, you have to add a declaration to the header file
extern paddle p1;
extern paddle p2;
so the other .cpp files will know that they exist.