smenu.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <cursor.h>
  6. #include <mouse.h>
  7. #include <keyboard.h>
  8. #include <frame.h>
  9. #include <fcall.h>
  10. #include <jay.h>
  11. #include "dat.h"
  12. #include "fns.h"
  13. static void
  14. addEntry(StartMenu *sm, char *name, char *action, StartMenu *submenu, Point p){
  15. if (name == nil)
  16. return;
  17. MenuEntry *e = sm->entries[sm->numEntries] = malloc(sizeof(MenuEntry));
  18. sm->numEntries++;
  19. e->name = estrdup(name);
  20. if (action != nil)
  21. e->action = estrdup(action);
  22. else
  23. e->action = nil;
  24. e->submenu = submenu;
  25. Point ssize = stringsize(font, e->name);
  26. Rectangle r = Rect(p.x, p.y, p.x + ssize.x + 2*Borderwidth, p.y + 2*Borderwidth + ssize.y);
  27. e->i = allocimage(display, r, CMAP8, 1, jayconfig->mainMenuColor);
  28. e->ih = allocimage(display, r, CMAP8, 1, jayconfig->mainMenuHooverColor);
  29. Point pt = Pt(p.x + Borderwidth, p.y+Borderwidth);
  30. string(e->i, pt, wht, pt, font, e->name);
  31. string(e->ih, pt, wht, pt, font, e->name);
  32. }
  33. static void
  34. resizeImageEntry(MenuEntry *e, int sizex){
  35. Image *aux;
  36. aux = e->i;
  37. e->i = allocimage(display, Rect(aux->r.min.x, aux->r.min.y, aux->r.min.x + sizex, aux->r.max.y), CMAP8, 1, jayconfig->mainMenuColor);
  38. draw(e->i, aux->r, aux, nil, e->i->r.min);
  39. freeimage(aux);
  40. aux = e->ih;
  41. e->ih = allocimage(display, Rect(aux->r.min.x, aux->r.min.y, aux->r.min.x + sizex, aux->r.max.y), e->ih->chan, 1, jayconfig->mainMenuHooverColor);
  42. draw(e->ih, aux->r, aux, nil, e->ih->r.min);
  43. freeimage(aux);
  44. }
  45. static void
  46. printEntries(StartMenu *sm) {
  47. MenuEntry *e;
  48. int maxx = 0;
  49. for (int i=0; i<sm->numEntries; i++){
  50. e = sm->entries[i];
  51. if (Dx(e->i->r) > maxx){
  52. maxx = Dx(e->i->r);
  53. }
  54. }
  55. if (maxx < Dx(sm->i->r)){
  56. maxx = Dx(sm->i->r);
  57. }
  58. for (int i=0; i<sm->numEntries; i++){
  59. e = sm->entries[i];
  60. resizeImageEntry(e, maxx);
  61. draw(sm->i, e->i->r, e->i, nil, e->i->r.min);
  62. }
  63. }
  64. void
  65. hoovermenu(StartMenu *sm, Point p) {
  66. MenuEntry *e;
  67. for(int i=0; i<sm->numEntries; i++){
  68. e = sm->entries[i];
  69. if(ptinrect(p, e->i->r)){
  70. draw(sm->i, e->i->r, e->ih, nil, e->i->r.min);
  71. } else {
  72. draw(sm->i, e->i->r, e->i, nil, e->i->r.min);
  73. }
  74. }
  75. }
  76. void
  77. execmenu(StartMenu *sm, Point p) {
  78. MenuEntry *e;
  79. for(int i=0; i<sm->numEntries; i++){
  80. e = sm->entries[i];
  81. if(ptinrect(p, e->i->r) && e->action != nil){
  82. new(wcenter(1.6*400, 400), FALSE, scrolling, 0, nil, e->action, nil);
  83. }
  84. }
  85. }
  86. void
  87. freeStartMenu(StartMenu *sm) {
  88. if(sm == nil)
  89. return;
  90. MenuEntry *e;
  91. for (int i=0; i<sm->numEntries; i++){
  92. e = sm->entries[i];
  93. freeimage(e->i);
  94. freeimage(e->ih);
  95. free(e->name);
  96. free(e->action);
  97. freeStartMenu(e->submenu);
  98. free(e);
  99. }
  100. sm->numEntries = 0;
  101. freeimage(sm->i);
  102. free(sm);
  103. }
  104. static char *
  105. getcharproperty(char *start, char *end, char *property){
  106. char *s, *aux, *r;
  107. int size;
  108. s = start;
  109. while (s < end && *s!='}' && strncmp(s, property, strlen(property))){
  110. if(*s == '['){
  111. //ignore submenu
  112. int o = 1;
  113. s++;
  114. while ( s < end && o > 0 ){
  115. while (s < end && *s != ']'){
  116. if(*s == '['){
  117. o++;
  118. }
  119. s++;
  120. }
  121. o--;
  122. }
  123. }
  124. s++;
  125. }
  126. while(s < end && *s!='}' && *s!='"'){
  127. s++;
  128. }
  129. if (s==end)
  130. return nil;
  131. aux = ++s;
  132. while(s < end && *s!='}' && *s!='"'){
  133. s++;
  134. }
  135. if (s==end || *s == '}' || s == aux)
  136. return nil;
  137. size = s - aux;
  138. r = malloc(size + 1);
  139. strncpy(r, aux, size);
  140. aux=r;
  141. aux += size;
  142. *aux = '\0';
  143. return r;
  144. }
  145. static StartMenu *
  146. parsesubmenuproperty(char *start, char *end){
  147. //TODO
  148. return nil;
  149. }
  150. static void
  151. parseentry(StartMenu *menu, char *start, char *end) {
  152. char *name, *action;
  153. Point p;
  154. if (menu->numEntries==0) {
  155. p = menu->i->r.min;
  156. } else {
  157. p = Pt(menu->i->r.min.x, menu->entries[menu->numEntries - 1]->i->r.max.y);
  158. }
  159. name = getcharproperty(start, end, "name");
  160. action = getcharproperty(start, end, "action");
  161. addEntry(menu, name, action, parsesubmenuproperty(start, end), p);
  162. free(name);
  163. free(action);
  164. }
  165. static StartMenu *
  166. parsemenu(char *start, char *end, Point p, int minSize){
  167. StartMenu *sm;
  168. char *s, *e;
  169. int o;
  170. s = start;
  171. if (*s != '['){
  172. return nil;
  173. }
  174. sm = malloc(sizeof(StartMenu));
  175. sm->numEntries=0;
  176. sm->i = allocwindow(wscreen, Rect(p.x +2, p.y + 2, p.x + minSize, p.y + 1.6*minSize), Refnone, jayconfig->mainMenuColor);
  177. while(s < end){
  178. while (s < end && *s !='{'){
  179. if(*s == ']')
  180. return sm;
  181. s++;
  182. }
  183. if(*s != '{')
  184. return nil;
  185. e = s + 1;
  186. o = 1;
  187. while (e < end && o > 0){
  188. while (e < end && *e !='}'){
  189. if (*e == '{')
  190. o++;
  191. e++;
  192. }
  193. o--;
  194. }
  195. if (e == end){
  196. freeStartMenu(sm);
  197. return nil;
  198. }
  199. parseentry(sm, s, e);
  200. s = ++e;
  201. }
  202. return sm;
  203. }
  204. static StartMenu *
  205. parsemenufile(TPanel *p, const char *path){
  206. int fd;
  207. Dir *d;
  208. char *s;
  209. fd = open(path, OREAD);
  210. if (fd < 0){
  211. error("openning menu file");
  212. return nil;
  213. }
  214. d = dirfstat(fd);
  215. s = malloc(sizeof(char) * d->length);
  216. if (read(fd, s, d->length)>0){
  217. close(fd);
  218. return parsemenu(s, s + d->length - 1, Pt(p->r.min.x, p->r.max.y), 100);
  219. }
  220. return nil;
  221. }
  222. StartMenu *
  223. loadStartMenu(TPanel *p){
  224. StartMenu *sm = parsemenufile(p, "/usr/harvey/lib/menu.conf");
  225. printEntries(sm);
  226. return sm;
  227. }