Commit b7059d7f authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge pull request #114 from mruwek/color-todo-widgets

Use all configurable colors in TodoWidget
parents 62d2bbc5 35326e17
......@@ -14,18 +14,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections import namedtuple
import datetime
import shlex
import time
import urwid
from collections import namedtuple
from string import ascii_uppercase
from topydo.cli.CLIApplicationBase import CLIApplicationBase
from topydo.Commands import get_subcommand
from topydo.ui.CommandLineWidget import CommandLineWidget
from topydo.ui.ConsoleWidget import ConsoleWidget
from topydo.ui.KeystateWidget import KeystateWidget
from topydo.ui.TodoListWidget import TodoListWidget
from topydo.ui.TodoWidget import _to_urwid_color
from topydo.ui.ViewWidget import ViewWidget
from topydo.ui.ColumnLayout import columns
from topydo.lib.Config import config, ConfigError
......@@ -146,8 +149,13 @@ class UIApplication(CLIApplicationBase):
# the columns should have keyboard focus
self._blur_commandline()
self._screen = urwid.raw_display.Screen()
self._screen.register_palette(self._create_color_palette())
self._screen.set_terminal_properties(256)
self.mainloop = urwid.MainLoop(
self.mainwindow,
screen=self._screen,
unhandled_input=self._handle_input,
pop_ups=True
)
......@@ -155,6 +163,39 @@ class UIApplication(CLIApplicationBase):
self.column_mode = _APPEND_COLUMN
self._set_alarm_for_next_midnight_update()
def _create_color_palette(self):
project_color = _to_urwid_color(config().project_color())
context_color = _to_urwid_color(config().context_color())
metadata_color = _to_urwid_color(config().metadata_color())
link_color = _to_urwid_color(config().link_color())
palette = [
('project', '', '', '', project_color, ''),
('project_focus', '', 'light gray', '', project_color, None),
('context', '', '', '', context_color, ''),
('context_focus', '', 'light gray', '', context_color, None),
('metadata', '', '', '', metadata_color, ''),
('metadata_focus', '', 'light gray', '', metadata_color, None),
('link', '', '', '', link_color, ''),
('link_focus', '', 'light gray', '', link_color, None),
('default_focus', 'black', 'light gray'),
]
for C in ascii_uppercase:
pri_color_cfg = config().priority_color(C)
pri_color = _to_urwid_color(pri_color_cfg)
pri_color_focus = pri_color if not pri_color_cfg.is_neutral() else 'black'
palette.append((
'pri_' + C, '', '', '', pri_color, ''
))
palette.append((
'pri_' + C + '_focus', '', 'light gray', '', pri_color_focus, None
))
return palette
def _set_alarm_for_next_midnight_update(self):
def callback(p_loop, p_data):
self._update_all_columns()
......@@ -347,6 +388,7 @@ class UIApplication(CLIApplicationBase):
current_column.view = view
self._viewwidget_visible = False
self._blur_commandline()
def _add_column(self, p_view, p_pos=None):
"""
......
......@@ -14,16 +14,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib.Config import config
from topydo.lib.ListFormat import ListFormatParser
from topydo.lib.ProgressColor import progress_color
import urwid
import re
# pass a None todo list, since we won't use %i or %I here
PRIO_FORMATTER = ListFormatParser(None, "%{(}p{)}")
TEXT_FORMATTER = ListFormatParser(None, "%s %k\n%h")
PRJ_CON_PATTERN = r'\B(?:\+|@)(?:\S*\w)'
TAG_PATTERN = r'\b\S+:[^/\s]\S*\b'
URL_PATTERN = r'(?:^|\s)(?:\w+:){1}(?://\S+)'
def _to_urwid_color(p_color):
"""
Given a Color object, transform it to a color that urwid understands.
......@@ -41,16 +46,21 @@ def _markup(p_todo, p_focus):
Returns an attribute spec for the colors that correspond to the given todo
item.
"""
# retrieve the assigned value in the config file
fg_color = config().priority_color(p_todo.priority())
if p_focus and fg_color.is_neutral():
fg_color = 'black'
pri = p_todo.priority()
pri = 'pri_' + pri if pri else 'default'
if not p_focus:
attr_dict = {None: pri}
else:
fg_color = _to_urwid_color(fg_color)
# use '_focus' palette entries instead of standard ones
attr_dict = {None: pri + '_focus'}
attr_dict['project'] = 'project_focus'
attr_dict['context'] = 'context_focus'
attr_dict['metadata'] = 'metadata_focus'
attr_dict['link'] = 'link_focus'
bg_color = 'light gray' if p_focus else 'default'
return attr_dict
return urwid.AttrSpec(fg_color, bg_color, 256)
class TodoWidget(urwid.WidgetWrap):
def __init__(self, p_todo, p_number):
......@@ -60,9 +70,32 @@ class TodoWidget(urwid.WidgetWrap):
todo_text = TEXT_FORMATTER.parse(p_todo)
priority_text = PRIO_FORMATTER.parse(p_todo)
# split todo_text at each occurrence of tag/project/context/url
txt_pattern = r'|'.join([PRJ_CON_PATTERN, TAG_PATTERN, URL_PATTERN])
txt_pattern = r'(' + txt_pattern + r')'
txt_splitted = re.split(txt_pattern, todo_text)
txt_markup = []
# Examine each substring and apply relevant palette entry if needed
for substring in txt_splitted:
# re.split can generate empty strings when capturing group is used
if not substring:
continue
if re.match(TAG_PATTERN, substring):
txt_markup.append(('metadata', substring))
elif re.match(URL_PATTERN, substring):
txt_markup.append(('link', substring))
elif re.match(PRJ_CON_PATTERN, substring):
if substring.startswith('+'):
txt_markup.append(('project', substring))
else:
txt_markup.append(('context', substring))
else:
txt_markup.append(substring)
id_widget = urwid.Text(str(p_number), align='right')
priority_widget = urwid.Text(priority_text)
self.text_widget = urwid.Text(todo_text)
self.text_widget = urwid.Text(txt_markup)
progress = _to_urwid_color(progress_color(p_todo))
progress_bar = urwid.AttrMap(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment