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 @@ ...@@ -14,18 +14,21 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections import namedtuple
import datetime import datetime
import shlex import shlex
import time import time
import urwid import urwid
from collections import namedtuple
from string import ascii_uppercase
from topydo.cli.CLIApplicationBase import CLIApplicationBase from topydo.cli.CLIApplicationBase import CLIApplicationBase
from topydo.Commands import get_subcommand from topydo.Commands import get_subcommand
from topydo.ui.CommandLineWidget import CommandLineWidget from topydo.ui.CommandLineWidget import CommandLineWidget
from topydo.ui.ConsoleWidget import ConsoleWidget from topydo.ui.ConsoleWidget import ConsoleWidget
from topydo.ui.KeystateWidget import KeystateWidget from topydo.ui.KeystateWidget import KeystateWidget
from topydo.ui.TodoListWidget import TodoListWidget from topydo.ui.TodoListWidget import TodoListWidget
from topydo.ui.TodoWidget import _to_urwid_color
from topydo.ui.ViewWidget import ViewWidget from topydo.ui.ViewWidget import ViewWidget
from topydo.ui.ColumnLayout import columns from topydo.ui.ColumnLayout import columns
from topydo.lib.Config import config, ConfigError from topydo.lib.Config import config, ConfigError
...@@ -146,8 +149,13 @@ class UIApplication(CLIApplicationBase): ...@@ -146,8 +149,13 @@ class UIApplication(CLIApplicationBase):
# the columns should have keyboard focus # the columns should have keyboard focus
self._blur_commandline() 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.mainloop = urwid.MainLoop(
self.mainwindow, self.mainwindow,
screen=self._screen,
unhandled_input=self._handle_input, unhandled_input=self._handle_input,
pop_ups=True pop_ups=True
) )
...@@ -155,6 +163,39 @@ class UIApplication(CLIApplicationBase): ...@@ -155,6 +163,39 @@ class UIApplication(CLIApplicationBase):
self.column_mode = _APPEND_COLUMN self.column_mode = _APPEND_COLUMN
self._set_alarm_for_next_midnight_update() 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 _set_alarm_for_next_midnight_update(self):
def callback(p_loop, p_data): def callback(p_loop, p_data):
self._update_all_columns() self._update_all_columns()
...@@ -347,6 +388,7 @@ class UIApplication(CLIApplicationBase): ...@@ -347,6 +388,7 @@ class UIApplication(CLIApplicationBase):
current_column.view = view current_column.view = view
self._viewwidget_visible = False self._viewwidget_visible = False
self._blur_commandline()
def _add_column(self, p_view, p_pos=None): def _add_column(self, p_view, p_pos=None):
""" """
......
...@@ -14,16 +14,21 @@ ...@@ -14,16 +14,21 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # 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.ListFormat import ListFormatParser
from topydo.lib.ProgressColor import progress_color from topydo.lib.ProgressColor import progress_color
import urwid import urwid
import re
# pass a None todo list, since we won't use %i or %I here # pass a None todo list, since we won't use %i or %I here
PRIO_FORMATTER = ListFormatParser(None, "%{(}p{)}") PRIO_FORMATTER = ListFormatParser(None, "%{(}p{)}")
TEXT_FORMATTER = ListFormatParser(None, "%s %k\n%h") 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): def _to_urwid_color(p_color):
""" """
Given a Color object, transform it to a color that urwid understands. Given a Color object, transform it to a color that urwid understands.
...@@ -41,16 +46,21 @@ def _markup(p_todo, p_focus): ...@@ -41,16 +46,21 @@ def _markup(p_todo, p_focus):
Returns an attribute spec for the colors that correspond to the given todo Returns an attribute spec for the colors that correspond to the given todo
item. item.
""" """
# retrieve the assigned value in the config file pri = p_todo.priority()
fg_color = config().priority_color(p_todo.priority()) pri = 'pri_' + pri if pri else 'default'
if p_focus and fg_color.is_neutral():
fg_color = 'black' if not p_focus:
attr_dict = {None: pri}
else: 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): class TodoWidget(urwid.WidgetWrap):
def __init__(self, p_todo, p_number): def __init__(self, p_todo, p_number):
...@@ -60,9 +70,32 @@ class TodoWidget(urwid.WidgetWrap): ...@@ -60,9 +70,32 @@ class TodoWidget(urwid.WidgetWrap):
todo_text = TEXT_FORMATTER.parse(p_todo) todo_text = TEXT_FORMATTER.parse(p_todo)
priority_text = PRIO_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') id_widget = urwid.Text(str(p_number), align='right')
priority_widget = urwid.Text(priority_text) 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 = _to_urwid_color(progress_color(p_todo))
progress_bar = urwid.AttrMap( 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