I have a GTK program with a lot of buttons. When I press one of them, my program starts to displaying a buffer, line by line, in this way:
...
gchar * stuff = g_strdup_printf("Some text");
gtk_text_buffer_insert(buffer, &iter, stuff, -1);
g_free(stuff);
while (gtk_events_pending())
gtk_main_iteration();
...
Because I manage a lot of data, this method is very slow.
I want a second plane mode when some variable reach a high value (for example an int scndplane=1). My idea for this mode is a normal execution of the main program, but to display the buffer only at the end of the program (a kind of backbuffer).
Is there any efficient way to do it?
Thank you.
Why do not you simply make a method of this and then call it at the end of your program ?
If you press your button during the exexution, put a boolean at true.
Then at the end of your program, you will have something along the lines of:
if(isClicked)
displayBuffer();
Related
I've created a Wasm animation using emscripten and SDL. I am now trying to create a button where the user can start and stop/pause the animation. The problem I have is that the whole canvas is cleared on every iteration. As I see it, there are 3 options here:
Redraw the button on every frame.
Only clear the part of the canvas that the animation uses on each iteration.
Use a HTML form for the input buttons.
(1) seems inefficient. (3) would require me to start interoperating between JS and Wasm. So far I've been able to build the whole thing without writing a single line of JS, and would prefer to keep it that way. So probably (2) is best.
I know that with JS it is possible to specify the dimensions of a clearRect call. I can't find this functionality in the SDL API however.
Below is the mainLoop function (which gets called about 60 times a second) (This is written in C if it's unclear. Not C++). My question is, how can I adapt the "SDL_RenderClear" so that it only clears one half of the canvas? (The half with the animation. I.e. don't clear the half where I want to make buttons.
main.c
#include <stdio.h>
#include <SDL2/SDL.h>
#include <emscripten.h>
#include <stdlib.h>
#include <stdbool.h>
<....>
/**
* The loop handler, will be called repeatedly
*/
void mainLoop(void *arg) {
struct Context *ctx = arg;
printf("iteration: %d\n", ctx->iteration);
SDL_SetRenderDrawColor(ctx->renderer, 255, 0, 100, 255);
SDL_RenderClear(ctx->renderer);
bool running = true;
if (running) {
for (int j=1; j<8; j++) {
for (int i=1; i<130; i++) {
// drawRect is another app function that calls the SDL to draw a rectangles.
drawRectangle(ctx, i, j);
}
}
}
SDL_RenderPresent(ctx->renderer);
ctx->iteration++;
}
<....>
You can just paint over parts you don't want with SDL_RenderFillRect. However, unless you do a lot of trickery, it isn't very helpful.
Formal reason - https://wiki.libsdl.org/SDL_RenderPresent says "The backbuffer should be considered invalidated after each present; do not assume that previous contents will exist between frames."
There are many cases when your buffer will be (partially) invalidated, e.g. moving window out of screen bounds. I don't know about webasm, you probably need to check webgl documentation if anything about buffer contents is being promised.
Even if you can rely on contents to be kept, but e.g. you have double buffered setup. You've rendered to first buffer, performed buffer swap - now you have second buffer, which contents isn't initialised yet. After second swap it could be more-or-less similar, but any change will be lagging behind 1 frame.
Some 3d software (e.g. blender) did what you described but even there it wasn't 100% stable and usually there was an option to disable that behabiour. Performing full redraw is much cheaper than you think, and if it becomes too costly - you can always render part of your screen into render texture and use it as single static image, updating it when necessary.
I'm coding a console editor in C. I'm using CodeLite Editor on Windows. I want to insert a newline ('\n') when the user presses Return (Enter) key. I want to accomplish this goal with getchar() function is that possible?
I need it because I want to increment the y axis variable.
Code I'm trying on :
int X = 0; // X-axis
int Y = 0; // Y-axis
char key = getchar();
if (key=='sth') // Here I want to perform my check
{
//Do Something
++Y;
}
Update :
If it has a code like : '\x45' for example post it in the comments plz!!!
If you are trying to implement an editor, you will quickly find that getchar() is not the way to interpret keyboard events. In this very simplistic example, where all you might do is wait for a single keystroke of input that either is or is not a newline, your program will work if you change 'sth' (an abbreviation for "something"?) to '\n'. However, as your editor becomes more complicated, you will want to have an actual event handler that can detect any sort of keyboard events and can asynchronously deal with them. getchar() is not the way to do that.
This answer from 7 years ago shows that (1) you can go a limited distance with getch() (and getchar()), but (2) a far larger number of people agree that it's no substitute for a real event handler: Detect Keyboard Event in C
I have seen a rare amount of programs, having animated window icons.
From a distant vantage point, this could be rather beneficially isn't it..
I took the rudder in the process of inventing one function to do so.
It does what you probably thought of and using Sleep() to simulate intervals after each "frame".
I don't have to say that using WinAPI in major programs is a bad idea as well as the fact that the program will freeze until the function terminates.
Back on track. I am looking for a possibility to avoid this behavior.
It is understandable, hence no one wants a non-functional but take a note WITH ANIMATED ICON program.
You are probably calling your function from the Main Event Loop. This is the thread where all sort of GUI events are handled, including mouse clicks and key presses. If you call Sleep from within this thread, all these processing tasks will be pending and your program will freeze.
To avoid this behavior, use g_timeout_add. This function will call a function at regular intervals from within the Main Event Loop (so no need to do it yourself). You need to define a function like this:
// define this function somewhere
gboolean animate(gpointer user_data) {
// cast user_data to appropriate type
// supposing you have a AnimationParameters class with everything you need...
AnimationParameters* animParams = (AnimationParameters*)user_data;
// update animation
// ...
return TRUE; // return TRUE to call function again, FALSE to stop
}
Elsewhere in your code, to start the animation:
AnimationParameters* animationParameters = new AnimationParameters(...);
g_timeout_add (30, // call every 30 milliseconds
animate,
animationParameters);
Hope it helps.
I am working on a GTK+ editor in C. I have added a feature of displaying the current line number and column number of the cursor position in the textview. Its working well. But the drawback is when I attempt to move the cursor with the arrow keys the line number and column number do not get updated. Below is my code for updating the line number and column number
update_statusbar(GtkTextBuffer *buffer,GtkStatusbar *statusbar)
{
gchar *msg;
gint row, col;
GtkTextIter iter;
gtk_statusbar_pop(statusbar, 0);
g_print("c");
gtk_text_buffer_get_iter_at_mark(buffer,
&iter, gtk_text_buffer_get_insert(buffer));
row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);
msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);
gtk_statusbar_push(statusbar, 0, msg);
g_free(msg);
}
int main ( int argc, char *argv[])
{
.
.
.
.
.
.
g_signal_connect(buffer, "changed", G_CALLBACK(update_statusbar), statusbar);
update_statusbar(buffer, GTK_STATUSBAR (statusbar));
}
I guess the problem is with "changed" signal. Since the cursor is moved with arrow keys, buffer doesn't get changed. So can anyone suggest me a better way to solve the problem .
Thanks in advance :).
The TextBuffer "cursor-position" property has the buffer offset of the insertion mark (aka cursor). The signal corresponding to this property changing is named "notify::cursor-position", and is a notify signal as defined in gobject.
There's a list of text buffer signals here and a list of general widget signals here.
The latter link has a signal called key-release-event which you will probably find interesting.
This is the probably the best way to do this job. Although the move_cursor signal on GtKTextView works well for key press. It does not respond to mouse click based cursor position change. Notify signal on GtKTextView works for mouse click but causes thread conflict while trying to update the buffer's insert position. So the best thing is to directly associate the signal "notify::cursor-position" to the buffer behind GtKTextView. No need to associate signal to GtKTextView.
I'm attempting to write a simple chat application in C using ncurses, both of which I am new to with a background in PHP. (Yes, I know. Thanks. I'll take that advice to heart. Please put down the guns.)
What I've attempted to do is create two windows, one for input and one for channel text, like so:
int termwidth = getmaxy(stdscr);
int termheight = getmaxx(stdscr);
WINDOW *channel = newwin(termwidth, termheight - 1, 0, 0);
scrollok(channel, TRUE);
WINDOW *input = newwin(termwidth, 1, termheight + 1, 0);
scrollok(input, TRUE);
and then set cursor position to input:
wmove(input, 0, 0);
in order to put typed input in the second window, which should occupy a single column at the bottom of the terminal, while output appears in the first window which fills the rest of the terminal's space.
Output appears to fill the top window (channel) properly, with the input cursor flashing in the proper place, but changing its size does not yield predictable results and typed input doesn't appear to be going into the input window at all.
The complete source is available here: http://pastebin.com/X8apHUgh
To sum up, I am asking why input is behaving unexpectedly, and why drawing the "channel" window is yielding strange results.
Oh, [expletive/deleted]! I'm an imbecile. It turns out my problem was twofold:
I had inadvertently mixed my X and Y assignments, and
I had also reversed the width and height parameters in the functions.
This meant that positioning worked properly, until I made certain assumptions for basic positioning math.
I should add that this is partly because I was conceiving terminal positioning in terms of X/Y position, where rows/cols is the paradigm in place. They are only partly equivalent.
slow clap for self