How to call the default handler from within an event handler - event-handling

I have a TStatusbar with 4 panels and one of them set in OwnerDraw style.
In the onDrawPanel() event handler, I would like the TStatusbar to use the default paint method before I add some custom drawing on top of it.
Is there a way I can call the default handler from my onDrawPanel handler?
EDIT
Well, I did found a fix, but I'm not sure how reliable it is if the system font change.
Since the default handler only draws the panel text, a simple call to TextRect will do the same trick.
StatusBar->Canvas->TextRect(Rect,Rect.Left,Rect.Top,Panel->Text);
But, I'm not sure how well this will work if the system font, language etc. isn't the default.
I would still like to get an answer to the original question.

TStatusBar is a wrapper for standard WinApi window class, so by default the painting is done by OS. You should look into WinApi functions, or messages like SB_SETTEXT
Check this on MSDN: SB_SETTEXT message
EDIT:
It seems DrawStatusText is the right WinApi function. SBT_NOBORDERS flag shall be specified if borders are not required.

Related

How to make window centered in GTK4?

In GTK3 there was a property on the Gtk.Window class called window-position. By setting this property to Gtk.WindowPosition.CENTER it was possible to tell the window to render in the center of the screen.
In GTK4 this property has been removed. How to achieve the same behavior in GTK4, i.e. how to make the main window of my application to be rendered in the center of the screen?
I checked the migration guide but I couldn't find the solution.
There is no replacement API, since it can't possibly work cross-platform, so it is broken API by definition. As such, it was removed.
For example: this is impossible to implement when running on top of a Wayland session, since the protocol doesn't allow getting/setting global coordinates. If you still want to have something similar working, you'll have to call the specific platform API (for example, X11) for those platforms that you want to support.

GUI: configure the racket:text% to read-only

I want to use an editor to display a log from a program, I just need a very basic text field:
With a vertical scrollbar
With a contextual menu for copy/paste
Prevent the user from changing the text
In order to activate the copy/paste menu, I use the class racket:text% from framework rather than the basic one.
How to prevent the user from changing the text?
I read the documentation, as far as I understand the closest thing I found is lock method:
https://docs.racket-lang.org/gui/editor___.html?q=lock#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._editor~3c~25~3e%29._lock%29%29
But it is not convenient, as it also prevent my program to write the data.
I also find get-read-write? but cannot find set-read-write.
Use the lock method, and just unlock the editor around any modifications that you want to do. You may find it useful to write a call-with-unlock helper function or with-unlock macro.
If you do your updates from the eventspace's handler thread (and you probably should; use queue-callback if they originate from another thread), then as long as you re-lock the editor at the end of an update, the user will never be able to interact with the unlocked editor.

GBinding update timing?

I connected a property of my GtkApplication with a GtkEntry field in my Preference dialog through g_object_bind_property. Works like a charm.
However, it works a little too well, in that each and every character added/deleted/changed in the GtkEntry is reflected in the corresponding GtkApplication property. I would like this update to happen only the GtkField is activated by the user pressing . Is there any way to tweak the timing of the binding, or should I just handle the activate signal?
I don’t think there is a way to make GObject property bindings conditional on a signal or on the value of a property. I think you need to handle the activate signal manually, as you suspected.

vscode extension onDidChangeCursorPosition

I am developing a vscode extention and I want provide something like the bracket match decoration. My problem is that I need to register onDidChangeCursorPosition and I don't know how to do that.
My purpose is to create a decorations that appears only when the cursor is on it.
There is no such event like onDidChangeCursorPosition. However you can use onDidChangeTextEditorSelection. The onDidChangeTextEditorSelection is actually a field on the vscode's window object and you can assign your own function to it which gets called when this event is sent. Look at my extension (or many others which do that) to learn how to handle the cursor change event.

gtkmm-Window remains empty

In our project, we're using gtkmm and we have several classes that extend Gtk::Window in order to display our graphical interface.
I now found out what call produces the behaviour (described in the previous revision. The question now slightly changed.)
We're displaying one window, works like a charm.
Then, we have a window which displays various status messages. Let's call it MessageWindow. It has a method setMessage(Glib::ustring msg) which simply calls a label's set_text().
After some processing, we hide this window again and we now show a toolbar. Just yet another simple window, nothing crazy.
For all windows applies: The main thread calls show() on the window and creates a new thread which calls Gtk::Main::run() (without argument).
That's how it should be, until now.
The problem starts here: The main thread now wants to call MessageWindow::setMessage("any string"). a) if I call this method, the message window reacts completely correctly. But afterwards, the toolbar-window is displayed empty. b) if I don't call it, the message window doesn't change the label (which is absolutely clear), and the toolbar window is displayed as it should.
Seems like the windows are messing up each other.
Now the question:
If my gui-thread is blocking in Gtk::Main::run(), how can I now change the text of a label?
We're using gtkmm-2.4 (and no, we cannot upgrade)
Any help is appreciated.
Wow! That's complicated...
First: you should not manipulate windows from several threads. That is you should have just one GUI thread that does all the GUI work, and let the other threads communicate with it.
It is theoretically possible to make it work (in Linux; in Windows it is impossible) but it is more trouble than it is worth.
Second: the line Gtk::Main main(argc, argv) is not a call, it is an object declaration. The object main should live for the duration of the program, so if you use it in a object constructor, as soon as you return from it, the object will be destroyed! Just put it at the top of the main function and forget about it.
UPDATE: My usual approach here is to create a pipe, a g_io_channel to read, and write bytes on the other end.
Other option, although I didn't test it is to call get the GMainContext of the main thread and then g_idle_source_new() and attach that source to the main context with g_source_attach(). If you try this one and it works, please post your result here!