Skip to content

Instantly share code, notes, and snippets.

@XayOn
Created September 22, 2013 04:26
Show Gist options
  • Save XayOn/6656708 to your computer and use it in GitHub Desktop.
Save XayOn/6656708 to your computer and use it in GitHub Desktop.
Using some python magic, the URWID example for multiple menus, and the XDG library, I present you here a simplish-as-it-can-get ncurses application menu for all TUI lovers over the world.
import urwid
import os
from xdg import DesktopEntry
def read_menus():
"""
Read the menus and return them in an array
"""
all_menus = []
result = {}
for menu_entry_file in os.listdir("/usr/share/applications"):
if menu_entry_file.endswith('.desktop'):
all_menus.append(DesktopEntry.DesktopEntry(
"/usr/share/applications/"+menu_entry_file
))
for category, ele in [[l.getCategories()[0], l] for l in all_menus if len(l.getCategories()) > 0]:
if not category in result: result[category] = []
result[category].append(ele)
return result
def menu_button(caption, program, callback):
button = urwid.Button(caption)
urwid.connect_signal(button, 'click', callback, program)
return urwid.AttrMap(button, None, focus_map='reversed')
def sub_menu(caption, choices):
contents = menu(caption, choices)
def open_menu(button, foo=False):
return top.open_box(contents)
return menu_button([caption, u'...'], False, open_menu)
def menu(title, choices):
body = [urwid.Text(title), urwid.Divider()]
body.extend(choices)
return urwid.ListBox(urwid.SimpleFocusListWalker(body))
def item_chosen(button, program):
os.system(program)
def exit_program(button):
raise urwid.ExitMainLoop()
class CascadingBoxes(urwid.WidgetPlaceholder):
max_box_levels = 4
def __init__(self, box):
super(CascadingBoxes, self).__init__(urwid.SolidFill(u'/'))
self.box_level = 0
self.open_box(box)
def open_box(self, box):
self.original_widget = urwid.Overlay(urwid.LineBox(box),
self.original_widget,
align='center', width=('relative', 80),
valign='middle', height=('relative', 80),
min_width=24, min_height=8,
left=self.box_level * 3,
right=(self.max_box_levels - self.box_level - 1) * 3,
top=self.box_level * 2,
bottom=(self.max_box_levels - self.box_level - 1) * 2)
self.box_level += 1
def keypress(self, size, key):
if key == 'esc' and self.box_level > 1:
self.original_widget = self.original_widget[0]
self.box_level -= 1
else:
return super(CascadingBoxes, self).keypress(size, key)
allmenus = read_menus()
menu_top = menu('Main menu', [sub_menu(menu_category, [menu_button(item.getName(), item.getExec(), item_chosen) for item in allmenus[menu_category] ]) for menu_category in allmenus.keys()])
top = CascadingBoxes(menu_top)
urwid.MainLoop(top, palette=[('reversed', 'standout', '')]).run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment