• entries
    707
  • comments
    1173
  • views
    434120

More GUI development

Sign in to follow this  

132 views



A simple screenshot of child controls in action. I've got a pretty basic window ordering system in place. I might implement something better later on if I need to, but for now this works.

There's a small problem with message handling when it comes to mousemove. This message always gives me a problem for the simple fact that even though a control handles it, the rest of the controls still need to receive it so that (like in the case of a button) it can changes it's state. However, you don't want every control at that point to receive the message, because then all of the controls under the mouse will change their state. Can be routed via adding a "Handled" argument, but that seems like a hack to me and the only message that really needs it is mousemove.

Anyway, it's not much a problem if controls in the same container don't overlap (which, they shouldn't really.) The only time this was really a problem in the past was drop-down lists and since I don't plan on having those, everything should be kosher.

I'm still deciding how to implement alignment. I'd like to have controls that are aligned via my Alignments enum, but it's a lot of calculating during rendering and input messages (which is bad.) I'm thinking that I'll implement something like WinForm's anchoring. I can call "Align()" passing my Alignment flags and then anchor it where ever. It'll take a little more code on the resize end of things, but that shouldn't be too bad.

I need to cache each control's screen location. At the moment, I just call ToScreen(0, 0) and render from there, but that'll be slow in the end (well, not necessarily. Only if you have deep nested controls. Which is a very good possibility (root->form->tab_container->tab_page->groupbox->button for example.)

Anyway, just to show off some code:

class CApp : public P16::IApplication
{
P16_ClassBindSetup(CApp);

P16::CHtmlLog Log;
P16::Graphics::HFont Font;

P16::UI::CPanel Root;
P16::UI::CPanel Panel, Panel2;
P16::UI::CButton Button, Button2, Button3, Button4;

bool panelX_OnClick(P16::UI::IControl *Control, P16::Input::EMouseButton Button, long X, long Y)
{
// This is just test code. The only that should ever need to call BringToFront() is a dialog
// and that'll be done automatically.
Control->BringToFront();
return true;
}
public:
CApp() : Root("root"), Panel("panel0"), Panel2("panel1"), Button("button0"), Button2("button1"), Button3("button2"), Button4("button3") { }

virtual bool OnRun()
{
Log.Initialize("Debug.HTML");
P16::BindHtmlLog(&Log);
P16::InitializeLog();

if(!P16::Graphics::Initialize() || !P16::Graphics::CreateDevice(this->GetWindowHandle(), 640, 480))
return false;

if(!(Font = P16::Graphics::LoadFontFromFile("Resources/COAH.pbmf")))
return false;

P16::Input::Initialize();
P16::Input::OnKeyDown = P16_BindMethod1(OnKeyDown);
P16::Input::OnMouseMove = P16_BindMethod2(OnMouseMove);
P16::Input::OnMouseClick = P16_BindMethod3(OnMouseClick);
P16::Input::OnMouseRelease = P16_BindMethod3(OnMouseRelease);

Root.Move(0, 0);
Root.Resize(P16::Graphics::GetResolutionWidth(), P16::Graphics::GetResolutionHeight());
Root.SetBackgroundColor(P16::Colors::Black);
Root.SetBackgroundImage(P16::Graphics::LoadTextureFromFile("Resources/PanelBg.png"));
Root.SetBackgroundImageLayout(P16::UI::ImageLayouts::Tile);

Panel.Move(25, 25);
Panel.Resize(200, 300);
Panel.SetBackgroundColor(160, 255, 255, 255);
Panel.SetBackgroundImage(P16::Graphics::LoadTextureFromFile("Resources/RockBg2.png"));
Panel.SetBackgroundImageLayout(P16::UI::ImageLayouts::Stretch);
Panel.SetBorderColor(0, 0, 0);
Panel.SetBorderSize(1);
Panel.OnClick = P16_BindMethod4(panelX_OnClick);
Panel.SetParent(&Root);

Button.Move(10, 10);
Button.Resize(100, 26);
Button.SetText(Button.GetName());
Button.SetFont(Font);
Button.SetBackgroundColor(128, 255, 255, 255);
Button.SetParent(&Panel);

Button2.Move(10, 41);
Button2.Resize(100, 26);
Button2.SetText(Button2.GetName());
Button2.SetFont(Font);
Button2.SetBackgroundColor(128, 255, 255, 255);
Button2.SetParent(&Panel);

Panel2.Move(100, 100);
Panel2.Resize(200, 300);
Panel2.SetBackgroundColor(160, 255, 255, 255);
Panel2.SetBackgroundImage(P16::Graphics::LoadTextureFromFile("Resources/RockBg2.png"));
Panel2.SetBackgroundImageLayout(P16::UI::ImageLayouts::Stretch);
Panel2.SetBorderColor(0, 0, 0);
Panel2.SetBorderSize(1);
Panel2.OnClick = P16_BindMethod4(panelX_OnClick);
Panel2.SetParent(&Root);

Button3.Move(10, 10);
Button3.Resize(100, 26);
Button3.SetText(Button3.GetName());
Button3.SetFont(Font);
Button3.SetBackgroundColor(128, 255, 255, 255);
Button3.SetBorderSize(2);
Button3.SetParent(&Panel2);

Button4.Move(10, 41);
Button4.Resize(100, 26);
Button4.SetText(Button4.GetName());
Button4.SetFont(Font);
Button4.SetBackgroundColor(128, 255, 255, 255);
Button4.SetBorderSize(2);
Button4.SetParent(&Panel2);
return true;
}

virtual void OnCleanUp()
{
P16::Graphics::CleanUp();

P16::CleanUpLog();
Log.CleanUp();
}

virtual void OnIdle(float Seconds)
{
P16::Graphics::ClearRenderTarget(P16::Colors::CornflowerBlue);

Root.Render();

P16::Graphics::PresentRenderTarget();
}

virtual bool OnMessage(HWND Handle, UINT Message, WPARAM Param1, LPARAM Param2)
{
P16::Input::HandleMessage(Message, Param1, Param2);
/*
In the future, all I'll have to do is make sure the application
doesn't handle the message and then call something like
P16::UI::HandleMessage(Message, Param1, Param2)
*/

return false;
}

virtual void OnKeyDown(P16::Input::EKey Key)
{
if(Key == P16::Input::Keys::F1)
P16::Graphics::SetResolution(800, 600);
else if(Key == P16::Input::Keys::F2)
P16::Graphics::SetResolution(1024, 768);
else if(Key == P16::Input::Keys::F3)
P16::Graphics::SetResolution(1440, 900);
else if(Key == P16::Input::Keys::Tilde)
P16::Graphics::TakeScreenshot();
}

void OnMouseMove(long X, long Y)
{
Root.HandleMouseMove(X, Y);
}

void OnMouseClick(P16::Input::EMouseButton Button, long X, long Y)
{
Root.HandleMouseClick(Button, X, Y);
}

void OnMouseRelease(P16::Input::EMouseButton Button, long X, long Y)
{
Root.HandleMouseRelease(Button, X, Y);
}
};



Questions? Comments? Feel free to reply!
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now