Skip to content

Commit

Permalink
Merge branch 'resizable-context-menus' of https://github.com/albel727…
Browse files Browse the repository at this point in the history
…/uTox

#
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
  • Loading branch information
irungentoo committed Sep 22, 2014
2 parents d53382d + 5383f05 commit 7982db1
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 23 deletions.
60 changes: 50 additions & 10 deletions contextmenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,51 @@ static CONTEXTMENU context_menu;
#define CONTEXT_WIDTH (SCALE * 60)
#define CONTEXT_HEIGHT (SCALE * 12)

static void calculate_pos_and_width(CONTEXTMENU *b, int *x, int *w) {
uint8_t i;

*x = b->x;
*w = b->width;

// Increase width if needed, so that all menu items fit.
for(i = 0; i < b->count; i++) {
STRING *name = b->ondisplay(i, b);
int needed_w = textwidth(name->str, name->length) + 4 * SCALE;
if(*w < needed_w) {
*w = needed_w;
}
}

// Push away from the right border to fit.
if(*x + *w >= width) {
*x -= *w;
}
}

void contextmenu_draw(void)
{
CONTEXTMENU *b = &context_menu;
if(!b->open) {
return;
}

// Ensure that font is set before calculating position and width.
setfont(FONT_TEXT);
setcolor(COLOR_TEXT);

drawrectw(b->x, b->y, b->width, b->height, WHITE);
drawrectw(b->x, b->y + b->over * CONTEXT_HEIGHT, b->width, CONTEXT_HEIGHT, C_GRAY);
int x, w;
calculate_pos_and_width(b, &x, &w);

drawrectw(x, b->y, w, b->height, WHITE);
drawrectw(x, b->y + b->over * CONTEXT_HEIGHT, w, CONTEXT_HEIGHT, C_GRAY);

int i;
for(i = 0; i != b->count; i++) {
drawtext(b->x + SCALE * 2, b->y + SCALE * 2 + i * CONTEXT_HEIGHT, b->names[i], strlen((char*)b->names[i]));
STRING *name = b->ondisplay(i, b);
drawtext(x + SCALE * 2, b->y + SCALE * 2 + i * CONTEXT_HEIGHT, name->str, name->length);
}

framerect(b->x, b->y, b->x + b->width, b->y + b->height, BLUE);
framerect(x, b->y, x + w, b->y + b->height, BLUE);
}

_Bool contextmenu_mmove(int mx, int my, int UNUSED(dx), int UNUSED(dy))
Expand All @@ -36,7 +62,14 @@ _Bool contextmenu_mmove(int mx, int my, int UNUSED(dx), int UNUSED(dy))

cursor = CURSOR_NONE;

_Bool mouseover = inrect(mx, my, b->x, b->y, b->width, b->height);
// Ensure that font is set before calculating position and width.
setfont(FONT_TEXT);
setcolor(COLOR_TEXT);

int x, w;
calculate_pos_and_width(b, &x, &w);

_Bool mouseover = inrect(mx, my, x, b->y, w, b->height);
if(!mouseover) {
if(b->over != 0xFF) {
b->over = 0xFF;
Expand Down Expand Up @@ -107,7 +140,7 @@ _Bool contextmenu_mleave(void)
return 0;
}

void contextmenu_new(uint8_t **names, uint8_t count, void (*onselect)(uint8_t))
void contextmenu_new_ex(uint8_t count, void *userdata, void (*onselect)(uint8_t), STRING* (*ondisplay)(uint8_t, const CONTEXTMENU*))
{
CONTEXTMENU *b = &context_menu;

Expand All @@ -118,13 +151,20 @@ void contextmenu_new(uint8_t **names, uint8_t count, void (*onselect)(uint8_t))
}
b->x = mouse.x;
b->width = CONTEXT_WIDTH;
if(b->x + b->width >= width) {
b->x -= b->width;
}

b->open = 1;
b->count = count;
b->over = 0xFF;
b->onselect = onselect;
memcpy(b->names, names, sizeof(uint8_t*) * count);
b->ondisplay = ondisplay;
b->userdata = userdata;
}

static STRING* contextmenu_localized_ondisplay(uint8_t i, const CONTEXTMENU* cm)
{
return SPTRFORLANG(LANG, ((UI_STRING_ID*) cm->userdata)[i]);
}

void contextmenu_new(uint8_t count, UI_STRING_ID* menu_string_ids, void (*onselect)(uint8_t)) {
contextmenu_new_ex(count, menu_string_ids, onselect, contextmenu_localized_ondisplay);
}
8 changes: 5 additions & 3 deletions contextmenu.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

typedef struct {
typedef struct contextmenu {
int x, y, width, height;
_Bool open;
uint8_t count, over, down;
void (*onselect)(uint8_t);
uint8_t *names[8];
STRING* (*ondisplay)(uint8_t, const struct contextmenu*);
void *userdata;
} CONTEXTMENU;

void contextmenu_draw(void);
Expand All @@ -13,4 +14,5 @@ _Bool contextmenu_mdown(void);
_Bool contextmenu_mup(void);
_Bool contextmenu_mleave(void);

void contextmenu_new(uint8_t **names, uint8_t count, void (*onselect)(uint8_t));
void contextmenu_new(uint8_t count, UI_STRING_ID* menu_string_ids, void (*onselect)(uint8_t));
void contextmenu_new_ex(uint8_t count, void *userdata, void (*onselect)(uint8_t), STRING* (*ondisplay)(uint8_t, const CONTEXTMENU*));
4 changes: 2 additions & 2 deletions edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static void contextmenu_edit_onselect(uint8_t i)

_Bool edit_mright(EDIT *edit)
{
static UI_STRING_ID menu_edit[] = {STR_CUT, STR_COPY, STR_PASTE, STR_DELETE, STR_SELECTALL};
if(edit->mouseover_char > edit->length) {
edit->mouseover_char = edit->length;
}
Expand All @@ -212,8 +213,7 @@ _Bool edit_mright(EDIT *edit)
edit_select = 1;
}

uint8_t *names[] = {S(CUT), S(COPY), S(PASTE), S(DELETE), S(SELECTALL)};
contextmenu_new(names, 5, contextmenu_edit_onselect);
contextmenu_new(countof(menu_edit), menu_edit, contextmenu_edit_onselect);

return 1;
}
Expand Down
13 changes: 7 additions & 6 deletions list.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,17 +499,18 @@ static void contextmenu_list_onselect(uint8_t i)

_Bool list_mright(void *UNUSED(n))
{
static UI_STRING_ID menu_friend[] = {STR_REMOVE_FRIEND};
static UI_STRING_ID menu_group[] = {STR_REMOVE_GROUP};
static UI_STRING_ID menu_request[] = {STR_REQ_ACCEPT, STR_REQ_DECLINE};

if(mitem) {
ritem = mitem;
if(mitem->item == ITEM_FRIEND) {
uint8_t *remove = (uint8_t*)"Remove";
contextmenu_new(&remove, 1, contextmenu_list_onselect);
contextmenu_new(countof(menu_friend), menu_friend, contextmenu_list_onselect);
} else if(mitem->item == ITEM_GROUP) {
uint8_t *leave = (uint8_t*)"Leave";
contextmenu_new(&leave, 1, contextmenu_list_onselect);
contextmenu_new(countof(menu_group), menu_group, contextmenu_list_onselect);
} else {
uint8_t *names[] = {(uint8_t*)"Accept", (uint8_t*)"Ignore"};
contextmenu_new(names, 2, contextmenu_list_onselect);
contextmenu_new(countof(menu_request), menu_request, contextmenu_list_onselect);
}
return 1;
//listpopup(mitem->item);
Expand Down
4 changes: 2 additions & 2 deletions messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,9 +596,9 @@ static void contextmenu_messages_onselect(uint8_t i)

_Bool messages_mright(MESSAGES *m)
{
static UI_STRING_ID menu_copy[] = {STR_COPY, STR_COPYWITHOUTNAMES};
if(m->iover != ~0 && ((MESSAGE*)m->data->data[m->iover])->flags <= 3) {
uint8_t *names[] = {S(COPY), S(COPYWITHOUTNAMES)};
contextmenu_new(names, 2, contextmenu_messages_onselect);
contextmenu_new(countof(menu_copy), menu_copy, contextmenu_messages_onselect);
return 1;
}
return 0;
Expand Down
6 changes: 6 additions & 0 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,17 @@ enum {
STR_PASTE,
STR_DELETE,
STR_SELECTALL,

STR_REMOVE,
STR_LEAVE,
STR_ACCEPT,
STR_IGNORE,

STR_REMOVE_FRIEND = STR_REMOVE,
STR_REMOVE_GROUP = STR_LEAVE,
STR_REQ_ACCEPT = STR_ACCEPT,
STR_REQ_DECLINE = STR_IGNORE,

STR_CLICKTOSAVE,
STR_CLICKTOOPEN,
STR_CANCELLED,
Expand Down

0 comments on commit 7982db1

Please sign in to comment.