Setting the size of gtk scale - c

I've got problems with gtk scale.
I've got fixed widget where I placed horizontal scale. The problem is that the scale is very small and I don't know how to resize it to for example 100 pixels.
Below is my code:
wind = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(wind), 300, 300);
fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(wind), fixed);
button = gtk_button_new_with_label("button1");
gtk_fixed_put(GTK_FIXED(fixed), button, 10, 20);
button2 = gtk_button_new_with_label("button2");
gtk_fixed_put(GTK_FIXED(fixed), button2, 200, 20);
scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 100, 1);
gtk_fixed_put(GTK_FIXED(fixed), scale, 100, 40);
and here is how it looks like:
The scale is in the middle of the window and shows 0 value.

Ok, I found the solution by myself:
g_object_set(scale, "width-request", 200, NULL);

Related

Simple Stretched Raylib Fullscreen Option?

The code for a simple Raylib program is listed below (based on the Raylib example shapes_logo_raylib). Running the program shows a version of the Raylib logo: a black square outline which fills about a third of the (800x450) window.
It's not hard to make a fullscreen version of the program, with calls such as GetCurrentMonitor(), SetWindowSize(), GetMonitorWidth(), GetMonitorHeight()
SetConfigFlags(FLAG_WINDOW_RESIZABLE), or ToggleFullscreen(). But then, while the black square remains a similar size as before, it occupies (top left) a much smaller proportion of the larger (fullscreen) window. Is there an option to display a larger "stretched" version of the original windowed image on the fullscreen window?
#include "raylib.h"
int main(void)
{
InitWindow(800, 450, "raylib [shapes] example - raylib logo using shapes");
while (!WindowShouldClose())
{
BeginDrawing()
ClearBackground(RAYWHITE);
DrawRectangle(screenWidth/2 - 128, screenHeight/2 - 128, 256, 256, BLACK);
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, RAYWHITE);
DrawText("raylib", screenWidth/2 - 44, screenHeight/2 + 48, 50, BLACK);
EndDrawing();
}
CloseWindow();
return 0;
}
I made the following additions to your code to make it work on any window size. It draws the stuff you want to draw onto a RenderTexture2D and then draws said texture onto the screen. I've only tested it with resizable windows, but it should work in any window mode, including exclusive fullscreen.
In short:
Request render texture using LoadRenderTexture(int, int)
Use BeginTextureMode(RenderTexture2D) and EndTextureMode() to draw onto the texture
Draw the texture using DrawTexturePro(Texture2D, Rectangle, Rectangle, Vector2, float, Color), the first rectangle is the size of the texture, the second the size of the screen. If it looks mirrored, invert the height of the input texture.
Unload the render texture when done.
I added comments to all my additions/changes to highlight what needs to be changed.
#include "raylib.h"
// This was just missing from your code, but I wanted to show a compilable version of the code
int screenWidth = 800;
int screenHeight = 450;
int main(void)
{
InitWindow(800, 450, "raylib [shapes] example - raylib logo using shapes");
// This should use the flag FLAG_FULLSCREEN_MODE which results in a possible ToggleFullscreen() call later on
SetWindowState(FLAG_WINDOW_RESIZABLE);
// Request a texture to render to. The size is the screen size of the raylib example.
RenderTexture2D renderTexture = LoadRenderTexture(screenWidth, screenHeight);
while (!WindowShouldClose())
{
// Instead of using BeginDrawing() we render to the render texture. Everything else stays unchanged
BeginTextureMode(renderTexture);
ClearBackground(RAYWHITE);
DrawRectangle(screenWidth / 2 - 128, screenHeight / 2 - 128, 256, 256, BLACK);
DrawRectangle(screenWidth / 2 - 112, screenHeight / 2 - 112, 224, 224, RAYWHITE);
DrawText("raylib", screenWidth / 2 - 44, screenHeight / 2 + 48, 50, BLACK);
// We need to end the texture mode separately
EndTextureMode();
// Let's draw the texture. The source rect is the size of the texture, the destination rect is of the same size as the screen. For some reason, the texture was flipped vertically, so I had to invert the source rects "height" to flip the UV.
BeginDrawing();
DrawTexturePro(
renderTexture.texture,
Rectangle{ 0, 0, static_cast<float>(renderTexture.texture.width), static_cast<float>(-renderTexture.texture.height) },
Rectangle{ 0, 0, static_cast<float>(GetScreenWidth()), static_cast<float>(GetScreenHeight()) },
Vector2{ 0, 0 },
0,
WHITE);
EndDrawing();
}
// Unload the texture handle again to make a clean exit.
UnloadRenderTexture(renderTexture);
CloseWindow();
return 0;
}
I hope this answers your question.

How to prevent GtkWindow growing?

This is my codes:
#include<gtk/gtk.h>
int main(int argc,char**argv)
{
GtkWidget* window, *button, *grid;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window),100,100);
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
//gtk_container_set_border_width(GTK_CONTAINER(window),10);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
grid = gtk_grid_new();
button = gtk_button_new_with_label("1");
gtk_grid_attach(GTK_GRID(grid), button, 0,0, 100, 1);
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
button = gtk_button_new_with_label("1");
gtk_grid_attach(GTK_GRID(grid), button,0, 1, 10, 1);
gtk_container_add(GTK_CONTAINER(window), grid);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
the result of this codes is :
gtk_grid_attach(GTK_GRID(grid), button,0, 1, 100, 1)
When I change gtk_grid_attach(GTK_GRID(grid), button,0, 1, 100, 1) to gtk_grid_attach(GTK_GRID(grid), button,0, 1, 200, 1)
Then the result of this code is:
gtk_grid_attach(GTK_GRID(grid), button,0, 1, 200, 1)
Why does the width of window increase? I find that the size of window may be varied with the function gtk_grid_attach(). So how to solve it?
Why does the width of window increase?
You have used
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
Which means that each cell in the grid will have equal width and height, which will be the same as the largest widget embedded. So If you have more cells, the grid will grow further and thus the window width increases
I find that the size of window may be varied with the function gtk_grid_attach(). So how to solve it?
I don't know what's your usecase is. But you could unset the homogeneous properties and/or use a real grid width and height when attaching children.

Blank screen after rendering text

I have opened a window which shows two rects on the screen then using SDL_TTF to show the mouse position on the screen.
The bit I am having hard time understanding is why after rendering text the the two rects before it do not show up.
I am using SDL_RenderFillRect to draw two rects on screen
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, rect1);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, rect2);
Code for rendering the text is
// define string with mouse x, y coords
sprintf(someString, "x: %d, y: %d", mouse.x, mouse.y);
SDL_Point textPos = {10, 10};
WriteText(renderer, font, someString, textPos, (SDL_Color){255, 255, 255, 255});
SDL_Surface *fontSurface = TTF_RenderText_Blended(font, someString, COLOR_BLACK); // create font surface
SDL_Texture *fontTexture = SDL_CreateTextureFromSurface(renderer, fontSurface); // create the texture
// get clip width and height from fontsurface clip rect
SDL_Rect *fontRect = &fontSurface->clip_rect;
fontRect->x = pos.x;
fontRect->y = pos.y;
SDL_RenderCopy(renderer, fontTexture, NULL, fontRect); // copy text to the renderer
// delete surface and texture
SDL_FreeSurface(fontSurface);
SDL_DestroyTexture(fontTexture);
It to shows the mouse positon top left corner of the window. However this makes the rest of the window blank.
To prevent this my work around is having to draw something on the screen after calling SDL_RendererCopy (and weirdly before calling SDL_DestroyTexture too) For example drawing single point
...
SDL_RenderCopy(renderer, fontTexture, NULL, fontRect); // copy text to the renderer
// why is this needed??
SDL_RenderDrawPoint(renderer, 0, 0);
// delete surface and texture
SDL_FreeSurface(fontSurface);
SDL_DestroyTexture(fontTexture); // have to draw a point before this
...
This then shows the two rects rendered before the text
If I set dstRect to NULL when calling SDL_RenderCopy then the text spans the whole window but I can see what was rendered before underneath the text.
Why am I having to draw a point after calling SDL_RenderCopy to stop what was rendered before from not showing up?
NOTE: Link to full source code https://pastebin.com/tRSFT0PV
This is a bug in SDL 2.0.10. It's fixed by https://hg.libsdl.org/SDL/rev/6ee12b88beed and this fix will ship with 2.0.11. Sorry about that!

Keeping elements on top using winapi

I've written a little app in winapi which draws animated background like so:
case WM_PAINT:
SelectObject(canvas, images[frame]);
StretchBlt(hdc, 0, 0, 640, 320, canvas, 0, 0, 64, 32, SRCCOPY);
break;
case WM_TIMER:
SelectObject(canvas, images[frame]);
StretchBlt(hdc, 0, 0, 640, 320, canvas, 0, 0, 64, 32, SRCCOPY);
frame += 1;
if (frame == sizeof(images)/sizeof(images[0]))
frame = 0;
break;
It works flawlessly but generates some problems when it comes to drawing other elements. I got some labels in the same window.
Right after first frame is drawn in WM_PAINT labels are still visible. When I replace canvas' (HDC canvas = CreateCompatibleDC(hdc)) image with second frame (in WM_TIMER), labels suddenly disappear - I guess they stay under that new layer that is drawn.
Is there any way to keep some elements always on top or bring them to top right after I redraw the bitmap?

Is it possible to create an XOR pen like DrawFocusRect()?

The Win32 GDI DrawFocusRect(HDC, const RECT*) function draws the dotted outline of a rectangle on the desired devince context. The cool thing about this function is it draws the dots using an XOR function so that when you call it a second time on the same device context and rectangle, it erases itself:
RECT rc = { 0, 0, 100, 100 };
DrawFocusRect(hdc, &rc); // draw rectangle
DrawFocusRect(hdc, &rc); // erase the rectangle we just drew
I want to achieve the same dotted line effect as DrawFocusRect() but I just want a line, not a whole rectangle. I tried doing this by passing a RECT of height 1 to DrawFocusRect() but this doesn't work because it XORs the "bottom line" of the rectange on top of the top line so nothing gets painted.
Can I create a plain HPEN that achieves the same effect as DrawFocusRect() so I can draw just a single line?
As #IInspectable commented, you want to use SetROP2(). The other half of the battle is creating the correct pen. Here is how the whole thing shakes out:
HPEN create_focus_pen()
{
LONG width(1);
SystemParametersInfo(SPI_GETFOCUSBORDERHEIGHT, 0, &width, 0);
LOGBRUSH lb = { }; // initialize to zero
lb.lbColor = 0xffffff; // white
lb.lbStyle = BS_SOLID;
return ExtCreatePen(PS.GEOMETRIC | PS.DOT, width, &lb, 0, 0);
}
void draw_focus_line(HDC hdc, HPEN hpen, POINT from, POINT to)
{
HPEN old_pen = SelectObject(hdc, hpen);
int old_rop = SetROP2(R2_XORPEN);
MoveToEx(hdc, from.x, from.y, nullptr);
LineTo(hdc, to.x, to.y);
SelectObject(hdc, old_pen);
SetROP2(old_rop);
}

Resources