Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "winlib.h"
  4.  
  5. #define ID_SCROLLER_UP       0x30
  6. #define ID_SCROLLER_DOWN     0x31
  7. #define ID_SCROLLER_THUMB    0x32
  8.  
  9. typedef int v2si __attribute__ ((vector_size (8)));
  10.  
  11. font_t *create_font(void *face, int size);
  12.  
  13. static pos_t    old_pos;
  14. ctrl_t  *mouse_capture = NULL;
  15.  
  16.  
  17.  
  18. void show_window(window_t *win)
  19. {
  20.     BeginDraw();
  21.     DrawWindow(0,0,0,0,NULL,0,0x73);
  22.     if( (win->win_state != MINIMIZED) &&
  23.         (win->win_state != ROLLED) )
  24.         show_context(win->ctx);
  25.     EndDraw();
  26. }
  27.  
  28. window_t  *create_window(char *caption, int style, int x, int y,
  29.                             int w, int h, handler_t handler)
  30. {
  31.     char proc_info[1024];
  32.     window_t *win;
  33.  
  34.     if(handler==NULL)
  35.         return NULL;
  36.  
  37.     win = malloc(sizeof(*win));
  38.     if(win == NULL)
  39.         return NULL;
  40.  
  41.     BeginDraw();
  42.     DrawWindow(x, y, w+TYPE_3_BORDER_WIDTH*2,
  43.                h+TYPE_3_BORDER_WIDTH+get_skin_height(), caption, 0x000000, 0x73);
  44.     EndDraw();
  45.  
  46.     GetProcInfo(proc_info);
  47.  
  48.     x = *(uint32_t*)(proc_info+34);
  49.     y = *(uint32_t*)(proc_info+38);
  50.     w = *(uint32_t*)(proc_info+42)+1;
  51.     h = *(uint32_t*)(proc_info+46)+1;
  52.  
  53.     win->handler = handler;
  54.  
  55.     list_initialize(&win->link);
  56.     list_initialize(&win->child);
  57.  
  58.     win->rc.l = x;
  59.     win->rc.t = y;
  60.     win->rc.r = x + w;
  61.     win->rc.b = y + h;
  62.  
  63.     win->w = w;
  64.     win->h = h;
  65.  
  66.     win->client.l = TYPE_3_BORDER_WIDTH;
  67.     win->client.t = get_skin_height();
  68.     win->client.r = w - TYPE_3_BORDER_WIDTH;
  69.     win->client.b = h - TYPE_3_BORDER_WIDTH;
  70.     win->clw = win->client.r - win->client.l;
  71.     win->clh = win->client.b - win->client.t;
  72.  
  73.     win->caption_txt = caption;
  74.     win->style = style;
  75.  
  76.     win->child_over  = NULL;
  77.     win->child_focus = NULL;
  78.  
  79.     win->ctx = create_context(win->client.l, win->client.t, win->clw, win->clh);
  80.     clear_context(win->ctx, 0xFFFFFFFF);
  81.  
  82.     win->font = create_font(NULL, 14);
  83.  
  84.     send_message((ctrl_t*)win, MSG_CREATE, 0, 0);
  85.     send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
  86.  
  87.     ctrl_t *child;
  88.  
  89.     child  = (ctrl_t*)win->child.next;
  90.  
  91.     while( &child->link != &win->child)
  92.     {
  93.         send_message(child, MSG_DRAW, 0, 0);
  94.         child = (ctrl_t*)child->link.next;
  95.     };
  96.  
  97.     show_window(win);
  98.  
  99.     return win;
  100. };
  101.  
  102.  
  103. void handle_sys_paint(window_t *win)
  104. {
  105.     char proc_info[1024];
  106.     int winx, winy, winw, winh;
  107.     uint8_t  state;
  108.  
  109.     GetProcInfo(proc_info);
  110.  
  111.     winx = *(uint32_t*)(proc_info+34);
  112.     winy = *(uint32_t*)(proc_info+38);
  113.     winw = *(uint32_t*)(proc_info+42)+1;
  114.     winh = *(uint32_t*)(proc_info+46)+1;
  115.  
  116.     state  = *(uint8_t*)(proc_info+70);
  117.  
  118.     if(state & 2)
  119.     {
  120.         win->win_state = MINIMIZED;
  121.         return;
  122.     }
  123.     else if(state & 4)
  124.     {
  125.         win->win_state = ROLLED;
  126.         show_window(win);
  127.         return;
  128.     };
  129.  
  130.     if(state & 1)
  131.         state = MAXIMIZED;
  132.     else
  133.         state = NORMAL;
  134.  
  135.     if( (win->w != winw) ||
  136.         (win->h != winh) )
  137.     {
  138.         ctrl_t *child;
  139.  
  140.         win->client.l = TYPE_3_BORDER_WIDTH;
  141.         win->client.t = get_skin_height();
  142.         win->client.r = winw - TYPE_3_BORDER_WIDTH;
  143.         win->client.b = winh - TYPE_3_BORDER_WIDTH;
  144.         win->clw = win->client.r - win->client.l;
  145.         win->clh = win->client.b - win->client.t;
  146.  
  147.         resize_context(win->ctx, win->clw, win->clh);
  148.  
  149.         clear_context(win->ctx, 0xFFFFFFFF);
  150.  
  151.         send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
  152.         send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
  153.  
  154.         child  = (ctrl_t*)win->child.next;
  155.  
  156.         while( &child->link != &win->child)
  157.         {
  158.             send_message(child, MSG_DRAW, 0, 0);
  159.             child = (ctrl_t*)child->link.next;
  160.         };
  161.     }
  162.  
  163.     win->rc.l = winx;
  164.     win->rc.t = winy;
  165.     win->rc.r = winx + winw;
  166.     win->rc.b = winy + winh;
  167.     win->w = winw;
  168.     win->h = winh;
  169.     win->win_state = state;
  170.  
  171.     show_window(win);
  172. };
  173.  
  174.  
  175. ctrl_t *get_child(ctrl_t *ctrl, int x, int y)
  176. {
  177.     ctrl_t *child = NULL;
  178.  
  179.     ctrl_t *tmp = (ctrl_t*)ctrl->child.next;
  180.  
  181.     while( &tmp->link != &ctrl->child )
  182.     {
  183.         if(pt_in_rect(&tmp->rc, x, y))
  184.         {
  185.             child = get_child(tmp, x, y);
  186.             return child == NULL ? tmp : child;
  187.         };
  188.         tmp = (ctrl_t*)tmp->link.next;
  189.     };
  190.     return child;
  191. };
  192.  
  193.  
  194. int send_mouse_message(window_t *win, uint32_t msg)
  195. {
  196.     ctrl_t *child;
  197.  
  198.     if(mouse_capture)
  199.         return send_message(mouse_capture, msg, 0, old_pos.val);
  200.  
  201.     child = get_child((ctrl_t*)win, old_pos.x, old_pos.y);
  202.  
  203.     if(msg == MSG_MOUSEMOVE)
  204.     {
  205.         if( win->child_over )
  206.         {
  207.             if(child == win->child_over)
  208.                 send_message(child, MSG_MOUSEMOVE, 0, old_pos.val);
  209.             else
  210.                 send_message(win->child_over, MSG_MOUSELEAVE, 0, old_pos.val);
  211.         }
  212.         else if( child )
  213.             send_message(child, MSG_MOUSEENTER, 0, old_pos.val);
  214.  
  215.         win->child_over = child;
  216.     };
  217.  
  218.     if( child )
  219.         return send_message(child, msg, 0, old_pos.val);
  220.  
  221.     if(pt_in_rect(&win->client, old_pos.x, old_pos.y))
  222.         return send_message((ctrl_t*)win, msg, 0, old_pos.val);
  223.  
  224. };
  225.  
  226. #define DBG(x)
  227.  
  228. static void handle_sys_mouse(window_t *win)
  229. {
  230.     static uint32_t  mouse_click_time;
  231.     static int  mouse_action;
  232.     static int  old_buttons;
  233.     int         buttons;
  234.     uint32_t    wheels;
  235.     uint32_t    click_time;
  236.     int         action;
  237.  
  238.     pos_t       pos;
  239.  
  240.     mouse_action = 0;
  241.     pos = get_mouse_pos(POS_WINDOW);
  242.  
  243.     if(pos.val != old_pos.val)
  244.     {
  245.         mouse_action = 0x80000000;
  246.         old_pos = pos;
  247.     };
  248. //    printf("pos x%d y%d\n", pos.x, pos.y);
  249.  
  250.     buttons = get_mouse_buttons();
  251.     wheels = get_mouse_wheels();
  252.  
  253. //    if( wheels & 0xFFFF){
  254. //        wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP;
  255. //        send_mouse_message(win, wheels);
  256. //    }
  257.  
  258.     if((action = (buttons ^ old_buttons))!=0)
  259.     {
  260.         mouse_action|= action<<3;
  261.         mouse_action|= buttons & ~old_buttons;
  262.     }
  263.     old_buttons = buttons;
  264.  
  265.     if(mouse_action & 0x80000000) {
  266.         DBG("mouse move \n\r");
  267.         send_mouse_message(win, MSG_MOUSEMOVE);
  268.     };
  269.  
  270.     if(mouse_action & 0x09)
  271.     {
  272.         if((mouse_action & 0x09)==0x09)
  273.         {
  274. //            printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y);
  275.             click_time = get_tick_count();
  276.             if(click_time < mouse_click_time+35) {
  277.                 mouse_click_time = click_time;
  278.                 send_mouse_message(win,MSG_LBTNDBLCLK);
  279.             }
  280.             else {
  281.               mouse_click_time = click_time;
  282.               send_mouse_message(win,MSG_LBTNDOWN);
  283.             };
  284.         }
  285.         else {
  286. //            printf("left button up \n\r");
  287.             send_mouse_message(win,MSG_LBTNUP);
  288.         }
  289.     };
  290.  
  291.     if(mouse_action & 0x12)
  292.     {
  293.         if((mouse_action & 0x12)==0x12) {
  294.             DBG("right button down \n\r");
  295.             send_mouse_message(win,MSG_RBTNDOWN);
  296.         }
  297.         else {
  298.             DBG("right button up \n\r");
  299.             send_mouse_message(win,MSG_RBTNUP);
  300.         };
  301.     };
  302.     if(mouse_action & 0x24)
  303.     {
  304.         if((mouse_action & 0x24)==0x24){
  305.             DBG("middle button down \n\r");
  306.             send_mouse_message(win,MSG_MBTNDOWN);
  307.         }
  308.         else {
  309.             DBG("middle button up \n\r");
  310.             send_mouse_message(win,MSG_MBTNUP);
  311.         };
  312.     };
  313. };
  314.  
  315.  
  316. int handle_system_events(window_t *win)
  317. {
  318.     oskey_t   key;
  319.  
  320.     for (;;)
  321.     {
  322.         switch (get_os_event())
  323.         {
  324.             case MSG_SYS_PAINT:
  325.                 handle_sys_paint(win);
  326.                 break;
  327.  
  328.             case MSG_SYS_KEY:
  329.                 key = get_key();
  330.                 printf("key %d\n", key.code);
  331.                 break;
  332.  
  333.             case MSG_SYS_BUTTON:
  334.                 // button pressed; we have only one button, close
  335.                 return 0;
  336.  
  337.             case MSG_SYS_MOUSE:
  338.                 handle_sys_mouse(win);
  339.                 break;
  340.         };
  341.  
  342.         if( (win->win_state != MINIMIZED) &&
  343.             (win->win_state != ROLLED) )
  344.             show_context(win->ctx);
  345.     }
  346.  
  347.     return 0;
  348. }
  349.  
  350. void *create_control(size_t size, int id, int x, int y,
  351.                          int w, int h, ctrl_t *parent)
  352. {
  353.  
  354.     ctrl_t  *ctrl;
  355.  
  356.     if( !parent )
  357.         return NULL;
  358.  
  359.     ctrl = (ctrl_t*)malloc(size);
  360.  
  361.     link_initialize(&ctrl->link);
  362.     list_initialize(&ctrl->child);
  363.  
  364.     ctrl->parent  = parent;
  365.  
  366.     ctrl->ctx     = parent->ctx;
  367.     ctrl->font    = parent->font;
  368.     ctrl->id      = id;
  369.  
  370.     ctrl->rc.l    = x;
  371.     ctrl->rc.t    = y ;
  372.  
  373.     ctrl->rc.r    = x + w;
  374.     ctrl->rc.b    = y + h;
  375.  
  376.     ctrl->w       = w;
  377.     ctrl->h       = h;
  378.  
  379.     list_append(&ctrl->link, &parent->child);
  380.  
  381.     return ctrl;
  382. };
  383.  
  384.  
  385. int move_ctrl(ctrl_t *ctrl, int x, int y, int w, int h)
  386. {
  387.     rect_t rc;
  388.     rc.l = x;
  389.     rc.t = y;
  390.     rc.r = w;
  391.     rc.b = h;
  392.  
  393.     send_message(ctrl, MSG_POSCHANGING, 0, &rc);
  394.  
  395.     ctrl->rc.l = rc.l;
  396.     ctrl->rc.t = rc.t;
  397.     ctrl->rc.r = rc.l + rc.r;
  398.     ctrl->rc.b = rc.t + rc.b;
  399.     ctrl->w = rc.r;
  400.     ctrl->h = rc.b;
  401.  
  402.     send_message(ctrl, MSG_POSCHANGE, 0, &rc);
  403.  
  404.     return 1;
  405. };
  406.  
  407.  
  408.  
  409. /*
  410.  *
  411.  *
  412.  *
  413.  *
  414.  *
  415.  *
  416.  *
  417.  *
  418. */
  419.  
  420. int def_ctrl_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
  421. {
  422.     switch( msg )
  423.     {
  424.  
  425.     };
  426.  
  427.     return 0;
  428. }
  429.  
  430. /*
  431.  *
  432.  *
  433.  *
  434.  *
  435.  *
  436.  *
  437.  *
  438.  *
  439. */
  440.  
  441.  
  442. static void scroller_on_draw(scroller_t *scrl)
  443. {
  444.     if(scrl->btn_up)
  445.         send_message((ctrl_t*)scrl->btn_up, MSG_DRAW, 0, 0);
  446.  
  447.     if(scrl->btn_down)
  448.         send_message((ctrl_t*)scrl->btn_down, MSG_DRAW, 0, 0);
  449.  
  450.     if(scrl->thumb)
  451.         send_message((ctrl_t*)scrl->thumb, MSG_DRAW, 0, 0);
  452.  
  453.     if(scrl->tl_rect.t != scrl->tl_rect.b)
  454.         px_fill_rect(scrl->ctrl.ctx, &scrl->tl_rect, 0xFFE1D8D0);
  455.  
  456.     if(scrl->br_rect.t != scrl->br_rect.b)
  457.         px_fill_rect(scrl->ctrl.ctx, &scrl->br_rect, 0xFFE1D8D0);
  458. }
  459.  
  460. static void scroller_on_ownerdraw(scroller_t *scrl, ctrl_t *child)
  461. {
  462. typedef struct
  463. {
  464.     ctrl_t   ctrl;
  465.  
  466.     uint32_t state;
  467.  
  468.     char     *caption;
  469.     int       capt_len;
  470. }button_t;
  471.  
  472.     button_t *btn;
  473.     color_t color = 0xFFD7D7D7;
  474.     char t = (char)child->id;
  475.     rect_t rc;
  476.  
  477.     switch(child->id)
  478.     {
  479.         case ID_SCROLLER_UP:
  480.         case ID_SCROLLER_DOWN:
  481.             btn = (button_t*)child;
  482.             if(btn->state & bPressed)
  483.                 color = 0xFFB0B0B0;
  484.             else if(btn->state & bHighlight)
  485.                 color = 0xFFE7E7E7;
  486.  
  487.             rc = btn->ctrl.rc;
  488.             px_fill_rect(btn->ctrl.ctx, &rc, color);
  489.             rc.l+= 3;
  490.             rc.t+= 5;
  491.             draw_text_ext(btn->ctrl.ctx, sym_font, &t, 1, &rc, 0xFF000000);
  492.             break;
  493.  
  494.         case ID_SCROLLER_THUMB:
  495.             btn = (button_t*)child;
  496.             color = 0xFFB0B0B0;
  497.             if(btn->state & bPressed)
  498.                 color = 0xFF707070;
  499.             else if(btn->state & bHighlight)
  500.                 color = 0xFF909090;
  501.  
  502.             rc = btn->ctrl.rc;
  503.             px_fill_rect(btn->ctrl.ctx, &rc, color);
  504.     }
  505. };
  506.  
  507. static void scroller_update_layout(scroller_t *scrl)
  508. {
  509.  
  510. //    th_size = scrl->pix_range*scrl->page_size/
  511. //              (scrl->max_range-scrl->min_range);
  512.  
  513. //    if(th_size > scrl->pix_range)
  514. //        th_size = scrl->pix_range;
  515.  
  516.     scrl->tl_rect.l = scrl->ctrl.rc.l;
  517.     scrl->br_rect.l = scrl->ctrl.rc.l;
  518.  
  519.     scrl->tl_rect.r = scrl->ctrl.rc.r;
  520.     scrl->br_rect.r = scrl->ctrl.rc.r;
  521.  
  522.     scrl->tl_rect.t = scrl->btn_up->rc.b;
  523.     scrl->tl_rect.b = scrl->thumb->rc.t;
  524.  
  525.     scrl->br_rect.t = scrl->thumb->rc.b;
  526.     scrl->br_rect.b = scrl->btn_down->rc.t;
  527.  
  528.     scrl->pix_range = scrl->ctrl.h - 40 - 20;
  529. };
  530.  
  531. static void scroller_on_poschange(scroller_t *scrl, rect_t *pos)
  532. {
  533.     move_ctrl(scrl->btn_up, pos->l, pos->t, pos->r, pos->r);
  534.     move_ctrl(scrl->btn_down, pos->l, pos->t+pos->b-pos->r, pos->r, pos->r);
  535.     move_ctrl(scrl->thumb, pos->l, pos->t+pos->r, pos->r, pos->r);
  536.  
  537.     scroller_update_layout(scrl);
  538.     scroller_on_draw(scrl);
  539. };
  540.  
  541. static void scroller_on_command(scroller_t *ctrl, int id, ctrl_t *child, int notify)
  542. {
  543.     scroller_t *scrl = (scroller_t*)ctrl;
  544.     int thumb_pos = scrl->thumb_pos;
  545.  
  546.     switch(id)
  547.     {
  548.         case ID_SCROLLER_UP:
  549.             if(scrl->thumb_pos > scrl->min_range)
  550.                 scrl->thumb_pos--;
  551.             printf("scroll up\n");
  552.             break;
  553.         case ID_SCROLLER_DOWN:
  554.             if(scrl->thumb_pos < scrl->max_range)
  555.                 scrl->thumb_pos++;
  556.             printf("scroll down\n");
  557.             break;
  558.     };
  559.  
  560.     if(thumb_pos != scrl->thumb_pos)
  561.     {
  562.         rect_t rc = scrl->thumb->rc;
  563.         int offset = scrl->pix_range*scrl->thumb_pos;
  564.         offset /= scrl->max_range - scrl->min_range;
  565.         rc.t = scrl->ctrl.rc.t + scrl->btn_up->h + offset;
  566.         rc.r = scrl->thumb->w;
  567.         rc.b = scrl->thumb->h;
  568.         move_ctrl(scrl->thumb, rc.l, rc.t, rc.r, rc.b);
  569.         scroller_update_layout(scrl);
  570.         scroller_on_draw(scrl);
  571.     }
  572. }
  573.  
  574. int scroller_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
  575. {
  576.     scroller_t *scrl = (scroller_t*)ctrl;
  577.  
  578.     switch( msg )
  579.     {
  580.         HANDLE_MSG(scrl, MSG_DRAW, scroller_on_draw);
  581.         HANDLE_MSG(scrl, MSG_COMMAND, scroller_on_command);
  582.         HANDLE_MSG(scrl, MSG_OWNERDRAW, scroller_on_ownerdraw);
  583.         HANDLE_MSG(scrl, MSG_POSCHANGE, scroller_on_poschange);
  584.     };
  585.  
  586.     return 0;
  587. };
  588.  
  589.  
  590. scroller_t *create_scroller(uint32_t style, int id, int x, int y,
  591.                             int w, int h, ctrl_t *parent)
  592. {
  593.     scroller_t  *scrl;
  594.  
  595.     if( !parent )
  596.         return NULL;
  597.  
  598.     scrl = create_control(sizeof(scroller_t), id, x, y, w, h, parent);
  599.     scrl->ctrl.handler = scroller_proc;
  600.  
  601.     scrl->min_range = 0;
  602.     scrl->max_range = 100;
  603.     scrl->thumb_pos = 0;
  604.     scrl->page_size = 1;
  605.  
  606.     scrl->btn_up = create_button(NULL, 1, ID_SCROLLER_UP, x, y, w, w, (ctrl_t*)scrl);
  607.     scrl->btn_down = create_button(NULL, 1, ID_SCROLLER_DOWN, x, y+h-w, w, w, (ctrl_t*)scrl);
  608.     scrl->thumb = create_button(NULL, 1, ID_SCROLLER_THUMB, x, w, w, w, (ctrl_t*)scrl);
  609.  
  610.     scroller_update_layout(scrl);
  611.  
  612.     return scrl;
  613. };
  614.  
  615.  
  616.