Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: ToDo widget text highlighting #2452

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

Expand All @@ -10,8 +16,10 @@
import net.gsantner.markor.format.todotxt.TodoTxtTask;
import net.gsantner.markor.model.AppSettings;
import net.gsantner.markor.model.Document;
import net.gsantner.opoc.util.GsContextUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class TodoWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
Expand Down Expand Up @@ -57,8 +65,8 @@ public int getCount() {
@Override
public RemoteViews getViewAt(int position) {
RemoteViews views = new RemoteViews(_context.getPackageName(), R.layout.todo_widget_list_item);
views.setTextViewText(R.id.todo_widget_item_text, _tasks.get(position).getDescription());
views.setInt(R.id.todo_widget_item_text, "setTextColor", _appSettings.getEditorForegroundColor());

views.setTextViewText(R.id.todo_widget_item_text, getTaskSpannable(_tasks.get(position)));

final Intent fillInIntent = new Intent()
.putExtra(Document.EXTRA_FILE_LINE_NUMBER, position);
Expand Down Expand Up @@ -86,4 +94,84 @@ public long getItemId(int position) {
public boolean hasStableIds() {
return false;
}

private Spannable getTaskSpannable(TodoTxtTask task) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This static function will return a highlighter callable which can apply todotxt highlighting to a spannable.

https://github.com/gsantner/markor/blob/master/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java#L758

So simply

final GsCallback.a1<Spannable> hl = getSttHighlighter();
for (Spannable s : lines) {
    hl.callback(s)
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will highlight every line in lines

You will need to make getSttHighlighter public and move it somewhere appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final GsCallback.a1<Spannable> hl = getSttHighlighter();
Spannable s = new SpannableString(_tasks.get(position).getLine());
hl.callback(s);
views.setTextViewText(R.id.todo_widget_item_text, s);

I couldn't make it work. What is wrong here?

It's also very important to remove creation dates, priority parentheses, etc. as they take up valuable space especially on narrower screens. How would that be achieved?,

SpannableStringBuilder spannable = new SpannableStringBuilder();
int currentPos = 0;
final char priority = task.getPriority();
final String dueDate = task.getDueDate();
final String description = task.getDescription();
final boolean isDone = task.isDone();

if (priority != TodoTxtTask.PRIORITY_NONE) {
spannable.append(String.valueOf(priority));
spannable.setSpan(new ForegroundColorSpan(getColorFromPriority(priority)), currentPos, ++currentPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, currentPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (!dueDate.isEmpty()) {
currentPos = addSpaceIfNecessary(currentPos, spannable);
String displayDueDate = Calendar.getInstance().get(Calendar.YEAR) == Integer.parseInt(dueDate.substring(0, 4))
? dueDate.substring(5) : dueDate;
spannable.append(displayDueDate);
spannable.setSpan(new ForegroundColorSpan(0xffEF2929), currentPos, currentPos += displayDueDate.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new StyleSpan(Typeface.ITALIC), currentPos - displayDueDate.length(), currentPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (!description.isEmpty()) {
currentPos = addSpaceIfNecessary(currentPos, spannable);
spannable.append(description);
spannable.setSpan(new ForegroundColorSpan(_appSettings.getEditorForegroundColor()), currentPos, currentPos += description.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
currentPos = appendTags(spannable, task.getProjects(), '+', 0xffef6C00, currentPos);
currentPos = appendTags(spannable, task.getContexts(), '@', 0xff88b04b, currentPos);
if(isDone){
spannable.setSpan(new ForegroundColorSpan(GsContextUtils.instance.isDarkModeEnabled(_appSettings.getContext()) ? 0x999d9d9d : 0x993d3d3d), 0, currentPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new StrikethroughSpan(), 0, currentPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

return spannable;
}

private static int addSpaceIfNecessary(int currentPos, SpannableStringBuilder spannable) {
if (currentPos > 0) {
spannable.append(" ");
currentPos++;
}
return currentPos;
}

private int appendTags(SpannableStringBuilder spannable, List<String> tags, char prefix, int color, int currentPos) {
for (String tag : tags) {
currentPos = addSpaceIfNecessary(currentPos, spannable);
spannable.append(prefix).append(tag);
spannable.setSpan(new ForegroundColorSpan(color), currentPos, currentPos += tag.length() + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return currentPos;
}

private int getColorFromPriority(char priority) {
final int COLOR_PRIORITY_A = 0xffEF2929;
final int COLOR_PRIORITY_B = 0xffd16900;
final int COLOR_PRIORITY_C = 0xff59a112;
final int COLOR_PRIORITY_D = 0xff0091c2;
final int COLOR_PRIORITY_E = 0xffa952cb;
final int COLOR_PRIORITY_F = 0xff878986;

switch (priority)
{
case 'A':
return COLOR_PRIORITY_A;
case 'B':
return COLOR_PRIORITY_B;
case 'C':
return COLOR_PRIORITY_C;
case 'D':
return COLOR_PRIORITY_D;
case 'E':
return COLOR_PRIORITY_E;
case 'F':
return COLOR_PRIORITY_F;
default:
return _appSettings.getEditorForegroundColor();
}
}
}
Loading