diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-06-27 17:34:51 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2013-02-17 00:09:34 (GMT) |
commit | 22a26ba7cbf4242f69ce3ae36f8ac652ffac9390 (patch) | |
tree | 476f5b8b50492500682e9cfeeb32a7266bb48b19 | |
parent | 74532a72a511ae5243bca776c20797b328aa89eb (diff) | |
download | fluxbox_pavel-22a26ba7cbf4242f69ce3ae36f8ac652ffac9390.zip fluxbox_pavel-22a26ba7cbf4242f69ce3ae36f8ac652ffac9390.tar.bz2 |
A veeeery rough implementation of lua menu parsers
-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 | 15 | ||||
-rw-r--r-- | src/Screen.cc | 7 |
6 files changed, 172 insertions, 9 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index 3632fc9..dfba1d0 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 41dcf73..b944bcb 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc | |||
@@ -433,8 +433,159 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc | |||
433 | return true; | 433 | return true; |
434 | } | 434 | } |
435 | 435 | ||
436 | string getField(lua::state &l, int pos, const char *field, FbTk::StringConvertor *conv = NULL) { | ||
437 | lua::stack_sentry s(l); | ||
438 | l.checkstack(1); | ||
439 | _FB_USES_NLS; | ||
440 | |||
441 | string val; | ||
442 | l.rawgetfield(pos, field); { | ||
443 | if(l.isstring(-1)) | ||
444 | val = l.tostring(-1); | ||
445 | else if(! l.isnil(-1)) { | ||
446 | fprintf(stderr, _FB_CONSOLETEXT(Menu, FieldNotString, | ||
447 | "Warning: Menu field %s is not a string", "One %s for field name.").c_str(), | ||
448 | field); | ||
449 | fputs("\n", stderr); | ||
450 | } | ||
451 | } l.pop(); | ||
452 | return conv ? conv->recode(val) : val; | ||
453 | } | ||
454 | |||
455 | std::auto_ptr<FbMenu> | ||
456 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
457 | FbTk::AutoReloadHelper *reloader); | ||
458 | |||
459 | void | ||
460 | insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | ||
461 | FbTk::AutoReloadHelper *reloader) { | ||
462 | lua::stack_sentry s(l, -1); | ||
463 | l.checkstack(1); | ||
464 | |||
465 | if(l.type(-1) != lua::TTABLE) | ||
466 | throw std::runtime_error(_FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", "Menu is not a lua table")); | ||
467 | |||
468 | // if menu specifies an encoding, create a convertor for it | ||
469 | std::auto_ptr<FbTk::StringConvertor> my_conv; | ||
470 | |||
471 | FbTk::StringConvertor *conv = &parent_conv; | ||
472 | const string &encoding = getField(l, -1, "encoding"); | ||
473 | if(! encoding.empty()) { | ||
474 | my_conv.reset(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
475 | conv = my_conv.get(); | ||
476 | conv->setSource(encoding); | ||
477 | } | ||
478 | |||
479 | const string &str_label = getField(l, -1, "label", conv); | ||
480 | const string &str_key = getField(l, -1, "type"); | ||
481 | const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance(); | ||
482 | BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); | ||
483 | size_t old_size = menu.numberOfItems(); | ||
484 | |||
485 | // first items that don't need additional parameters | ||
486 | if(str_key == "separator") | ||
487 | menu.insert(new FbTk::MenuSeparator()); | ||
488 | else if(str_key == "nop") { | ||
489 | int size = menu.insert(str_label); | ||
490 | menu.setItemEnabled(size-1, false); | ||
491 | } else if(str_key == "icons") { | ||
492 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber()); | ||
493 | if (submenu == 0) | ||
494 | return; | ||
495 | if (str_label.empty()) | ||
496 | menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu); | ||
497 | else | ||
498 | menu.insert(str_label, submenu); | ||
499 | } else if (str_key == "exit") { // exit | ||
500 | FbTk::RefCount<FbTk::Command<void> > exit_cmd(FbTk::CommandParser<void>::instance().parse("exit")); | ||
501 | if (str_label.empty()) | ||
502 | menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd); | ||
503 | else | ||
504 | menu.insert(str_label, exit_cmd); | ||
505 | } else if (str_key == "config") { | ||
506 | menu.insert(str_label, &screen->configMenu()); | ||
507 | } else if(str_key == "menu") { | ||
508 | l.pushvalue(-1); | ||
509 | menu.insert(str_label, createMenu_(l, menu.screenNumber(), *conv, reloader).release()); | ||
510 | } else { | ||
511 | // items that have a parameter | ||
512 | const string &str_cmd = getField(l, -1, "param"); | ||
513 | |||
514 | if(str_key == "command") { | ||
515 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
516 | parser.parse(str_cmd)) ); | ||
517 | } else if(str_key == "exec") { | ||
518 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
519 | parser.parse("exec", str_cmd)) ); | ||
520 | } else if(str_key == "style") | ||
521 | menu.insert(new StyleMenuItem(str_label, str_cmd)); | ||
522 | else if (str_key == "stylesdir") | ||
523 | createStyleMenu(menu, str_label, reloader, str_cmd); | ||
524 | else if (str_key == "wallpapers") { | ||
525 | const string &program = getField(l, -1, "program"); | ||
526 | createRootCmdMenu(menu, str_label, str_cmd, reloader, | ||
527 | program.empty() ? realProgramName("fbsetbg") : program); | ||
528 | } else if (str_key == "workspaces") { | ||
529 | /* screen->workspaceMenu().setInternalMenu(); | ||
530 | menu.insert(str_label, &screen->workspaceMenu());*/ | ||
531 | } | ||
532 | } | ||
533 | |||
534 | const string &icon = getField(l, -1, "icon"); | ||
535 | if(! icon.empty()) { | ||
536 | while(old_size < menu.numberOfItems()) | ||
537 | menu.find(old_size++)->setIcon(icon, menu.screenNumber()); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | std::auto_ptr<FbMenu> | ||
542 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
543 | FbTk::AutoReloadHelper *reloader) { | ||
544 | |||
545 | lua::stack_sentry s(l, -1); | ||
546 | l.checkstack(1); | ||
547 | |||
548 | std::auto_ptr<FbMenu> menu( MenuCreator::createMenu(getField(l, -1, "label", &conv), | ||
549 | screen_number) ); | ||
550 | |||
551 | for(int i = 1; l.rawgeti(-1, i), !l.isnil(-1); ++i) { | ||
552 | try { | ||
553 | insertMenuItem(l, *menu, conv, reloader); | ||
554 | } | ||
555 | catch(std::runtime_error &e) { | ||
556 | cerr << e.what() << endl; | ||
557 | } | ||
558 | } l.pop(); | ||
559 | |||
560 | l.pop(); | ||
561 | return menu; | ||
562 | } | ||
563 | |||
436 | } // end of anonymous namespace | 564 | } // end of anonymous namespace |
437 | 565 | ||
566 | std::auto_ptr<FbMenu> | ||
567 | MenuCreator::createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader) { | ||
568 | lua::stack_sentry s(l, -1); | ||
569 | l.checkstack(1); | ||
570 | |||
571 | if(l.type(-1) != lua::TTABLE) { | ||
572 | cerr << _FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", | ||
573 | "Menu is not a lua table") << endl; | ||
574 | return std::auto_ptr<FbMenu>(); | ||
575 | } | ||
576 | |||
577 | std::auto_ptr<FbTk::StringConvertor> conv(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
578 | |||
579 | // if menu specifies an encoding, create a convertor for it | ||
580 | l.rawgetfield(-1, "encoding"); { | ||
581 | if(l.isstring(-1)) | ||
582 | conv->setSource(l.tostring(-1)); | ||
583 | } l.pop(); | ||
584 | |||
585 | return createMenu_(l, screen_number, *conv, reloader); | ||
586 | } | ||
587 | |||
588 | |||
438 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { | 589 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { |
439 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | 590 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); |
440 | if (screen == 0) | 591 | if (screen == 0) |
diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh index 91add47..4329639 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,14 +42,16 @@ class FluxboxWindow; | |||
37 | 42 | ||
38 | namespace MenuCreator { | 43 | namespace MenuCreator { |
39 | 44 | ||
45 | std::auto_ptr<FbMenu> | ||
46 | createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader = NULL); | ||
40 | FbMenu *createMenu(const std::string &label, int screen_num); | 47 | FbMenu *createMenu(const std::string &label, int screen_num); |
41 | FbMenu *createMenuType(const std::string &label, int screen_num); | 48 | FbMenu *createMenuType(const std::string &label, int screen_num); |
42 | bool createFromFile(const std::string &filename, | 49 | bool createFromFile(const std::string &filename, |
43 | FbTk::Menu &inject_into, | 50 | FbTk::Menu &inject_into, |
44 | FbTk::AutoReloadHelper *reloader = NULL, | 51 | FbTk::AutoReloadHelper *reloader = NULL, |
45 | bool begin = true); | 52 | bool begin = true); |
46 | bool createWindowMenuItem(const std::string &type, const std::string &label, | 53 | bool createWindowMenuItem(const std::string &type, const std::string &label, |
47 | FbTk::Menu &inject_into); | 54 | FbTk::Menu &inject_into); |
48 | }; | 55 | } |
49 | 56 | ||
50 | #endif // MENUCREATOR_HH | 57 | #endif // MENUCREATOR_HH |
diff --git a/src/Screen.cc b/src/Screen.cc index 6ddc74c..51fb165 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -1403,8 +1403,13 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, | |||
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | void BScreen::initMenus() { | 1405 | void BScreen::initMenus() { |
1406 | lua::state &l = Fluxbox::instance()->lua(); | ||
1406 | m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); | 1407 | m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); |
1407 | m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); | 1408 | l.loadfile(FbTk::StringUtil::expandFilename(Fluxbox::instance()->getMenuFilename()).c_str()); |
1409 | l.call(0, 0); | ||
1410 | l.getglobal("menu"); | ||
1411 | m_rootmenu = MenuCreator::createMenu(l, 0); | ||
1412 | // m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); | ||
1408 | m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); | 1413 | m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); |
1409 | } | 1414 | } |
1410 | 1415 | ||