bcbf383f76101c597d1db97a5e14e08ab7653203
[sdk] / samples / net / browser / browser.ec
1 import "HTMLView"
2
3 //define homeLocation = "localhost:8080";
4 //define homeLocation = "www.ecere.com";
5 define homeLocation = "google.com";
6
7 class AddressBar : Window
8 {
9    background = activeBorder;
10    tabCycle = true;
11    Button back
12    {
13       this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
14       disabled = true;
15
16       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
17       {
18          ((Explorer)parent).Back();
19          return true;
20       }
21    };
22    Button forward
23    {
24       this, bevelOver = true, inactive = true, anchor = Anchor { left = 24, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
25       disabled = true;
26
27       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
28       {
29          ((Explorer)parent).Forward();
30          return true;
31       }
32    };
33    Button home
34    {
35       this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
36
37       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
38       {
39          ((Explorer)parent).Go(homeLocation);
40          return true;
41       }
42    };
43    Button refresh
44    {
45       this, bevelOver = true, inactive = true, anchor = Anchor { left = 76, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = f5, bitmap = { "<:ecere>actions/viewRefresh.png" };
46
47       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
48       {
49          ((Explorer)parent).Refresh();
50          return true;
51       }
52    };
53    Label { this, anchor = Anchor { left = (96+12) }, labeledWindow = address };
54    EditBox address
55    {
56       this, text = "Address:", anchor = Anchor { left = (16+48+96), right = 60, top = 0, bottom = 0 }, hotKey = altD;
57
58       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
59       {
60          if(!go.disabled && (SmartKey)key == enter)
61             ((Explorer)parent).Go(editBox.contents);
62          return true;
63       }
64
65       void NotifyUpdate(EditBox editBox)
66       {
67          String location = ((Explorer)parent).htmlView.location;
68          go.disabled = !strcmp(location ? location : "", editBox.contents);
69       }
70    };
71    Button go
72    {
73       this, bevelOver = true, inactive = true, text = "Go!", anchor = Anchor { top = 0, right = 0, bottom = 0 }, size = Size { 60 }, hotKey = altG;
74
75       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
76       {
77          ((Explorer)parent).Go(address.contents);
78          return true;
79       }
80    };
81
82    bool OnKeyHit(Key key, unichar ch)
83    {
84       if(key == escape)
85          ((Explorer)parent).htmlView.MakeActive();
86       return true;
87    }
88 }
89
90 class Explorer : Window
91 {
92    FileDialog openFileDialog { caption = "Select a file or enter a URL... " };
93    FileDialog saveFileDialog { type = save, caption = "Save to file... " };
94
95    icon = { ":newb.png" };
96
97    tabCycle = true;
98    background = activeBorder;
99    hasMenuBar = true;
100    hasStatusBar = true;
101    borderStyle = sizable;
102    hasClose = true;
103    hasMaximize = true;
104    hasMinimize = true;
105    text = "Ecere Web Browser";
106    size = Size { 800, 600 };
107    state = maximized;
108
109    AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
110    HTMLView htmlView { this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true, anchor = Anchor { left = 0, right = 0, top = 26, bottom = 0 }, NotifyPageOpened = PageOpened, OnOpen = OnOpen };
111
112    // File Menu
113    menu = Menu {};
114    Menu fileMenu { menu, "File", f };
115    MenuItem newWindowItem
116    {
117       fileMenu, "New Window\tCtrl+N", n, ctrlN;
118
119       bool NotifySelect(MenuItem selection, Modifiers mods)
120       {
121          Explorer { state = normal }.Create();
122          return true;
123       }
124    };
125    MenuItem openItem
126    {
127       fileMenu, "Open...\tCtrl+O", o, ctrlO;
128
129       bool NotifySelect(MenuItem selection, Modifiers mods)
130       {
131          if(openFileDialog.Modal() == ok)
132             Go(openFileDialog.filePath);
133          return true;
134       }
135    };
136    // MenuItem closeItem { fileMenu, "Close\tCtrl-F4", c, NotifySelect = MenuFileClose };
137    MenuDivider { fileMenu };
138    MenuItem saveAsItem
139    {
140       fileMenu, "Save As...";
141
142       bool NotifySelect(MenuItem selection, Modifiers mods)
143       {
144          char fileName[MAX_LOCATION];
145          GetLastDirectory(htmlView.location, fileName);
146          strcpy(fileName, saveFileDialog.currentDirectory);
147          PathCat(fileName, fileName);
148          saveFileDialog.filePath = fileName;
149
150          if(saveFileDialog.Modal() == ok)
151          {
152             File f = FileOpen(htmlView.location, read);
153             if(f)
154             {               
155                if(!f.CopyTo(saveFileDialog.filePath))
156                {
157                   String e = PrintString("Error saving to ", saveFileDialog.filePath);
158                   MessageBox { contents = e }.Modal();
159                   delete e;
160                }
161             }
162          }
163          return true;
164       }
165    };
166    MenuDivider { fileMenu };
167    MenuItem exitItem { fileMenu, "Exit\tAlt+F4", x, NotifySelect = MenuFileExit };
168    
169    bool PageOpened()
170    {
171       char caption[MAX_LOCATION];
172
173       strcpy(caption, "Ecere Web Browser - ");
174       strcat(caption, htmlView.title);
175
176       text = caption;
177       addressBar.address.Clear();
178       addressBar.address.PutS(htmlView.fileName);
179       return true;
180    }
181
182    bool OnPostCreate()
183    {  
184       addressBar.MakeActive();
185       return true;
186    }
187
188    Array<String> history { };
189    int historyPos;
190
191    ~Explorer()
192    {
193       history.Free();
194    }
195
196    bool HTMLView::OnOpen(char * href)
197    {
198       bool result = true;
199       char newLocation[MAX_LOCATION];
200       Explorer explorer = (Explorer)parent;
201
202       strcpy(newLocation, location ? location : "");
203       if(newLocation[strlen(newLocation)-1] != '/')
204          PathCat(newLocation, "..");
205       if(href[0] == '/' && href[1] == '/')
206       {
207          strcpy(newLocation, "http:");
208          strcat(newLocation, href);
209       }
210       else
211          PathCat(newLocation, href);
212
213       if(explorer.history.count > explorer.historyPos+1)
214       {
215          int i;
216          for(i = explorer.historyPos+1; i < explorer.history.count; i++)
217             delete explorer.history[i];
218          explorer.history.count = explorer.historyPos+1;
219       }
220       explorer.historyPos = explorer.history.count-1;
221       explorer.addressBar.back.disabled = (explorer.historyPos == 0);
222       explorer.addressBar.forward.disabled = (explorer.historyPos >= explorer.history.count-1);
223
224       Open(newLocation, null);
225
226       explorer.history.Add(CopyString(location));
227       explorer.historyPos = explorer.history.count-1;
228
229       explorer.addressBar.back.disabled = (explorer.historyPos == 0);
230       explorer.addressBar.forward.disabled = (explorer.historyPos >= explorer.history.count-1);
231       return result;
232    }
233
234    void Go(const String location)
235    {
236       if(history.count > historyPos+1)
237       {
238          int i;
239          for(i = historyPos+1; i < history.count; i++)
240             delete history[i];
241          history.count = historyPos+1;
242       }
243       history.Add(CopyString(location));
244       historyPos = history.count-1;
245       addressBar.back.disabled = (historyPos == 0);
246       addressBar.forward.disabled = (historyPos >= history.count-1);
247       htmlView.MakeActive();
248       htmlView.location = location;
249    }
250
251    void Refresh()
252    {
253       htmlView.MakeActive();
254       if(history.count)
255          htmlView.location = history[historyPos];
256    }
257
258    bool Forward()
259    {
260       if(historyPos < history.count-1)
261       {
262          historyPos++;
263          addressBar.back.disabled = (historyPos == 0);
264          addressBar.forward.disabled = (historyPos >= history.count-1);
265          htmlView.location = history[historyPos];
266          return true;
267       }
268       return false;
269    }
270
271    bool Back()
272    {
273       if(historyPos > 0)
274       {
275          historyPos--;
276          addressBar.back.disabled = (historyPos == 0);
277          addressBar.forward.disabled = (historyPos >= history.count-1);
278          htmlView.location = history[historyPos];
279          return true;
280       }
281       return false;
282    }
283
284    bool OnKeyHit(Key key, unichar ch)
285    {
286       if(key == ctrlR)
287       {
288          Refresh();
289          return false;
290       }
291       return true;
292    }
293 }
294
295 #ifndef ECERE_MODULE
296
297 class BrowserApp : GuiApplication
298 {
299    //driver = "OpenGL";
300    Explorer explorerWindow {};
301
302    bool Init()
303    {
304       app = this;
305
306    #ifndef ECERE_MODULE
307       if(argc > 1)
308          explorerWindow.Go(argv[1]);
309       else
310    #endif
311          explorerWindow.Go(homeLocation);
312       return true;
313    }
314 }
315
316 BrowserApp app;
317
318 #else
319
320 extern GuiApplication app;
321
322 #endif