I need some advice for my GUI

Discussion of chess software programming and technical issues.

Moderator: Ras

Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

I need some advice for my GUI

Post by Mike Sherwin »

I have designed my own GUI engine. It is up and running in my game Alien Cookbook. It runs in a dedicated thread and is instantly responsive and the mouse does not stutter when moving. The graphics are quite pleasing even beautiful. And I can do anything I can think of with it. The only problem I'm having with it is that I have to code everything by eye, compile, run, edit and repeat until it it looking perfect. That is a long tedious process. So I want to write a visual designer that will do all the alignment values for me at compile time. The GUI code will all be written to GUI.h. The next problem is I'm not quite sure how to go about writing a visual designer. I want it to write code for SDL2. Can someone help me to get started on the right approach?

Screenshot from Alien Cookbook showing the send ship popup. It has a lot of GUI elements. And it is keyboard capable as well as mouse activated.https://www.mediafire.com/file/lvmpr1kc ... e.PNG/file
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: I need some advice for my GUI

Post by Mike Sherwin »

I do want to use this for a special chess GUI to run my chess engine in a special realtime learning mode for as many positions as there are available threads. I'm sure that someone(s) here must have some insight on how to best go about writing a visual designer or pointing me to another site where I might find some help.
mar
Posts: 2655
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: I need some advice for my GUI

Post by mar »

if you want something that allows you to write/prototype quickly, you can take a look at ImGui, very popular for writing
debug/editor UI for games

it has automatic layouts and you then simply write code, no need for "UI designers",

Code: Select all

if (ImGui::Button("OK"))
{
    // code logic if button was clicked
}
one has to be a bit careful with unique labels, but otherwise it's absolutely amazing to work with and saves huge amounts of bloat

ImGui will then hand you a buffer with commands to draw everything, you may want to search the web for examples/tutorials and so on

https://github.com/ocornut/imgui
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: I need some advice for my GUI

Post by Mike Sherwin »

mar wrote: Tue Apr 26, 2022 3:39 pm if you want something that allows you to write/prototype quickly, you can take a look at ImGui, very popular for writing
debug/editor UI for games

it has automatic layouts and you then simply write code, no need for "UI designers",

Code: Select all

if (ImGui::Button("OK"))
{
    // code logic if button was clicked
}
one has to be a bit careful with unique labels, but otherwise it's absolutely amazing to work with and saves huge amounts of bloat

ImGui will then hand you a buffer with commands to draw everything, you may want to search the web for examples/tutorials and so on

https://github.com/ocornut/imgui
Thanks Martin. I have heard of ImGui before. Maybe it will be simple enough for me to use. But I have my new GUI engine perfected and I want to use it in my chess GUI project. I only need a layout tool for all the x,y coordinates so I do not have to do that by hand and edit them by eye. Let's say I use ImGui to make a tool with a left pane where all the types of elements and their coordinates are listed and then they are drawn in the right pane on the fly. I could have a checkbox to declare an element as static or dynamic. The static elements can be drawn only once and placed in an image block and just blited to the screen. The dynamic elements can be drawn every frame on top of the image. That way I could test the functionality with the mouse and keyboard in real time. all I'd have to have is a focus variable to know which pane I'm in. Since there are three monitors on my system I should create two windows one for each pane. Does ImGui allow two independent windows? Does ImGui have rounded rectangles? Can it really make my GUI look exactly how I want it to look? Does it imbed a runtime kernel to interpret the buffers and draw them. Is it in a DLL? No need to answer. I'm just thinking out loud. I can research these things myself. Thanks again I'll take a look.
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: I need some advice for my GUI

Post by Mike Sherwin »

I took a look at ImGui and I agree it is a fantastic product! But it is not what I want. I don't want to learn it. And I don't want to write the ImGui functions. I'll give some example code from Alien Cookbook to show what I am doing. Right now it is written for Allegro 5.

Code: Select all

bool GetEvent() {
  key = 0;
  if (al_get_next_event(queue, &event)) {
    switch (event.type) {
    case ALLEGRO_EVENT_KEY_DOWN:
      key = event.keyboard.keycode;
      switch (key) {
      case ALLEGRO_KEY_ESCAPE:
        return false;
        break;
      case ALLEGRO_KEY_PAD_MINUS:
        if (rate < 40) rate++;
        break;
      case ALLEGRO_KEY_PAD_PLUS:
        if (rate > 1) rate--;
        break;
      case ALLEGRO_KEY_D:
        demo = 1 - demo;
        break;
      case ALLEGRO_KEY_L:
        LoadGame();
        break;
      case ALLEGRO_KEY_N:
        SaveGame();
        NewGame();
        break;
      case ALLEGRO_KEY_S:
        SaveGame();
        break;
      }
      break;
    case ALLEGRO_EVENT_MOUSE_AXES:
      mx = event.mouse.x;
      my = event.mouse.y;
      break;
    case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
      mbu = false;
      mbd = event.mouse.button;
      mdx = event.mouse.x;
      mdy = event.mouse.y;
      break;
    case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
      mbd = false;
      mbu = event.mouse.button;
      mux = event.mouse.x;
      muy = event.mouse.y;
      break;
    }
  }
  return true;
}
After getting the event the event is processed.

Code: Select all

void ProcessEvent() {
  switch (gui[ui]) {
  case NONE:
    None();
    break;
  case SEND:
    Send();
    break;
  case STAND:
    Stand();
    break;
  case GAME:
    Game();
    break;
  case SELECT:
    Select();
    break;
  case PAUSED:
    Paused();
    break;
  }
}
Then in the draw frame section of the game loop.

Code: Select all

void DrawGui() {
  switch (gui[ui]) {
  case NONE:
    DrawInfo();
    break;
  case SEND:
    DrawSend();
    break;
  case STAND:
    DrawStand();
    break;
  case GAME:
    DrawGame();
    break;
  case SELECT:
    DrawSelect();
    DrawInfo();
    break;
  case PAUSED:
    DrawInfo();
    break;
  }
}
And here is the draw standing orders panel.

Code: Select all

void DrawStand() {
  int i, x, y;
  char buf[12];
  i = dst;
  if (i < numStars) {
    if (orders[org].over > 0) {
      over = orders[org].over;
      ships = orders[org].send;
      bump = orders[org].bump;
    }
    x = star[dst].x; y = star[dst].y;
    gx = x = (x < sw / 2) ? x + 20 : x - 500;
    gy = y = (y < 640) ? y : 640;
    al_draw_filled_rounded_rectangle(x, y, x + 479, y + 398, 10, 10, STEEL);
    al_draw_filled_rounded_rectangle(x + 435, y + 4, x + 475, y + 44, 10, 10, DARKSTEEL);
    al_draw_text(font35, STEEL, x + 455, y + 4, ALLEGRO_ALIGN_CENTER, "X");
    al_draw_text(font70, BLACK, x + 239, y, ALLEGRO_ALIGN_CENTRE, star[i].name);
    al_draw_line(x + 10, y + 80, x + 469, y + 80, BLACK, 4.0f);
    for (i = 0; i < 10; i++) {
      _itoa_s(i, buf, 12, 10);
      al_draw_text(font70, BLACK, x + 33 + i * 46, y + 80, ALLEGRO_ALIGN_CENTER, buf);
    }

    al_draw_line(x + 10, y + 158, x + 469, y + 158, BLACK, 4.0f);

    al_draw_text(font35, LIGHTSTEEL, x + 10, y + 168, 0, "If Over");
    al_draw_filled_rectangle(x + 140, y + 168, x + 340, y + 208, LIGHTSTEEL);
    if (active == 0) al_draw_filled_circle(x + 146, y + 173, 4, DARKSTEEL);
    _itoa_s(over, buf, 12, 10);
    al_draw_text(font35, BLACK, x + 240, y + 168, ALLEGRO_ALIGN_CENTER, buf);
    al_draw_filled_rectangle(x + 350, y + 168, x + 420, y + 208, LIGHTSTEEL);
    al_draw_text(font25, BLACK, x + 385, y + 173, ALLEGRO_ALIGN_CENTER, "Clear");
    al_draw_filled_triangle(x + 430, y + 188, x + 450, y + 168, x + 450, y + 208, LIGHTSTEEL);
    al_draw_filled_rectangle(x + 450, y + 168, x + 469, y + 208, LIGHTSTEEL);
    al_draw_text(font35, BLACK, x + 457, y + 168, ALLEGRO_ALIGN_CENTER, "X");

    al_draw_line(x + 10, y + 218, x + 469, y + 218, BLACK, 4.0f);

    al_draw_text(font35, LIGHTSTEEL, x + 10, y + 228, 0, "Send");
    al_draw_filled_rectangle(x + 140, y + 228, x + 340, y + 268, LIGHTSTEEL);
    if (active == 1) al_draw_filled_circle(x + 146, y + 233, 4, DARKSTEEL);
    _itoa_s(ships, buf, 12, 10);
    al_draw_text(font35, BLACK, x + 240, y + 228, ALLEGRO_ALIGN_CENTER, buf);
    al_draw_filled_rectangle(x + 350, y + 228, x + 469, y + 268, LIGHTSTEEL);
    al_draw_text(font25, BLACK, x + 410, y + 233, ALLEGRO_ALIGN_CENTER, "Stop All");

    al_draw_line(x + 10, y + 278, x + 469, y + 278, BLACK, 4.0f);

    al_draw_text(font35, LIGHTSTEEL, x + 10, y + 288, 0, "Bump");
    al_draw_filled_rectangle(x + 140, y + 288, x + 340, y + 328, LIGHTSTEEL);
    if (active == 2) al_draw_filled_circle(x + 146, y + 293, 4, DARKSTEEL);
    _itoa_s(bump, buf, 12, 10);
    al_draw_text(font35, BLACK, x + 240, y + 288, ALLEGRO_ALIGN_CENTER, buf);
    al_draw_filled_rectangle(x + 350, y + 288, x + 469, y + 328, LIGHTSTEEL);
    al_draw_text(font25, BLACK, x + 410, y + 293, ALLEGRO_ALIGN_CENTER, "Order");

    al_draw_line(x + 10, y + 338, x + 469, y + 338, BLACK, 4.0f);

    al_draw_filled_rounded_rectangle(x + 10, y + 348, x + 469, y + 388, 10, 10, DARKSTEEL);
    al_draw_text(font15, LIGHTSTEEL, x + 240, y + 359, ALLEGRO_ALIGN_CENTER, "Reassign ALL Standing Orders To Destination");
  }
}
And here is the code that queries the standing orders panel according to keyboard and mouse input.

Code: Select all

void Stand() {
  int i;

  if (key) {
    if (key == ALLEGRO_KEY_TAB) {
      active = active + 1;
      if (active > 2) active = 0;
    }
    else if (key >= ALLEGRO_KEY_PAD_0 && key <= ALLEGRO_KEY_PAD_9) {
      i = 9 - (ALLEGRO_KEY_PAD_9 - key);
      printf("%i  %i\n", active, i);
      if (active == 0) over = over * 10 + i;
      if (active == 1) ships = ships * 10 + i;
      if (active == 2) bump = bump * 10 + i;
    }
    else if (key == ALLEGRO_KEY_BACKSPACE) {
      if (active == 0) over = (int)(over / 10);
      if (active == 1) ships = (int)(ships / 10);
      if (active == 2) bump = (int)(bump / 10);
    }
    else if (key == ALLEGRO_KEY_ENTER) {
      if (over > 0 && ships > 0 && over >= ships) {
        orders[org].dst = dst;
        orders[org].over = over;
        orders[org].send = ships;
        orders[org].bump = bump;
        orders[org].owner = star[dst].owner;
      }
      over = 0;
      ships = 0;
      bump = 0;
      gui[ui] = NONE;
      ui--;
    }
  }
  else if (mbu) {

    if (mbu == 2) {
      if (over > 0 && ships > 0 && over >= ships) {
        orders[org].dst = dst;
        orders[org].over = over;
        orders[org].send = ships;
        orders[org].bump = bump;
        orders[org].owner = star[dst].owner;
      }
      over = 0;
      ships = 0;
      bump = 0;
      gui[ui] = NONE;
      ui--;
    }
    else if (mux > gx + 435 && mux < gx + 475 && muy > gy + 4 && muy < gy + 44) {
      if (over > 0 && ships > 0 && over >= ships) {
        orders[org].dst = dst;
        orders[org].over = over;
        orders[org].send = ships;
        orders[org].bump = bump;
        orders[org].owner = star[dst].owner;
      }
      over = 0;
      ships = 0;
      bump = 0;
      gui[ui] = NONE;
      ui--;
    }
    else if (mux > gx + 10 && mux < gx + 469 && muy > gy + 80 && muy < gy + 160) {
      if (active == 0) {
        if (over < 10000000) {
          i = (mux - gx - 10) / 46;
          over = over * 10 + i;
        }
      }
      if (active == 1) {
        if (ships < 10000000) {
          i = (mux - gx - 10) / 46;
          ships = ships * 10 + i;
        }
      }
      if (active == 2) {
        if (ships < 10000000) {
          i = (mux - gx - 10) / 46;
          bump = bump * 10 + i;
        }
      }
    }
    else if (mux > gx + 140 && mux < gx + 340 && muy > gy + 168 && muy < gy + 208) {
      active = 0;
    }
    else if (mux > gx + 140 && mux < gx + 340 && muy > gy + 228 && muy < gy + 268) {
      active = 1;
    }
    else if (mux > gx + 140 && mux < gx + 340 && muy > gy + 288 && muy < gy + 328) {
      active = 2;
    }
    else if (mux > gx + 350 && mux < gx + 420 && muy > gy + 168 && muy < gy + 208) {
      if (active == 0) over = 0;
      if (active == 1) ships = 0;
      if (active == 2) bump = 0;
      orders[org].over = 0;
    }
    else if (mux > gx + 430 && mux < gx + 469 && muy > gy + 168 && muy < gy + 208) {
      if (active == 0) over /= 10;
      if (active == 1) ships /= 10;
      if (active == 2) bump /= 10;
      orders[org].over = 0;
    }
    else if (mux > gx + 350 && mux < gx + 469 && muy > gy + 228 && muy < gy + 268) {
      for (i = 0; i < numStars; i++) orders[i].over = 0;
      over = 0;
      ships = 0;
      bump = 0;
      gui[ui] = NONE;
      ui--;
    }
    else if (mux > gx + 350 && mux < gx + 469 && muy > gy + 288 && muy < gy + 328) {
      if (over > 0 && ships > 0 && over >= ships) {
        orders[org].dst = dst;
        orders[org].over = over;
        orders[org].send = ships;
        orders[org].bump = bump;
        orders[org].owner = star[dst].owner;
      }
      over = 0;
      ships = 0;
      bump = 0;
      gui[ui] = NONE;
      ui--;
    }
    else if (mux > gx + 10 && mux < gx + 469 && muy > gy + 348 && muy < gy + 388) {
      for (i = 0; i < numStars; i++) {
        if (orders[i].dst == org) {
          orders[i].dst = dst;
          over = 0;
          ships = 0;
        }
      }
      gui[ui] = NONE;
      ui--;
    }
    mbu = false;
  }
}


So what I want is a visual designer that writes all this code for me. I even supply the code for what to do for each action.
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: I need some advice for my GUI

Post by Mike Sherwin »

Here is the MediaFire link to the 7z file containing the .exe, .c and .ttf files.
https://www.mediafire.com/file/30atlysx ... ok.7z/file
I running a bit late for something I have to do today. I forgot to include the readme so here is a link for that.
https://www.mediafire.com/file/n5bnl9b0 ... e.txt/file
dangi12012
Posts: 1062
Joined: Tue Apr 28, 2020 10:03 pm
Full name: Daniel Infuehr

Re: I need some advice for my GUI

Post by dangi12012 »

Mike Sherwin wrote: Tue Apr 26, 2022 3:12 am I have designed my own GUI engine. It is up and running in my game Alien Cookbook. It runs in a dedicated thread and is instantly responsive and the mouse does not stutter when moving. The graphics are quite pleasing even beautiful. And I can do anything I can think of with it. The only problem I'm having with it is that I have to code everything by eye, compile, run, edit and repeat until it it looking perfect. That is a long tedious process. So I want to write a visual designer that will do all the alignment values for me at compile time. The GUI code will all be written to GUI.h. The next problem is I'm not quite sure how to go about writing a visual designer. I want it to write code for SDL2. Can someone help me to get started on the right approach?

Screenshot from Alien Cookbook showing the send ship popup. It has a lot of GUI elements. And it is keyboard capable as well as mouse activated.https://www.mediafire.com/file/lvmpr1kc ... e.PNG/file
Hey mike - I happen to have solved this one for my projects. You dont need to write your own designer at all. You just need a way to serialize your Form (so all properties and locations etc. can be loaded from a file) Then you can build a simple develpment menu similar to a C# propertygrid.
Now you can easily integrate a development mode where rightclick brings up the propertygrid for the clicked object - and there you can edit location, color etc. Best is to have sliders too so you dont edit integers by hand.
You could even dynamically add buttons. On save everything is stored to disk and you are good to go.

I think this was one of my first projects: https://www.codeproject.com/Articles/78 ... at-Runtime
This solves alignment etc. All happening at runtime (so not even a designer at compiletime) and you can even write code (at runtime) that gets JIT injected into the events of a button to bootstrap a gui with application code without either an IDE or a Designer.

I was crazy back then and just did things because I had the concentration power of a teenager and the time to do so. Now I dont have that luxury anymore and have to be more selective with my projects. (Visuals.inf stores forms properties and the c# sourcecode that gets loaded when you start the app again)

You can literally try it out now: https://www.codeproject.com/KB/miscctrl ... c_Form.zip
Worlds-fastest-Bitboard-Chess-Movegenerator
Daniel Inführ - Software Developer
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: I need some advice for my GUI

Post by Mike Sherwin »

dangi12012 wrote: Fri Apr 29, 2022 1:40 am
Mike Sherwin wrote: Tue Apr 26, 2022 3:12 am I have designed my own GUI engine. It is up and running in my game Alien Cookbook. It runs in a dedicated thread and is instantly responsive and the mouse does not stutter when moving. The graphics are quite pleasing even beautiful. And I can do anything I can think of with it. The only problem I'm having with it is that I have to code everything by eye, compile, run, edit and repeat until it it looking perfect. That is a long tedious process. So I want to write a visual designer that will do all the alignment values for me at compile time. The GUI code will all be written to GUI.h. The next problem is I'm not quite sure how to go about writing a visual designer. I want it to write code for SDL2. Can someone help me to get started on the right approach?

Screenshot from Alien Cookbook showing the send ship popup. It has a lot of GUI elements. And it is keyboard capable as well as mouse activated.https://www.mediafire.com/file/lvmpr1kc ... e.PNG/file
Hey mike - I happen to have solved this one for my projects. You dont need to write your own designer at all. You just need a way to serialize your Form (so all properties and locations etc. can be loaded from a file) Then you can build a simple develpment menu similar to a C# propertygrid.
Now you can easily integrate a development mode where rightclick brings up the propertygrid for the clicked object - and there you can edit location, color etc. Best is to have sliders too so you dont edit integers by hand.
You could even dynamically add buttons. On save everything is stored to disk and you are good to go.

I think this was one of my first projects: https://www.codeproject.com/Articles/78 ... at-Runtime
This solves alignment etc. All happening at runtime (so not even a designer at compiletime) and you can even write code (at runtime) that gets JIT injected into the events of a button to bootstrap a gui with application code without either an IDE or a Designer.

I was crazy back then and just did things because I had the concentration power of a teenager and the time to do so. Now I dont have that luxury anymore and have to be more selective with my projects. (Visuals.inf stores forms properties and the c# sourcecode that gets loaded when you start the app again)

You can literally try it out now: https://www.codeproject.com/KB/miscctrl ... c_Form.zip
Thanks Daniel, I'll probably be able to have a look at it tomorrow. 8-)