visopsys.org

Visopsys Forums
It is currently Mon Apr 23, 2018 6:34 pm

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: GUI programming
PostPosted: Fri Sep 20, 2013 8:47 pm 
Offline

Joined: Fri Sep 20, 2013 8:43 pm
Posts: 2
Hi some help with making a GUI driver in ASM(if can C++/C is fine).

And i pmode and it must use the entire screen.


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Sat Sep 21, 2013 9:53 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 7:20 pm
Posts: 463
Hi DropKickXxs, welcome 8-)

Thanks for posting your question. I've been thinking for a while that I should post a tutorial about how to program the Visopsys GUI.

This seems like as good a time as any, so I'll try to answer your specific needs, but also provide general guidance, later in the thread.

So far, all of the GUI programs (and just about everything else) are written in C. The operating system doesn't really have runtime C++ support yet - it's not so difficult to add - I just haven't needed to do it yet.

So, C would be the easiest choice. You could code in assembler if you want; I've never tried making an application program that way, but there's no reason it couldn't be done. You'd just have to code a couple of simple support routines that would help you to interface with the rest of the system. I can write another post to tell you about that.

The operating system runs in protected mode all the time.

The GUI's "root window" is an example of a full-screen window. Would you want to do something like that - using the GUI's controls (buttons, menus, etc., etc.) - or would you want to do raw screen-drawing, like programming a game?


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Sun Sep 22, 2013 7:20 pm 
Offline

Joined: Fri Sep 20, 2013 8:43 pm
Posts: 2
Both Please.


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Tue Sep 24, 2013 1:43 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 7:20 pm
Posts: 463
I'll start with some general background.

A lot of the GUI basics of Visopsys are built right into the kernel (it is intended to be a "visual" operating system, after all). So, much of what you'll need comes directly from kernel API calls. These calls are for creating and laying out windows, creating the basic GUI components, and interacting with the windowing system. Here's a link to the documentation for these functions:

http://visopsys.org/developers/kernel_API.php#window

To use the API functions in C, you need
Code:
#include <sys/api.h>

There is some additional functionality that comes from a window library. The library has code for things like dialog boxes, composite window components, and runtime event dispatching. Here's the documentation for the library functions:

http://visopsys.org/developers/window_library.php

To use the window library in C, you need
Code:
#include <sys/window.h>
and you'll need to link the library into your executable with -lwindow, i.e.
Code:
gcc myprog.c -lwindow -o myprog

Here's a simple example. To get started, you'll probably want to create a main window, and make it visible. We'll need 2 function calls
Quote:
objectKey windowNew(int processId, const char *title)
Create a new window, owned by the process 'processId', and with the title 'title'. Returns an object key to reference the window, needed by most other window functions below (such as adding components to the window)

int windowSetVisible(objectKey window, int visible)
Tell the windowing system whether to make 'window' visible or not. Non-zero 'visible' means make the window visible. When windows are created, they are not visible by default so you can add components, do layout, set the size, etc.
Here's the code
Code:
#include <sys/api.h>

objectKey window;

void main(void)
{
   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   windowSetVisible(window, 1);

   while (1);
}

And here's what we get:
Attachment:
emptywindow.png
emptywindow.png [ 8.56 KiB | Viewed 12187 times ]
Cute, but not too useful yet. :lol: We'll have to start putting some components in there.

There are several different types of basic components:
  • button
  • canvas
  • checkbox
  • divider
  • icon
  • image
  • list (and list item)
  • menu (and menu item)
  • menu bar
  • password field
  • progress bar
  • radio button
  • scrollbar
  • slider
  • text area
  • text field
  • text label

We'll start with a label and a button. Here are the functions for creating them:
Quote:
objectKey windowNewTextLabel(objectKey parent, const char *text, componentParameters *params)
Get a new text labelComponent to be placed inside the parent object 'parent', with the given component parameters 'params', and using the text string 'text'. If the params 'font' is NULL, the default font will be used.

objectKey windowNewButton(objectKey parent, const char *label, image *buttonImage, componentParameters *params)
Get a new button component to be placed inside the parent object 'parent', with the given component parameters, and with the (optional) label 'label', or the (optional) image 'buttonImage'. Either 'label' or 'buttonImage' can be used, but not both.

When we create a component, we need to supply some component parameters (defined in <sys/window.h>)
Code:
// This structure is needed to describe parameters consistent to all
// window components
typedef struct {
   int gridX;                     // Grid X coordinate
   int gridY;                     // Grid Y coordinate
   int gridWidth;                  // Grid span width
   int gridHeight;                  // Grid span height
   int padLeft;                  //
   int padRight;                  // Pixels of empty space (padding)
   int padTop;                  // around each side of the component
   int padBottom;                  //
   int flags;                     // Attributes - See WINDOW_COMPFLAG_*
   componentXOrientation orientationX;      // orient_left, orient_center, orient_right
   componentYOrientation orientationY;      // orient_top, orient_middle, orient_bottom
   color foreground;               // Foreground drawing color
   color background;               // Background frawing color
   objectKey font;                  // Font for text

} componentParameters;

Windows are laid out somewhat like tables in HTML. Each component occupies one grid cell. The gridX and gridY values specify which cell. If the cell should span the width or height of adjacent cells, then gridWidth and gridHeight are used for that. Here's the code now when we add our components:
Code:
#include <sys/api.h>
#include <sys/window.h>
#include <string.h>

objectKey window;
objectKey okButton;

void main(void)
{
   componentParameters params;

   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   // Set up the parameters for our label
   memset(&params, 0, sizeof(componentParameters));
   params.gridX = 0;
   params.gridY = 0;
   params.gridWidth = 1;
   params.gridHeight = 1;

   // Create the label
   windowNewTextLabel(window, "Welcome to my program", &params);

   // Reuse the parameters from the label, but change the grid coordinate
   params.gridY = 1;

   // Create the button, and save a global reference to it
   okButton = windowNewButton(window, "OK", NULL, &params);

   windowSetVisible(window, 1);

   while (1);
}

It doesn't look great, but at least our window now has something in it:
Attachment:
label+button.png
label+button.png [ 9.52 KiB | Viewed 12187 times ]

The following function can help us to see how the grid layout is being interpreted:
Quote:
void windowDebugLayout(objectKey window)
This function draws grid boxes around all the grid cells containing components (or parts thereof).

Lets add some more to our component parameters to fix the layout:
Code:
#include <sys/api.h>
#include <sys/window.h>
#include <string.h>

objectKey window;
objectKey okButton;

void main(void)
{
   componentParameters params;

   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   // Set up the parameters for our label
   memset(&params, 0, sizeof(componentParameters));
   params.gridX = 0;
   params.gridY = 0;
   params.gridWidth = 1;
   params.gridHeight = 1;
   params.padTop = 5;      // Add some padding
   params.padLeft = 5;      // around the top,
   params.padRight = 5;   // left, and bottom
   params.orientationX = orient_center;   // Center of the cell
   params.orientationY = orient_middle;   // middle of the cell

   // Create the label
   windowNewTextLabel(window, "Welcome to my program", &params);

   // Reuse the parameters from the label, but change the grid coordinate,
   // add some padding on the bottom, and prevent the button from expanding
   // to fill its cell
   params.gridY = 1;
   params.padBottom = 5;
   params.flags = (WINDOW_COMPFLAG_FIXEDHEIGHT | WINDOW_COMPFLAG_FIXEDWIDTH);

   // Create the button, and save a global reference to it
   okButton = windowNewButton(window, "OK", NULL, &params);

   //windowDebugLayout(window);
   windowSetVisible(window, 1);

   while (1);
}

Here's how it looks now (with and without grid debugging):
Attachment:
debug-layout.png
debug-layout.png [ 9.43 KiB | Viewed 12187 times ]
Attachment:
improved-layout.png
improved-layout.png [ 9.24 KiB | Viewed 12187 times ]


So there we have some basic window creation. In the next installment, I'll talk about how the runtime event handling works (so that we can make that button do something useful).


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Wed Sep 25, 2013 5:55 am 
Offline

Joined: Thu Aug 15, 2013 4:23 pm
Posts: 22
Hi Andy,

I think your last post here about how to program the Visopsys GUI is just great! :D

It would be nice to know more about this topic. Thank you! :dance:

Oscar


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Wed Nov 27, 2013 10:47 pm 
Offline
User avatar

Joined: Mon Sep 09, 2013 12:16 am
Posts: 58
Location: Paraguay
Hi! How can I use text files to store data and select data from it for display? I need something like a database.

Example text file:

Quote:
Name1*Value1*Value2
Name2*Value1*Value2
Name3*Value1*Value2
Name4*Value1*Value2


Now I want to add a new Name5 with values, delete Name1 with its values, edit Value1 of Name3 and display the values of Name2.

I hope you understand me...

_________________
My Homepage: http://www.fosforito.net/ :)


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Tue Dec 03, 2013 1:45 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 7:20 pm
Posts: 463
Sorry for the slow reply, I had to take an un-planned trip!

The kernel has several functions for reading and writing configuration files:
Code:
int kernelConfigRead(const char *, variableList *);
int kernelConfigWrite(const char *, variableList *);
int kernelConfigGet(const char *, const char *, char *, unsigned);
int kernelConfigSet(const char *, const char *, const char *);
int kernelConfigUnset(const char *, const char *);

These are exported to user programs in src/include/sys/api.h:
Code:
int configRead(const char *, variableList *);
int configWrite(const char *, variableList *);
int configGet(const char *, const char *, char *, unsigned);
int configSet(const char *, const char *, const char *);
int configUnset(const char *, const char *);

The functions are documented here: http://visopsys.org/developers/kernel_API.php#miscellaneous. 'variableList' is defined in src/include/sys/variable.h

The current format expects name=value pairs in the file, but this is fairly extensible when used with the concept of name-spaces. For example, in the file dist/system/config/desktop.conf:
Code:
icon.name.computer=Computer
icon.computer.image=/system/icons/compicon.ico
icon.computer.command=/programs/computer

I define an icon.name.<whatever>=..., and then define properties for that thing with lines that say icon.<whatever>.<propertyname>=...

It's somewhat primitive, but also kind of elegant and simple IMHO :ugeek: :lol:


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Tue Mar 11, 2014 3:10 pm 
Offline
User avatar

Joined: Tue Feb 14, 2012 12:40 am
Posts: 103
andymc wrote:
I'll start with some general background.

A lot of the GUI basics of Visopsys are built right into the kernel (it is intended to be a "visual" operating system, after all). So, much of what you'll need comes directly from kernel API calls. These calls are for creating and laying out windows, creating the basic GUI components, and interacting with the windowing system. Here's a link to the documentation for these functions:

http://visopsys.org/developers/kernel_API.php#window

To use the API functions in C, you need
Code:
#include <sys/api.h>

There is some additional functionality that comes from a window library. The library has code for things like dialog boxes, composite window components, and runtime event dispatching. Here's the documentation for the library functions:

http://visopsys.org/developers/window_library.php

To use the window library in C, you need
Code:
#include <sys/window.h>
and you'll need to link the library into your executable with -lwindow, i.e.
Code:
gcc myprog.c -lwindow -o myprog

Here's a simple example. To get started, you'll probably want to create a main window, and make it visible. We'll need 2 function calls
Quote:
objectKey windowNew(int processId, const char *title)
Create a new window, owned by the process 'processId', and with the title 'title'. Returns an object key to reference the window, needed by most other window functions below (such as adding components to the window)

int windowSetVisible(objectKey window, int visible)
Tell the windowing system whether to make 'window' visible or not. Non-zero 'visible' means make the window visible. When windows are created, they are not visible by default so you can add components, do layout, set the size, etc.
Here's the code
Code:
#include <sys/api.h>

objectKey window;

void main(void)
{
   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   windowSetVisible(window, 1);

   while (1);
}

And here's what we get:
Attachment:
emptywindow.png
Cute, but not too useful yet. :lol: We'll have to start putting some components in there.

There are several different types of basic components:
  • button
  • canvas
  • checkbox
  • divider
  • icon
  • image
  • list (and list item)
  • menu (and menu item)
  • menu bar
  • password field
  • progress bar
  • radio button
  • scrollbar
  • slider
  • text area
  • text field
  • text label

We'll start with a label and a button. Here are the functions for creating them:
Quote:
objectKey windowNewTextLabel(objectKey parent, const char *text, componentParameters *params)
Get a new text labelComponent to be placed inside the parent object 'parent', with the given component parameters 'params', and using the text string 'text'. If the params 'font' is NULL, the default font will be used.

objectKey windowNewButton(objectKey parent, const char *label, image *buttonImage, componentParameters *params)
Get a new button component to be placed inside the parent object 'parent', with the given component parameters, and with the (optional) label 'label', or the (optional) image 'buttonImage'. Either 'label' or 'buttonImage' can be used, but not both.

When we create a component, we need to supply some component parameters (defined in <sys/window.h>)
Code:
// This structure is needed to describe parameters consistent to all
// window components
typedef struct {
   int gridX;                     // Grid X coordinate
   int gridY;                     // Grid Y coordinate
   int gridWidth;                  // Grid span width
   int gridHeight;                  // Grid span height
   int padLeft;                  //
   int padRight;                  // Pixels of empty space (padding)
   int padTop;                  // around each side of the component
   int padBottom;                  //
   int flags;                     // Attributes - See WINDOW_COMPFLAG_*
   componentXOrientation orientationX;      // orient_left, orient_center, orient_right
   componentYOrientation orientationY;      // orient_top, orient_middle, orient_bottom
   color foreground;               // Foreground drawing color
   color background;               // Background frawing color
   objectKey font;                  // Font for text

} componentParameters;

Windows are laid out somewhat like tables in HTML. Each component occupies one grid cell. The gridX and gridY values specify which cell. If the cell should span the width or height of adjacent cells, then gridWidth and gridHeight are used for that. Here's the code now when we add our components:
Code:
#include <sys/api.h>
#include <sys/window.h>
#include <string.h>

objectKey window;
objectKey okButton;

void main(void)
{
   componentParameters params;

   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   // Set up the parameters for our label
   memset(&params, 0, sizeof(componentParameters));
   params.gridX = 0;
   params.gridY = 0;
   params.gridWidth = 1;
   params.gridHeight = 1;

   // Create the label
   windowNewTextLabel(window, "Welcome to my program", &params);

   // Reuse the parameters from the label, but change the grid coordinate
   params.gridY = 1;

   // Create the button, and save a global reference to it
   okButton = windowNewButton(window, "OK", NULL, &params);

   windowSetVisible(window, 1);

   while (1);
}

It doesn't look great, but at least our window now has something in it:
Attachment:
label+button.png

The following function can help us to see how the grid layout is being interpreted:
Quote:
void windowDebugLayout(objectKey window)
This function draws grid boxes around all the grid cells containing components (or parts thereof).

Lets add some more to our component parameters to fix the layout:
Code:
#include <sys/api.h>
#include <sys/window.h>
#include <string.h>

objectKey window;
objectKey okButton;

void main(void)
{
   componentParameters params;

   // Create a new window, and save a global reference to it
   window = windowNew(multitaskerGetCurrentProcessId(), "MyProg");
   if (window == NULL)
      return;

   // Set up the parameters for our label
   memset(&params, 0, sizeof(componentParameters));
   params.gridX = 0;
   params.gridY = 0;
   params.gridWidth = 1;
   params.gridHeight = 1;
   params.padTop = 5;      // Add some padding
   params.padLeft = 5;      // around the top,
   params.padRight = 5;   // left, and bottom
   params.orientationX = orient_center;   // Center of the cell
   params.orientationY = orient_middle;   // middle of the cell

   // Create the label
   windowNewTextLabel(window, "Welcome to my program", &params);

   // Reuse the parameters from the label, but change the grid coordinate,
   // add some padding on the bottom, and prevent the button from expanding
   // to fill its cell
   params.gridY = 1;
   params.padBottom = 5;
   params.flags = (WINDOW_COMPFLAG_FIXEDHEIGHT | WINDOW_COMPFLAG_FIXEDWIDTH);

   // Create the button, and save a global reference to it
   okButton = windowNewButton(window, "OK", NULL, &params);

   //windowDebugLayout(window);
   windowSetVisible(window, 1);

   while (1);
}

Here's how it looks now (with and without grid debugging):
Attachment:
debug-layout.png
Attachment:
improved-layout.png


So there we have some basic window creation. In the next installment, I'll talk about how the runtime event handling works (so that we can make that button do something useful).


This was nice to read... :) Still waiting for the next installment, whenever you have the time :pray:

_________________
Image
Image


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Tue Mar 11, 2014 3:15 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 7:20 pm
Posts: 463
Heheh, yes, I will. But ... the time :-)


Top
 Profile  
 
 Post subject: Re: GUI programming
PostPosted: Tue Mar 18, 2014 7:56 pm 
Offline
User avatar

Joined: Mon Sep 09, 2013 12:16 am
Posts: 58
Location: Paraguay
Quote:
So there we have some basic window creation. In the next installment, I'll talk about how the runtime event handling works (so that we can make that button do something useful).


Hello Andy, when you have time, can you please explain how to do that? It would be very useful. ;)

_________________
My Homepage: http://www.fosforito.net/ :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group