diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-06-27 17:34:51 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2011-06-27 17:34:51 (GMT) |
commit | 4ef496df68eb7c778e4624f924de7f93829b7ae0 (patch) | |
tree | d1aca8af94a5fbb5abac44173db5051117401dff /src | |
parent | b08a5a2017764170706032e79ae0a8e95a928f25 (diff) | |
download | fluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.zip fluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.tar.bz2 |
A veeeery rough implementation of lua menu parsers
Diffstat (limited to 'src')
-rw-r--r-- | src/FbTk/Menu.cc | 2 | ||||
-rw-r--r-- | src/FbTk/Menu.hh | 2 | ||||
-rw-r--r-- | src/FbTk/MenuItem.hh | 4 | ||||
-rw-r--r-- | src/MenuCreator.cc | 151 | ||||
-rw-r--r-- | src/MenuCreator.hh | 7 | ||||
-rw-r--r-- | src/Screen.cc | 7 |
6 files changed, 168 insertions, 5 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index 40f81c8..e52b4dd 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc | |||
@@ -219,7 +219,7 @@ Menu::~Menu() { | |||
219 | s_focused = 0; | 219 | s_focused = 0; |
220 | } | 220 | } |
221 | 221 | ||
222 | int Menu::insert(const FbString &label, RefCount<Command<void> > &cmd, int pos) { | 222 | int Menu::insert(const FbString &label, const RefCount<Command<void> > &cmd, int pos) { |
223 | return insert(new MenuItem(label, cmd, this), pos); | 223 | return insert(new MenuItem(label, cmd, this), pos); |
224 | } | 224 | } |
225 | 225 | ||
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh index bd830b4..4096295 100644 --- a/src/FbTk/Menu.hh +++ b/src/FbTk/Menu.hh | |||
@@ -61,7 +61,7 @@ public: | |||
61 | */ | 61 | */ |
62 | //@{ | 62 | //@{ |
63 | /// add a menu item with a label and a command | 63 | /// add a menu item with a label and a command |
64 | int insert(const FbString &label, RefCount<Command<void> > &cmd, int pos=-1); | 64 | int insert(const FbString &label, const RefCount<Command<void> > &cmd, int pos=-1); |
65 | /// add empty menu item | 65 | /// add empty menu item |
66 | int insert(const FbString &label, int pos=-1); | 66 | int insert(const FbString &label, int pos=-1); |
67 | /// add submenu | 67 | /// add submenu |
diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh index 2149559..cc24228 100644 --- a/src/FbTk/MenuItem.hh +++ b/src/FbTk/MenuItem.hh | |||
@@ -69,7 +69,7 @@ public: | |||
69 | m_toggle_item(false) | 69 | m_toggle_item(false) |
70 | { } | 70 | { } |
71 | /// create a menu item with a specific command to be executed on click | 71 | /// create a menu item with a specific command to be executed on click |
72 | MenuItem(const BiDiString &label, RefCount<Command<void> > &cmd, Menu *menu = 0) | 72 | MenuItem(const BiDiString &label, const RefCount<Command<void> > &cmd, Menu *menu = 0) |
73 | : m_label(label), | 73 | : m_label(label), |
74 | m_menu(menu), | 74 | m_menu(menu), |
75 | m_submenu(0), | 75 | m_submenu(0), |
@@ -91,7 +91,7 @@ public: | |||
91 | { } | 91 | { } |
92 | virtual ~MenuItem() { } | 92 | virtual ~MenuItem() { } |
93 | 93 | ||
94 | void setCommand(RefCount<Command<void> > &cmd) { m_command = cmd; } | 94 | void setCommand(const RefCount<Command<void> > &cmd) { m_command = cmd; } |
95 | virtual void setSelected(bool selected) { m_selected = selected; } | 95 | virtual void setSelected(bool selected) { m_selected = selected; } |
96 | virtual void setEnabled(bool enabled) { m_enabled = enabled; } | 96 | virtual void setEnabled(bool enabled) { m_enabled = enabled; } |
97 | virtual void setLabel(const BiDiString &label) { m_label = label; } | 97 | virtual void setLabel(const BiDiString &label) { m_label = label; } |
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index 74968e3..60669db 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc | |||
@@ -365,8 +365,159 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc | |||
365 | return true; | 365 | return true; |
366 | } | 366 | } |
367 | 367 | ||
368 | string getField(lua::state &l, int pos, const char *field, FbTk::StringConvertor *conv = NULL) { | ||
369 | lua::stack_sentry s(l); | ||
370 | l.checkstack(1); | ||
371 | _FB_USES_NLS; | ||
372 | |||
373 | string val; | ||
374 | l.rawgetfield(pos, field); { | ||
375 | if(l.isstring(-1)) | ||
376 | val = l.tostring(-1); | ||
377 | else if(! l.isnil(-1)) { | ||
378 | fprintf(stderr, _FB_CONSOLETEXT(Menu, FieldNotString, | ||
379 | "Warning: Menu field %s is not a string", "One %s for field name.").c_str(), | ||
380 | field); | ||
381 | fputs("\n", stderr); | ||
382 | } | ||
383 | } l.pop(); | ||
384 | return conv ? conv->recode(val) : val; | ||
385 | } | ||
386 | |||
387 | std::auto_ptr<FbMenu> | ||
388 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
389 | FbTk::AutoReloadHelper *reloader); | ||
390 | |||
391 | void | ||
392 | insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | ||
393 | FbTk::AutoReloadHelper *reloader) { | ||
394 | lua::stack_sentry s(l, -1); | ||
395 | l.checkstack(1); | ||
396 | |||
397 | if(l.type(-1) != lua::TTABLE) | ||
398 | throw std::runtime_error(_FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", "Menu is not a lua table")); | ||
399 | |||
400 | // if menu specifies an encoding, create a convertor for it | ||
401 | std::auto_ptr<FbTk::StringConvertor> my_conv; | ||
402 | |||
403 | FbTk::StringConvertor *conv = &parent_conv; | ||
404 | const string &encoding = getField(l, -1, "encoding"); | ||
405 | if(! encoding.empty()) { | ||
406 | my_conv.reset(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
407 | conv = my_conv.get(); | ||
408 | conv->setSource(encoding); | ||
409 | } | ||
410 | |||
411 | const string &str_label = getField(l, -1, "label", conv); | ||
412 | const string &str_key = getField(l, -1, "type"); | ||
413 | const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance(); | ||
414 | BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); | ||
415 | size_t old_size = menu.numberOfItems(); | ||
416 | |||
417 | // first items that don't need additional parameters | ||
418 | if(str_key == "separator") | ||
419 | menu.insert(new FbTk::MenuSeparator()); | ||
420 | else if(str_key == "nop") { | ||
421 | int size = menu.insert(str_label); | ||
422 | menu.setItemEnabled(size-1, false); | ||
423 | } else if(str_key == "icons") { | ||
424 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber()); | ||
425 | if (submenu == 0) | ||
426 | return; | ||
427 | if (str_label.empty()) | ||
428 | menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu); | ||
429 | else | ||
430 | menu.insert(str_label, submenu); | ||
431 | } else if (str_key == "exit") { // exit | ||
432 | FbTk::RefCount<FbTk::Command<void> > exit_cmd(FbTk::CommandParser<void>::instance().parse("exit")); | ||
433 | if (str_label.empty()) | ||
434 | menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd); | ||
435 | else | ||
436 | menu.insert(str_label, exit_cmd); | ||
437 | } else if (str_key == "config") { | ||
438 | menu.insert(str_label, &screen->configMenu()); | ||
439 | } else if(str_key == "menu") { | ||
440 | l.pushvalue(-1); | ||
441 | menu.insert(str_label, createMenu_(l, menu.screenNumber(), *conv, reloader).release()); | ||
442 | } else { | ||
443 | // items that have a parameter | ||
444 | const string &str_cmd = getField(l, -1, "param"); | ||
445 | |||
446 | if(str_key == "command") { | ||
447 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
448 | parser.parse(str_cmd)) ); | ||
449 | } else if(str_key == "exec") { | ||
450 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
451 | parser.parse("exec", str_cmd)) ); | ||
452 | } else if(str_key == "style") | ||
453 | menu.insert(new StyleMenuItem(str_label, str_cmd)); | ||
454 | else if (str_key == "stylesdir") | ||
455 | createStyleMenu(menu, str_label, reloader, str_cmd); | ||
456 | else if (str_key == "wallpapers") { | ||
457 | const string &program = getField(l, -1, "program"); | ||
458 | createRootCmdMenu(menu, str_label, str_cmd, reloader, | ||
459 | program.empty() ? realProgramName("fbsetbg") : program); | ||
460 | } else if (str_key == "workspaces") { | ||
461 | /* screen->workspaceMenu().setInternalMenu(); | ||
462 | menu.insert(str_label, &screen->workspaceMenu());*/ | ||
463 | } | ||
464 | } | ||
465 | |||
466 | const string &icon = getField(l, -1, "icon"); | ||
467 | if(! icon.empty()) { | ||
468 | while(old_size < menu.numberOfItems()) | ||
469 | menu.find(old_size++)->setIcon(icon, menu.screenNumber()); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | std::auto_ptr<FbMenu> | ||
474 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
475 | FbTk::AutoReloadHelper *reloader) { | ||
476 | |||
477 | lua::stack_sentry s(l, -1); | ||
478 | l.checkstack(1); | ||
479 | |||
480 | std::auto_ptr<FbMenu> menu( MenuCreator::createMenu(getField(l, -1, "label", &conv), | ||
481 | screen_number) ); | ||
482 | |||
483 | for(int i = 1; l.rawgeti(-1, i), !l.isnil(-1); ++i) { | ||
484 | try { | ||
485 | insertMenuItem(l, *menu, conv, reloader); | ||
486 | } | ||
487 | catch(std::runtime_error &e) { | ||
488 | cerr << e.what() << endl; | ||
489 | } | ||
490 | } l.pop(); | ||
491 | |||
492 | l.pop(); | ||
493 | return menu; | ||
494 | } | ||
495 | |||
368 | } // end of anonymous namespace | 496 | } // end of anonymous namespace |
369 | 497 | ||
498 | std::auto_ptr<FbMenu> | ||
499 | MenuCreator::createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader) { | ||
500 | lua::stack_sentry s(l, -1); | ||
501 | l.checkstack(1); | ||
502 | |||
503 | if(l.type(-1) != lua::TTABLE) { | ||
504 | cerr << _FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", | ||
505 | "Menu is not a lua table") << endl; | ||
506 | return std::auto_ptr<FbMenu>(); | ||
507 | } | ||
508 | |||
509 | std::auto_ptr<FbTk::StringConvertor> conv(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
510 | |||
511 | // if menu specifies an encoding, create a convertor for it | ||
512 | l.rawgetfield(-1, "encoding"); { | ||
513 | if(l.isstring(-1)) | ||
514 | conv->setSource(l.tostring(-1)); | ||
515 | } l.pop(); | ||
516 | |||
517 | return createMenu_(l, screen_number, *conv, reloader); | ||
518 | } | ||
519 | |||
520 | |||
370 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { | 521 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { |
371 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | 522 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); |
372 | if (screen == 0) | 523 | if (screen == 0) |
diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh index a9fb649..6c537de 100644 --- a/src/MenuCreator.hh +++ b/src/MenuCreator.hh | |||
@@ -26,6 +26,11 @@ | |||
26 | #include "FbTk/FbString.hh" | 26 | #include "FbTk/FbString.hh" |
27 | 27 | ||
28 | #include <list> | 28 | #include <list> |
29 | #include <memory> | ||
30 | |||
31 | namespace lua { | ||
32 | class state; | ||
33 | } | ||
29 | 34 | ||
30 | namespace FbTk { | 35 | namespace FbTk { |
31 | class AutoReloadHelper; | 36 | class AutoReloadHelper; |
@@ -37,6 +42,8 @@ class FluxboxWindow; | |||
37 | 42 | ||
38 | class MenuCreator { | 43 | class MenuCreator { |
39 | public: | 44 | public: |
45 | static std::auto_ptr<FbMenu> | ||
46 | createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader = NULL); | ||
40 | static FbMenu *createMenu(const std::string &label, int screen_num); | 47 | static FbMenu *createMenu(const std::string &label, int screen_num); |
41 | static FbMenu *createMenuType(const std::string &label, int screen_num); | 48 | static FbMenu *createMenuType(const std::string &label, int screen_num); |
42 | static bool createFromFile(const std::string &filename, | 49 | static bool createFromFile(const std::string &filename, |
diff --git a/src/Screen.cc b/src/Screen.cc index 117cb29..f384476 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -1392,8 +1392,13 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, | |||
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | void BScreen::initMenus() { | 1394 | void BScreen::initMenus() { |
1395 | lua::state &l = Fluxbox::instance()->lua(); | ||
1395 | m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); | 1396 | m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); |
1396 | m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); | 1397 | l.loadfile(FbTk::StringUtil::expandFilename(Fluxbox::instance()->getMenuFilename()).c_str()); |
1398 | l.call(0, 0); | ||
1399 | l.getglobal("menu"); | ||
1400 | m_rootmenu = MenuCreator::createMenu(l, 0); | ||
1401 | // m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); | ||
1397 | m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); | 1402 | m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); |
1398 | } | 1403 | } |
1399 | 1404 | ||