I am trying to make a change in the position of the scroller through this function but nothing is happening, I suspect that I'm using structs wrongly.
I searched online but the issue couldn't be resolved.
void On_click_scroller(ALLEGRO_EVENT event, SCROLLER *scroll) { if(event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) if(event.mouse.x > scroll->x1 && event.mouse.x < scroll->x2 && event.mouse.y > scroll->y1 && event.mouse.y < scroll->y2 && scroll->flag == 0) { scroll->flag = 1; scroll->from_y = event.mouse.y; } }
What could be the problem?
It doesn't look like the problem is in the code you are showing.
What happens to your scroller when you change the from_y and flag values? Are you redrawing your scroller?
However, the problem could be absolute coordinates vs relative coordinates. Shouldn't you be subtracting scroller->y1 from event.mouse.y?
I have divided it into three functions
I have uploaded the source files in the attachments.
This function is incorrect because it takes Scroller by value, and not by reference (C++) or pointer (C).
SCROLLER scroller_listener(ALLEGRO_EVENT event, SCROLLER scroll) { On_click_scroller(event, &scroll); On_drag_scroller(event, &scroll); On_release_scroller(event, &scroll); return scroll; }
You're returning a copy of a copy. The SCROLLER returned by the function calls your three callback checks on a local copy of 'scroll'. You need to use pointers.
The function could be changed to :
void scroller_listener(ALLEGRO_EVENT event , SCROLLER* pscroll) { On_click_scroller(event , pscroll); On_drag_scroller(event , pscroll); On_release_scroller(event , pscroll); return; }
And then it should work.
Changed the function but still no difference.
See the attachments.
Have you tried setting breakpoints and using a debugger to see how far it gets? Where does it get stuck, what is the state of the stack where it gets stuck or does not enter.
well, I'm not compiling on Code blocks and I don't know how to use command line GDB. I will have to learn it first to do that.
Oh yeah, using a debugger is an absolute must to be a programmer in 2019.
If you switch to visual studio as your IDE, debugging is a lot easier.
Is there a reason you're not using an IDE like VS or Code blocks?
In job postings, I find that they require the command line compilers and Linux knowledge. It was explicitly said that I need to be able to work with Linux and GCC compiler.
I am making a project for students to learn C programming. They are the people who don't even know how to create header files and how to manage code. Some don't even have enough resources to download an IDE so I decided to go fully command line.
I will look for GDB tutorials shortly.
There are plenty of free IDEs for Linux that use GDB and GCC and let you set breakpoints using a gui interface.
https://www.tecmint.com/best-linux-ide-editors-source-code-editors/
There is simply no reason for anyone who codes professionally not to use a debugger. Any company that doesn't, don't go work there.
GDB primer :
gdb>backtrace (bt) gdb>bt Gives you the stack trace gdb>print x prints the value of the expression x, including function calls gdb>break file.ext:### Sets a breakpoint in file.ext on line ### gdb>run gdb>continue Unpauses execution after hitting a breakpoint gdb>breakpoints Tells you the currently selected breakpoints gdb>info threads Gives you info on the threads currently executing (paused) gdb>thread apply all bt Gives you a backtrace for every thread gdb>thread # Switches to thread # gdb>frame # Switches to frame # gdb>info locals gdb>info globals Gives you information on local or global variables. gdb>info globals EXPR Gives you info on global variables that match EXPR
That pretty much covers the basics of using GDB. You can always type 'help' or 'help TOPIC' and get the runtime info on that command.
Seems like you aren't calling that listener function anywhere inside the loop?
Thanks Edgar, that was really helpful.
Peter, The file is in the attachments.
What you're failing to understand is the difference between pass by value and pass by reference. In your code you are still using copies of objects instead of pointers to objects. If you alter a copy, the original remains unchanged. Pass by pointer and then your changes will take effect.
https://stackoverflow.com/questions/2229498/passing-by-reference-in-c
At first, I was using pass by reference but when it didn't compile then I changed it to pass by value.
I have made these changes and I will be blunt to say that I have tried everything I could (even stack overflow) but couldn't find anything on how to resolve this problem and there doesn't seem to be any good tutorial on struct with pointers in function parameters (or I'm just not good at searching).
Seems like you aren't calling that listener function anywhere inside the loop?
Peter, I'm calling it inside bt_list_box_listner(); function.
Peter, I'm calling it inside bt_list_box_listner(); function.
Right and where are you calling that?
This is Text_Box.c file
This is main.c file
Right and where are you calling that?
Right and where are you calling that?
at line no. 145.
145 list_box = bt_list_box_listener(event, list_box);
I now know it wasn't in the loop.
It's working now and blinking for some reason.
Anyway Thanks Peter.
Okay, Pointer Primer :
First, in C, all variables are pass by value, including pointers. But a pointer happens to hold the address of another object, which can be used to change that object, but not the pointer you pass to the function.
typedef struct DATA { int x; };
Pass by value :
They are all pass by value, including the pointer. But the pointer allows you to change memory.
Here's a little quiz for you. What does the following code output? Does it compile? Does it run successfully? Why or why not?
DATA d = {1}; int i = 2; int* iptr = &i; IncrementLocalDataCopy(d); IncrementLocalDataPointerCopy(&d); IncrementLocalIntCopy(i); IncrementLocalIntPointerCopy(iptr); printf("d.x is %d , and i is %d\n" , d.x , i);
They are equal
<spoiler>
They equal 2
</spoiler>
Tips on working with pointers :
int i = 0; int* iptr = &i;/// & Means 'the address of' i i->x = i->x + 1;/// -> Derefences a pointer and accesses a field *iptr = 3;/// * Dereferences a pointer and returns a reference to i which is used to assign the value 3 iptr = 0;/// Does nothing to i *iptr = 4;/// Crashes if you're lucky with a segfault SIGSEGV accessing invalid memory address
And if you ever switch to C++, they introduce a second meaning for & when inside a function signature or variable declaration. It means 'a reference to' an object.
Example :
int i = 0; int& j = i;/// j now references i j = 1;/// Directly modifies i through its address printf("I should be 1, and the value is %d" , i);
There. Learn that, and then tell us why it wasn't working.
Thanks Edgar, for the valuable lesson and I already knew about the references.
I was confused about passing structs as pointer copy because that was my first time doing it and there was a logical error in my program that lead me to believe that I'm using it wrongly.
Thanks again.
On "pass by value" - I saw something like that recently (OK, a year ago):
https://news.ycombinator.com/item?id=16533862
and the author responded to my comments:
https://news.ycombinator.com/item?id=16537111
(also note the response from munificent aka Bob Nystrom who knows a thing or two )
On the other stuff - GDB would have helped you here
gdb> br bt_list_box_listener gdb> run
to set a breakpoint on that function and run the program; it would then be obvious it was not being called, since the breakpoint would not be hit.
Thanks Peter!