![]() |
|
Silly demo |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I made this with Eagle and Allegro 5. EDIT Download here : Demo2.7z Everything is done with the mouse. LMB selects. MMB drag scrolls (only the inner window). Hover over different areas to see which widget is in focus, and to see the layering effects. Hover over the border to see the icon change to a grabby hand to move the widget on LMB press, and hover over the margin to see the resize icons. {"name":"611953","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/1\/117cf8015c51eb6108ba16240442bd18.png","w":1202,"h":941,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/1\/117cf8015c51eb6108ba16240442bd18"} Cleaned up the example code. 1
2
3
4#include "Eagle/backends/Allegro5Backend.hpp"
5#include "allegro5/allegro_color.h"
6
7
8
9class TestWidget : public WidgetBase {
10
11 virtual void PrivateDisplay(EagleGraphicsContext* win , int xpos , int ypos);
12 virtual int PrivateHandleEvent(EagleEvent ee);
13
14 virtual void OnFlagChanged(WIDGET_FLAGS f , bool on);
15
16
17public :
18 TestWidget(std::string objname) :
19 WidgetBase("TestWidget" , objname) {}
20
21};
22
23
24
25void TestWidget::PrivateDisplay(EagleGraphicsContext* win , int xpos , int ypos) {
26 Rectangle r = InnerArea();
27 r.MoveBy(xpos,ypos);
28 unsigned int flags = Flags();
29 EagleColor c1 = GetColor(MGCOL);
30 EagleColor c2 = GetColor(BGCOL);
31 if (flags & HASFOCUS) {
32 c1 = GetColor(HLCOL);
33 c2 = GetColor(FGCOL);
34 }
35 win->DrawFilledRectangle(r , (flags & HOVER)?c1:c2);
36 std::string n = ShortName();
37 win->DrawTextString(win->DefaultFont() , n , InnerArea().CX() , InnerArea().CY() , EagleColor(255,0,0) , HALIGN_CENTER , VALIGN_CENTER);
38}
39
40
41
42int TestWidget::PrivateHandleEvent(EagleEvent ee) {
43 if (ee.type == EAGLE_EVENT_MOUSE_BUTTON_DOWN && ee.mouse.button == 1) {
44 if (OuterArea().Contains(ee.mouse.x , ee.mouse.y)) {
45 return DIALOG_TAKE_FOCUS;
46 }
47 }
48 return DIALOG_OKAY;
49}
50
51
52
53void TestWidget::OnFlagChanged(WIDGET_FLAGS f , bool on) {
54 if (f == HOVER) {
55 EagleLog() << "HOVER changed to " << (on?"on":"off") << std::endl;
56 SetRedrawFlag();
57 }
58 if (f == HASFOCUS) {
59 EagleLog() << "HASFOCUS changed to " << (on?"on":"off") << std::endl;
60 SetRedrawFlag();
61 }
62}
63
64
65
66int main(int argc , char** argv) {
67
68 EnableLog();
69
70 SendOutputToFile("Eagle.log" , "" , false);
71
72 (void)argc;
73 (void)argv;
74
75/// EagleSystem* sys = Eagle::EagleLibrary::System("Allegro5");
76/// EagleSystem* sys = Eagle::EagleLibrary::System("Allegro5");
77 Allegro5System* sys = GetAllegro5System();
78
79 int sw = 1200;
80 int sh = 900;
81
82 if (EAGLE_FULL_SETUP != sys->Initialize(EAGLE_FULL_SETUP)) {
83 EagleWarn() << "Failed to install some components." << std::endl;
84 }
85 EagleGraphicsContext* win = sys->GetWindowManager()->CreateWindow("win" , sw , sh , EAGLE_OPENGL | EAGLE_WINDOWED | EAGLE_RESIZABLE);
86
87 win->Clear(EagleColor(0,255,255));
88 win->FlipDisplay();
89
90 std::string bgfile = "stallions.jpg";
91 EagleImage* bg = win->LoadImageFromFile(bgfile);
92 if (!bg || (bg && !bg->Valid())) {
93 EagleError() << StringPrintF("Failed to load %s from disk.\n" , bgfile.c_str());
94 return -1;
95 }
96
97 /// Setup some custom colors for our margin, border, and padding
98 SHAREDOBJECT<WidgetColorset> pwc = GetColorsetByName("Default");
99 EAGLE_ASSERT(pwc);
100 WidgetColorset& wc = *pwc.get();
101 wc[PADCOL] = EagleColor(127,127,127,255);
102 wc[BORDCOL] = EagleColor(255,255,255,255);
103 wc[MARGCOL] = EagleColor(0,0,0,255);
104
105
106 /// Outer root gui
107 WidgetHandler gui(win , "WidgetHandler" , "GUI1");
108 gui.SetWidgetArea(WIDGETAREA(10 , 15 , 25 , Rectangle(150,150,900,600)) , false);
109
110 /// A WidgetMover allows us to move any widgets we want
111 WidgetMover wmover("Widget mover");
112 wmover.SetWidgetArea(Rectangle(-1000,-1000,1,1) , false);
113 wmover.SetHotKey(input_key_held(EAGLE_KEY_LSHIFT) && input_key_press(EAGLE_KEY_ENTER));
114 wmover.SetAbilities(true , true);
115
116 gui << wmover;
117
118 /// Inner gui
119 WidgetHandler gui2(win , "WidgetHandler" , "GUI2");
120 gui2.SetupBuffer(1280,960,win);
121 gui2.SetWidgetArea(WIDGETAREA(5,10,15 , Rectangle(130,60,640,480)) , false);
122 gui.AllowMiddleMouseButtonScroll(false);
123 gui2.AllowMiddleMouseButtonScroll(true);
124
125 gui << gui2;
126
127 /// We can have transparent backgrounds in our gui
128 gui.SetBackgroundColor(EagleColor(0,0,0,0));
129 gui2.SetBackgroundColor(EagleColor(0,0,0,0));
130
131 /// A RelativeLayout allows us to keep relative positions and sizes of our widgets
132 RelativeLayout rl1("RLAYOUT1");
133 rl1.Resize(5);
134 rl1.SetLayoutRectangle(0 , LayoutRectangle(0.2 , 0.2 , 0.6 , 0.2));
135 rl1.SetLayoutRectangle(1 , LayoutRectangle(0.2 , 0.6 , 0.6 , 0.2));
136 rl1.SetLayoutRectangle(2 , LayoutRectangle(0.4 , 0.2 , 0.2 , 0.6));
137 rl1.SetLayoutRectangle(3 , LayoutRectangle(0.1 , 0.2 , 0.2 , 0.6));
138 rl1.SetLayoutRectangle(4 , LayoutRectangle(0.7 , 0.2 , 0.2 , 0.6));
139
140 gui2.SetRootLayout(&rl1);
141
142 TestWidget tw1("TESTWIDGETH1");
143 TestWidget tw2("TESTWIDGETH2");
144 TestWidget tw3("TESTWIDGETV1");
145 TestWidget tw4("TESTWIDGETV2");
146 TestWidget tw5("TESTWIDGETV3");
147
148 rl1.PlaceWidget(&tw1 , 0);
149 rl1.PlaceWidget(&tw2 , 1);
150 rl1.PlaceWidget(&tw3 , 2);
151 rl1.PlaceWidget(&tw4 , 3);
152 rl1.PlaceWidget(&tw5 , 4);
153
154 tw1.SetWidgetArea(WIDGETAREA(tw1.OuterArea() , 3,5,7));
155 tw2.SetWidgetArea(WIDGETAREA(tw2.OuterArea() , 7,5,3));
156 tw3.SetWidgetArea(WIDGETAREA(tw3.OuterArea() , 2,4,6));
157 tw4.SetWidgetArea(WIDGETAREA(tw4.OuterArea() , 6,4,2));
158 tw5.SetWidgetArea(WIDGETAREA(tw5.OuterArea() , 5,5,5));
159
160 EagleLog() << "******* SETUP COMPLETE ********" << std::endl;
161
162 bool quit = false;
163 bool redraw = true;
164
165 int mx = 0;
166 int my = 0;
167
168 sys->GetSystemTimer()->Start();
169
170 while (!quit) {
171 if (redraw) {
172 win->DrawToBackBuffer();
173 win->Clear(EagleColor(0,0,0));
174 win->DrawStretched(bg , Rectangle(0 , 0 , sw , sh));
175 gui.Display(win , 0 , 0);
176/// WidgetBase* hw = gui.GetWidgetAt(mx,my);
177 WidgetBase* hw = wmover.GetMoveWidget();
178 std::string name = (hw?hw->FullName():"NULL");
179 win->DrawTextString(win->DefaultFont() , StringPrintF("Widget at %d,%d is [%s]" , mx , my , name.c_str()) , sw - 10 , sh - win->DefaultFont()->Height() - 5 , EagleColor(0,0,0) , HALIGN_RIGHT , VALIGN_TOP);
180 win->FlipDisplay();
181 redraw = false;
182 }
183 do {
184 EagleEvent ev = sys->WaitForSystemEventAndUpdateState();
185 if (ev.type != EAGLE_EVENT_TIMER && ev.type != EAGLE_EVENT_MOUSE_AXES) {
186 /// Log non timer and non mouse axes events
187 EagleInfo() << "Event " << EagleEventName(ev.type) << " received in main." << std::endl;
188 }
189
190 /// Event handling
191 if (ev.type == EAGLE_EVENT_DISPLAY_CLOSE) {
192 quit = true;
193 }
194 else if (ev.type == EAGLE_EVENT_KEY_DOWN && ev.keyboard.keycode == EAGLE_KEY_ESCAPE) {
195 quit = true;
196 }
197 else if (ev.type == EAGLE_EVENT_TIMER) {
198 gui.Update(ev.timer.eagle_timer_source->SPT());
199 redraw = true;
200 }
201 else {
202 gui.HandleEvent(ev);
203 }
204
205 /// Check our gui for messages
206 while (gui.HasMessages()) {
207 WidgetMsg wmsg = gui.TakeNextMessage();
208 EagleLog() << "Widget Message [" << wmsg << "]" << std::endl;
209 }
210 if (gui.Flags().FlagOn(NEEDS_REDRAW)) {
211 redraw = true;
212 }
213
214 } while (!sys->UpToDate());
215 }
216
217/// sys->GetSystemQueue()->WaitForEvent(EAGLE_EVENT_KEY_DOWN , 0);
218
219 EagleLog() << "Exited main loop." << std::endl;
220
221/// sys->Shutdown();
222 atexit(Eagle::EagleLibrary::ShutdownEagle);
223
224 return 0;
225}
Widgets follow the CSS Box model, with a margin, border, and padding surrounding the inner client area. In the left picture, the margin is blue, the border is green, and the padding is red, so you can see it more easily. The right picture looks much better without the coloring though. Support for attributes is built in. Eventually I think styling with CSS and scripting with XML will be implemented. That seems to be the direction I'm heading anyway. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
Edgar Reynaldo said: ...scripting with XML...
{"name":"tenor.gif","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/3\/6392f3acb985a4c0d29c37ba48ad2eed.gif","w":418,"h":234,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/3\/6392f3acb985a4c0d29c37ba48ad2eed"} I assume you mean layout/content in XML. Scripting in XML, like as in programming in XML, would just be silly. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Thank you for the correction but don't you have any thing to say about the rest of it? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
All that I can really say is that you've done a lot of work on this, and that's great. You should keep it up. I have no immediate need for it, and I think that the learning curve would be quite steep for somebody that did. Also, I think that like most non-trivial software it has some design flaws, but that's to be expected. You should be proud of it and you should continue working on it. I think that a video demo would have been much more informative than still screenshots. My intention is not at all to diminish the work that you have done, and that is why my previous post was so narrow in its scope. I don't have a lot more to say on the rest of it. The only other thing that I can add is that this sort of redundancy drives me crazy: Quote: if (!bg || (bg && !bg->Valid())) { If !bg failed then bg is implied. When I see this sort of construct I am left to wonder if the author made a mistake because they're repeating themselves, and it's pointless. Of course, we all make mistakes. It's just a pet-peeve because colleagues do this regularly. This can be simplified to: if (!bg || !bg->Valid()) { Or, depending on style, though it doesn't aid in keystrokes and generally I don't find that it aides in readability either, you could transform it into this... if (!(bg && bg->Valid())) { Perhaps in this case it helps, but it's highly subjective. I appreciate languages that have an unless statement, or at least a more visual/readable not keyword so the operation isn't as easy to overlook. Particularly as our eyes age. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
bamccaig said: The only other thing that I can add is that this sort of redundancy drives me crazy: Edgar Reynaldo said:
if (!bg || (bg && !bg->Valid())) {
Ah, yes, you're correct. I like your second version the best : if (!(bg && bg->Valid())) {
bamccaig said: All that I can really say is that you've done a lot of work on this, and that's great. You should keep it up. I have no immediate need for it, and I think that the learning curve would be quite steep for somebody that did. Also, I think that like most non-trivial software it has some design flaws, but that's to be expected. You should be proud of it and you should continue working on it. I think that a video demo would have been much more informative than still screenshots. My intention is not at all to diminish the work that you have done, and that is why my previous post was so narrow in its scope. I don't have a lot more to say on the rest of it. Steep learning curve? Perhaps, but there will be full documentation by the time I release it, as well as small tutorials, and a widget creation guide. Design flaws? What would you change? Or what would you support that I'm not? I will take your advice about a video demo. I've never recorded video on my laptop before, so that will be an adventure. It's much easier to demonstrate it if you run the example program though, which is why I linked to it. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
Edgar Reynaldo said: Design flaws? What would you change? Or what would you support that I'm not? I can't say there necessarily are any. I certainly am not familiar enough with it to know them. I think that the flaws will reveal themselves when you try to develop a separate backend for it. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
bamccaig said: I can't say there necessarily are any. I certainly am not familiar enough with it to know them. I think that the flaws will reveal themselves when you try to develop a separate backend for it. Quite right, again. I originally developed Eagle for Allegro 4, and then decided I no longer wanted to be tied down to a single library, as well as reach a larger audience. So I made the abstraction layer, and implemented a driver for Allegro 5. Most of the system and everything is just modeled around Allegro 5 anyway, so when I write the SDL2 driver, I will probably need to refactor everything once more. But for that I would need someone versed in SDL, as I have zero experience with it. I could help them write the driver, but wouldn't know how specific code would have to be implemented. Anyway, it's growing, and evolving. I'm in a feature freeze right now, for the most part unless there's something really important I'm missing. So that means writing docs and test programs and debugging. Thank you bambams, for the helpful insight. Appreciated.
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|