synced with r21612
[mplayer/greg.git] / libmenu / menu_txt.c
blob2fb79fcec704cb9e8c50cf4c5cdc90460516fc26
2 #include "config.h"
3 #include "mp_msg.h"
4 #include "help_mp.h"
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
10 #include "libmpcodecs/img_format.h"
11 #include "libmpcodecs/mp_image.h"
13 #include "m_struct.h"
14 #include "m_option.h"
15 #include "menu.h"
17 #include "libvo/font_load.h"
18 #include "osdep/keycodes.h"
20 struct menu_priv_s {
21 char** lines;
22 int num_lines;
23 int cur_line;
24 int disp_lines;
25 int minb;
26 int hspace;
27 char* file;
30 static struct menu_priv_s cfg_dflt = {
31 NULL,
37 NULL
40 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
42 static m_option_t cfg_fields[] = {
43 { "minbor", ST_OFF(minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
44 { "hspace", ST_OFF(hspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
45 { "file", ST_OFF(file), CONF_TYPE_STRING, 0, 0, 0, NULL },
46 { NULL, NULL, NULL, 0,0,0,NULL }
49 #define mpriv (menu->priv)
51 static void read_cmd(menu_t* menu,int cmd) {
52 switch(cmd) {
53 case MENU_CMD_UP:
54 mpriv->cur_line -= mpriv->disp_lines / 2;
55 if(mpriv->cur_line < 0)
56 mpriv->cur_line = 0;
57 break;
58 case MENU_CMD_DOWN:
59 case MENU_CMD_OK:
60 mpriv->cur_line += mpriv->disp_lines / 2;
61 if(mpriv->cur_line >= mpriv->num_lines)
62 mpriv->cur_line = mpriv->num_lines - 1;
63 break;
64 case MENU_CMD_CANCEL:
65 menu->show = 0;
66 menu->cl = 1;
67 break;
71 static void read_key(menu_t* menu,int c) {
72 switch (c) {
73 case KEY_HOME:
74 mpriv->cur_line = 0;
75 break;
76 case KEY_END:
77 mpriv->cur_line = mpriv->num_lines - 1;
78 break;
79 case KEY_PAGE_UP:
80 mpriv->cur_line = mpriv->cur_line > mpriv->disp_lines ?
81 mpriv->cur_line - mpriv->disp_lines : 0;
82 break;
83 case KEY_PAGE_DOWN:
84 mpriv->cur_line = mpriv->cur_line + mpriv->disp_lines > mpriv->num_lines - 1 ? mpriv->num_lines - 1 : mpriv->cur_line + mpriv->disp_lines;
85 break;
86 default:
87 menu_dflt_read_key(menu,c);
92 static void draw(menu_t* menu,mp_image_t* mpi) {
93 int x = mpriv->minb;
94 int y = mpriv->minb;
95 //int th = 2*mpriv->hspace + vo_font->height;
96 int i,end;
98 if(x < 0) x = 8;
99 if(y < 0) y = 8;
101 mpriv->disp_lines = (mpi->h + mpriv->hspace - 2*mpriv->minb) / ( vo_font->height + mpriv->hspace);
102 if(mpriv->num_lines - mpriv->cur_line < mpriv->disp_lines) {
103 i = mpriv->num_lines - 1 - mpriv->disp_lines;
104 if(i < 0) i = 0;
105 end = mpriv->num_lines - 1;
106 } else {
107 i = mpriv->cur_line;
108 end = i + mpriv->disp_lines;
109 if(end >= mpriv->num_lines) end = mpriv->num_lines - 1;
112 for( ; i < end ; i++) {
113 menu_draw_text(mpi,mpriv->lines[i],x,y);
114 y += vo_font->height + mpriv->hspace;
119 #define BUF_SIZE 1024
121 static int open(menu_t* menu, char* args) {
122 FILE* fd;
123 char buf[BUF_SIZE];
124 char *l;
125 int s;
126 int pos = 0, r = 0;
127 args = NULL; // Warning kill
129 menu->draw = draw;
130 menu->read_cmd = read_cmd;
131 menu->read_key = read_key;
133 if(!mpriv->file) {
134 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuTxtNeedATxtFileName);
135 return 0;
138 fd = fopen(mpriv->file,"r");
139 if(!fd) {
140 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuTxtCantOpen,mpriv->file);
141 return 0;
144 while(1) {
145 r = fread(buf+pos,1,BUF_SIZE-pos-1,fd);
146 if(r <= 0) {
147 if(pos > 0) {
148 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
149 mpriv->lines[mpriv->num_lines] = strdup(buf);
150 mpriv->num_lines++;
152 fclose(fd);
153 break;
155 pos += r;
156 buf[pos] = '\0';
158 while((l = strchr(buf,'\n')) != NULL) {
159 s = l-buf;
160 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
161 mpriv->lines[mpriv->num_lines] = malloc(s+1);
162 memcpy(mpriv->lines[mpriv->num_lines],buf,s);
163 mpriv->lines[mpriv->num_lines][s] = '\0';
164 pos -= s + 1;
165 if(pos > 0)
166 memmove(buf,l+1,pos);
167 buf[pos] = '\0';
168 mpriv->num_lines++;
170 if(pos >= BUF_SIZE-1) {
171 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_WarningTooLongLineSplitting);
172 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
173 mpriv->lines[mpriv->num_lines] = strdup(buf);
174 mpriv->num_lines++;
175 pos = 0;
179 mp_msg(MSGT_GLOBAL,MSGL_INFO,MSGTR_LIBMENU_ParsedLines,mpriv->num_lines);
181 return 1;
184 const menu_info_t menu_info_txt = {
185 "Text file viewer",
186 "txt",
187 "Albeu",
190 "txt_cfg",
191 sizeof(struct menu_priv_s),
192 &cfg_dflt,
193 cfg_fields
195 open,