Subversion Repositories Kolibri OS

Rev

Rev 7254 | Rev 7257 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. enum {
  2.         TOOL_NONE = -1,
  3.         TOOL_PENCIL,
  4.         TOOL_PIPETTE,
  5.         TOOL_FILL,
  6.         TOOL_LINE,
  7.         TOOL_RECT,
  8.         TOOL_SELECT
  9. };
  10.  
  11. struct Tool {
  12.         int id;
  13.        
  14.         void (*activate)();
  15.         void (*deactivate)();
  16.         void (*onMouseEvent)(int x, int y, int lkm, int pkm);
  17.         void (*onKeyEvent)(dword keycode);
  18.         void (*onCanvasDraw)();
  19. };
  20.  
  21. int currentTool = -1;
  22. Tool tools[6];
  23.  
  24.  
  25. void resetCurrentTool() {
  26.         if ((currentTool != TOOL_NONE) && (tools[currentTool].deactivate != 0)) {
  27.                 tools[currentTool].deactivate();
  28.         }
  29.        
  30.         currentTool = TOOL_NONE;
  31. }
  32.  
  33. void setCurrentTool(int index) {
  34.         resetCurrentTool();
  35.  
  36.         currentTool = index;
  37.        
  38.         if ((index != TOOL_NONE) && (tools[index].activate != 0))
  39.                 tools[index].activate();
  40.  
  41.         DrawLeftPanel();
  42.         DrawCanvas();
  43. }
  44.  
  45. //===================================================//
  46. //                                                   //
  47. //                    FUNTIONS                       //
  48. //                                                   //
  49. //===================================================//
  50.  
  51. void FillTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
  52.         if (canvas.hovered()) && (currentTool==TOOL_FILL) && (mouse.up)
  53.         {
  54.                 image.fill(mouseY-canvas.y/zoom.value,
  55.                                 mouseX-canvas.x/zoom.value, tool_color);
  56.                 actionsHistory.saveCurrentState();                     
  57.                 DrawCanvas();
  58.         }
  59. }
  60.  
  61. void PipetteTool_activate() {
  62.         SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE);
  63. }
  64.  
  65. void PipetteTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
  66.         tool_color = GetPixelUnderMouse();
  67.         DrawBar(Form.cwidth-30, 5, 20, 20, tool_color);
  68.        
  69.         if (mouse.down) {
  70.                 DrawBar(Form.cwidth-30, 5, 20, 20, system.color.work);
  71.                 SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER);
  72.                 if (mouse.key&MOUSE_LEFT) EventSetActiveColor(1, tool_color);
  73.                 if (mouse.key&MOUSE_RIGHT) EventSetActiveColor(2, tool_color);
  74.                
  75.                 setCurrentTool(TOOL_PENCIL);
  76.         }
  77. }
  78.  
  79. bool PencilTool_Drawing = false;
  80.  
  81. void PencilTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
  82.         if (canvas.hovered())
  83.         {
  84.                 if ((PencilTool_Drawing == true) && (!mouse.key)) {
  85.                         actionsHistory.saveCurrentState();
  86.                         PencilTool_Drawing = false;
  87.                 }
  88.  
  89.                 if (mouse.key) {
  90.                         image.set_pixel(mouseY-canvas.y/zoom.value,
  91.                                 mouseX-canvas.x/zoom.value, tool_color);
  92.                         PencilTool_Drawing = true;
  93.                 }
  94.                 DrawCanvas();
  95.         }
  96. }
  97.  
  98. void PencilTool_reset() {
  99.         PencilTool_Drawing = false;
  100. }
  101.  
  102. // Line tool
  103. struct SimpleFigureTool_State {
  104.         int startX, startY;
  105.         int lastTempPosX, lastTempPosY;
  106. };
  107.  
  108. enum {
  109.         TOOL_LINE_STATE,
  110.         TOOL_RECT_STATE
  111. };
  112.  
  113. dword currentFigToolState = -1;
  114. SimpleFigureTool_State figTool_States[2];
  115.  
  116. void SimpleFigureTool_Reset() {
  117.         if (currentTool == TOOL_LINE)
  118.                 currentFigToolState = TOOL_LINE_STATE;
  119.         else if (currentTool == TOOL_RECT)
  120.                 currentFigToolState = TOOL_RECT_STATE;
  121.  
  122.         figTool_States[currentFigToolState].startX = -1;
  123.         figTool_States[currentFigToolState].startY = -1;
  124.         figTool_States[currentFigToolState].lastTempPosX = -1;
  125.         figTool_States[currentFigToolState].lastTempPosY = -1;
  126. }
  127.  
  128. int mouseX_last;
  129. int mouseY_last;
  130. bool first_click_in_canvas = false;
  131.  
  132. void SimpleFigureTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
  133.         if (mouse.down) && (canvas.hovered()) first_click_in_canvas = true;
  134.         if (first_click_in_canvas)
  135.         {
  136.                 if (mouseX>canvas.x+canvas.w-zoom.value) mouseX = canvas.x+canvas.w-zoom.value;
  137.                 if (mouseY>canvas.y+canvas.h-zoom.value) mouseY = canvas.y+canvas.h-zoom.value;
  138.                 if (mouseX<canvas.x) mouseX = canvas.x;
  139.                 if (mouseY<canvas.y) mouseY = canvas.y;
  140.  
  141.                 if (mouse.key) {
  142.                         if ((figTool_States[currentFigToolState].startX < 0)
  143.                         || (figTool_States[currentFigToolState].startY < 0)) {
  144.                                 figTool_States[currentFigToolState].startX = mouseX;
  145.                                 figTool_States[currentFigToolState].startY = mouseY;
  146.                         }
  147.                         else {
  148.                                 if ((calc(mouseX - canvas.x/zoom.value) != figTool_States[currentFigToolState].lastTempPosX)
  149.                                         || (calc(mouseY - canvas.y/zoom.value) != figTool_States[currentFigToolState].lastTempPosY))
  150.                                 {
  151.                                         DrawCanvas();
  152.                                 }
  153.                         }
  154.                         mouseX_last = mouseX;
  155.                         mouseY_last = mouseY;
  156.                 }
  157.                 if (mouse.up) {
  158.                         if ((figTool_States[currentFigToolState].startX >= 0)
  159.                         && (figTool_States[currentFigToolState].startY >= 0)) {
  160.                                 // Draw line from start position to current position
  161.                                 if (currentTool == TOOL_LINE) {
  162.                                         DrawLine(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
  163.                                                 figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
  164.                                                 mouseX - canvas.x/zoom.value,
  165.                                                 mouseY - canvas.y/zoom.value,
  166.                                                 tool_color,
  167.                                                 1);
  168.                                 }
  169.                                 else if (currentTool == TOOL_RECT) {
  170.                                         DrawRectangleInCanvas(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
  171.                                                 figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
  172.                                                 mouseX - canvas.x/zoom.value,
  173.                                                 mouseY - canvas.y/zoom.value, tool_color, 1);
  174.                                 }
  175.  
  176.                                 DrawCanvas();
  177.  
  178.                                 actionsHistory.saveCurrentState();
  179.  
  180.                                 // Reset start position
  181.                                 figTool_States[currentFigToolState].startX = -1;
  182.                                 figTool_States[currentFigToolState].startY = -1;
  183.  
  184.                                 first_click_in_canvas = false;
  185.                         }
  186.                 }
  187.         }
  188. }
  189.  
  190. void SimpleFigureTool_onCanvasDraw() {
  191.         if ((figTool_States[currentFigToolState].startX >= 0)
  192.         && (figTool_States[currentFigToolState].startY >= 0) && (mouse.key)) {
  193.                 if (currentTool == TOOL_LINE) {
  194.                         DrawLine(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
  195.                                 figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
  196.                                 mouseX_last - canvas.x/zoom.value,
  197.                                 mouseY_last - canvas.y/zoom.value,
  198.                                 tool_color,
  199.                                 2);
  200.                 }
  201.                 else if (currentTool == TOOL_RECT) {
  202.                         DrawRectangleInCanvas(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
  203.                                 figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
  204.                                 mouseX_last - canvas.x/zoom.value,
  205.                                 mouseY_last - canvas.y/zoom.value,
  206.                                 tool_color,
  207.                                 2);
  208.                 }
  209.  
  210.                 figTool_States[currentFigToolState].lastTempPosX = mouseX_last - canvas.x/zoom.value;
  211.                 figTool_States[currentFigToolState].lastTempPosY = mouseY_last - canvas.y/zoom.value;
  212.         }
  213. }
  214.  
  215. // Selection
  216. int selection_start_x = -1;
  217. int selection_start_y = -1;
  218. int selection_end_x = -1;
  219. int selection_end_y = -1;
  220. bool selection_active = false;
  221.  
  222. dword SelectionTool_buffer = 0;
  223. dword SelectionTool_buffer_r = 0;
  224. dword SelectionTool_buffer_c = 0;
  225.  
  226. bool selection_moving_started = false;
  227. int selection_pivot_x = -1;
  228. int selection_pivot_y = -1;
  229.  
  230. void SelectTool_normalizeSelection() {
  231.         int t;
  232.  
  233.         // Restructuring of the selection coordinates
  234.         if (selection_end_x < selection_start_x) {
  235.                 t = selection_start_x;
  236.                 selection_start_x = selection_end_x;
  237.                 selection_end_x = t;
  238.         }
  239.  
  240.         if (selection_end_y < selection_start_y) {
  241.                 t = selection_end_y;
  242.                 selection_end_y = selection_start_y;
  243.                 selection_start_y = t;
  244.         }
  245. }
  246.  
  247. void reset_selection_moving() {
  248.         if (selection_moving_started) {
  249.                 SelectTool_drawBuffer(selection_start_x, selection_start_y, 1);
  250.  
  251.                 selection_pivot_x = -1;
  252.                 selection_pivot_y = -1;
  253.                
  254.                 selection_moving_started = false;
  255.                
  256.                 actionsHistory.saveCurrentState();
  257.                 DrawCanvas();
  258.         }
  259. }
  260.  
  261. bool is_selection_moving() {
  262.         return selection_moving_started;
  263. }
  264.  
  265. void reset_selection() {
  266.         reset_selection_moving();
  267.        
  268.         selection_start_x = -1;
  269.         selection_start_y = -1;
  270.         selection_end_x = -1;
  271.         selection_end_y = -1;  
  272. }
  273.  
  274. void SelectTool_activate() {
  275.         reset_selection();
  276.  
  277.         selection_active = false;
  278. }
  279.  
  280. void SelectTool_deactivate() {
  281.         reset_selection_moving();
  282. }
  283.  
  284. bool SelectTool_pointInSelection(int x, int y) {
  285.         if (x >= selection_start_x) && (x <= selection_end_x) && (y >= selection_start_y) && (y <= selection_end_y)
  286.                 return true;
  287.         else
  288.                 return false;
  289. }
  290.  
  291.  
  292. void SelectTool_copyToBuffer() {
  293.         dword offset, r, c;
  294.  
  295.                 if (SelectionTool_buffer != 0)
  296.                         free(SelectionTool_buffer);
  297.  
  298.                 SelectionTool_buffer_r = selection_end_y - selection_start_y + 1;
  299.                 SelectionTool_buffer_c = selection_end_x - selection_start_x + 1;
  300.                 SelectionTool_buffer = malloc(SelectionTool_buffer_r * SelectionTool_buffer_c * 4);
  301.  
  302.                 for (r = selection_start_y; r <= selection_end_y; r++) {
  303.                         for (c = selection_start_x; c <= selection_end_x; c++) {
  304.                                 offset = calc(SelectionTool_buffer_c * calc(r - selection_start_y) + calc(c - selection_start_x)) * 4;
  305.  
  306.                                 ESDWORD[SelectionTool_buffer + offset] = image.get_pixel(r, c);
  307.                         }
  308.                 }
  309. }
  310.  
  311. void SelectTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
  312.         int click_x, click_y, dx, dy, m_x, m_y, r, c, color;
  313.         dword pixel;
  314.        
  315.         m_x = TO_CANVAS_X(mouseX);
  316.         m_y = TO_CANVAS_Y(mouseY);
  317.        
  318.         if (mouse.down) && (canvas.hovered()) && (!selection_active) {
  319.                 if (selection_start_x != -1) && (SelectTool_pointInSelection(m_x, m_y)) {
  320.                         if (selection_pivot_x == -1) {
  321.                                 selection_pivot_x = m_x;
  322.                                 selection_pivot_y = m_y;
  323.                                
  324.                                 GetKeys();
  325.                                
  326.                                 if (!selection_moving_started) && ( !(key_modifier&KEY_LSHIFT) ) {
  327.                                         for (r = selection_start_y; r <= selection_end_y; r++)
  328.                                                 for (c = selection_start_x; c <= selection_end_x; c++) {
  329.                                                         image.set_pixel(r, c, color2);
  330.                                                 }
  331.                                 }
  332.                                
  333.                                 selection_moving_started = true;
  334.                         }
  335.                 }
  336.                 else {
  337.                
  338.                         reset_selection();
  339.                         selection_active = true;
  340.                 }
  341.         }
  342.  
  343.         if (selection_pivot_x != -1) {
  344.                 dx = m_x - selection_pivot_x;
  345.                 dy = m_y - selection_pivot_y;
  346.  
  347.                 if (selection_start_x + dx < 0)
  348.                         dx = selection_start_x;
  349.                
  350.                 if (selection_end_x + dx >= image.columns)
  351.                         dx = image.columns-1 - selection_end_x;
  352.                
  353.                 if (selection_start_y + dy < 0)
  354.                         dy = selection_start_y;
  355.                
  356.                 if (selection_end_y + dy >= image.rows)
  357.                         dy = image.rows-1 - selection_end_y;
  358.                
  359.                
  360.                 selection_start_x += dx;
  361.                 selection_end_x += dx;
  362.                
  363.                 selection_start_y += dy;
  364.                 selection_end_y += dy;
  365.                
  366.                 selection_pivot_x += dx;
  367.                 selection_pivot_y += dy;
  368.                
  369.                 DrawCanvas();
  370.         }
  371.        
  372.         if (selection_active)
  373.         {
  374.                 if (mouseX>canvas.x+canvas.w-zoom.value) mouseX = canvas.x+canvas.w-zoom.value;
  375.                 if (mouseY>canvas.y+canvas.h-zoom.value) mouseY = canvas.y+canvas.h-zoom.value;
  376.  
  377.                 if (mouseX<canvas.x) mouseX = canvas.x;
  378.                 if (mouseY<canvas.y) mouseY = canvas.y;
  379.  
  380.                 if (mouse.key) {
  381.                         selection_end_x = TO_CANVAS_X(mouseX);
  382.                         selection_end_y = TO_CANVAS_Y(mouseY);
  383.  
  384.                         if ((selection_start_x < 0) || (selection_start_y < 0)) {
  385.                                 selection_start_x = TO_CANVAS_X(mouseX);
  386.                                 selection_start_y = TO_CANVAS_Y(mouseY);
  387.                         }
  388.                         else {
  389.                                 DrawCanvas();
  390.  
  391.                                 /**if ((calc(TO_CANVAS_X(mouseX)) != selection_end_x)
  392.                                         || (calc(TO_CANVAS_Y(mouseY)) != selection_end_y))
  393.                                 {
  394.                                         DrawCanvas();
  395.                                 }*/
  396.                         }
  397.  
  398.                 }
  399.                
  400.                 if (mouse.up) {                
  401.                         selection_active = false;
  402.                        
  403.                         SelectTool_normalizeSelection();
  404.                         SelectTool_copyToBuffer();
  405.                 }
  406.         }
  407.        
  408.         if (mouse.up) {
  409.                 if (selection_pivot_x != -1) {
  410.                         selection_pivot_x = -1;
  411.                         selection_pivot_y = -1;
  412.                 }
  413.         }
  414. }
  415.  
  416. void SelectTool_onCanvasDraw() {       
  417.         if (selection_moving_started)
  418.                 SelectTool_drawBuffer(selection_start_x, selection_start_y, 2);
  419.  
  420.         if ((selection_start_x >= 0) && (selection_start_y >= 0) && (selection_end_x >= 0) && (selection_end_y >= 0)) {
  421.                 DrawSelection(selection_start_x, selection_start_y, selection_end_x, selection_end_y);
  422.         }      
  423. }
  424.  
  425. void SelectTool_drawBuffer(int insert_x, int insert_y, int target) {
  426.         dword color;
  427.         dword offset, r, c;
  428.         dword insert_to_x, insert_to_y;
  429.        
  430.         if (SelectionTool_buffer != 0) {
  431.                 insert_to_x = insert_x + SelectionTool_buffer_c - 1;
  432.                        
  433.                 if (insert_to_x >= image.columns)
  434.                         insert_to_x = image.columns-1;
  435.  
  436.                 insert_to_y = insert_y + SelectionTool_buffer_r - 1;
  437.                        
  438.                 if (insert_to_y >= image.rows)
  439.                         insert_to_y = image.rows-1;
  440.  
  441.                 for (r = insert_y; r <= insert_to_y; r++) {
  442.                         for (c = insert_x; c <= insert_to_x; c++) {
  443.                                         offset = calc(SelectionTool_buffer_c * calc(r - insert_y) + calc(c - insert_x)) * 4;
  444.  
  445.                                         color = ESDWORD[SelectionTool_buffer + offset];
  446.                                        
  447.                                         if (target == 1)
  448.                                                 image.set_pixel(r, c, color);
  449.                                         else
  450.                                                 DrawBar(c*zoom.value + canvas.x, r*zoom.value + canvas.y,
  451.                                                         zoom.value, zoom.value, color);
  452.                         }
  453.                 }      
  454.         }      
  455. }
  456.  
  457. void SelectTool_onKeyEvent(dword keycode) {
  458.         dword offset, r, c;
  459.         dword insert_x, insert_y, insert_to_x, insert_to_y;
  460.  
  461.         if (keycode == SCAN_CODE_KEY_V) {
  462.                 if (SelectionTool_buffer != 0) {
  463.                         reset_selection();
  464.                        
  465.                         selection_moving_started = true;
  466.                         selection_start_x = 0;
  467.                         selection_end_x = SelectionTool_buffer_c - 1;
  468.                        
  469.                         selection_start_y = 0;
  470.                         selection_end_y = SelectionTool_buffer_r - 1;
  471.                        
  472.                         DrawCanvas();
  473.        
  474.                 }
  475.         }
  476. }
  477.  
  478.  
  479. //===================================================//
  480. //                                                   //
  481. //                      DRAWs                        //
  482. //                                                   //
  483. //===================================================//
  484.  
  485.  
  486.  
  487. // target - image (1) or canvas (2)
  488. void DrawLine(int x1, int y1, int x2, int y2, dword color, int target) {
  489.         int dx, dy, signX, signY, error, error2;
  490.  
  491.         if (1==target) {
  492.                 image.draw_line(x1, y1, x2, y2, color);
  493.                 return;
  494.         }
  495.        
  496.         dx = x2 - x1;
  497.  
  498.         if (dx < 0)
  499.                 dx = -dx;
  500.    
  501.         dy = y2 - y1;
  502.  
  503.         if (dy < 0)
  504.                 dy = -dy;
  505.    
  506.         if (x1 < x2)
  507.                 signX = 1;
  508.         else
  509.                 signX = -1;
  510.    
  511.         if (y1 < y2)
  512.                 signY = 1;
  513.         else
  514.                 signY = -1;
  515.    
  516.         error = dx - dy;
  517.  
  518.         DrawBar(x2*zoom.value + canvas.x, y2*zoom.value + canvas.y,
  519.                         zoom.value, zoom.value, color);
  520.  
  521.         while((x1 != x2) || (y1 != y2))
  522.         {
  523.                 DrawBar(x1*zoom.value + canvas.x, y1*zoom.value + canvas.y,
  524.                         zoom.value, zoom.value, color);
  525.                
  526.            error2 = error * 2;
  527.  
  528.        if(error2 > calc(-dy))
  529.        {
  530.            error -= dy;
  531.            x1 += signX;
  532.        }
  533.            
  534.        if(error2 < dx)
  535.        {
  536.            error += dx;
  537.            y1 += signY;
  538.        }
  539.         }
  540. }
  541.  
  542. void DrawRectangleInCanvas(int x1, int y1, int x2, int y2, dword color, int target) {
  543.         DrawLine(x1, y1, x2, y1, color, target);
  544.         DrawLine(x2, y1, x2, y2, color, target);
  545.         DrawLine(x2, y2, x1, y2, color, target);
  546.         DrawLine(x1, y2, x1, y1, color, target);
  547. }
  548.  
  549. #define SELECTION_COLOR 0xAAE5EF
  550.  
  551. void DrawSelection(int x1, int y1, int x2, int y2) {
  552.         int p1x, p1y, p2x, p2y, r, c, old_color, new_color;
  553.         dword offset;
  554.  
  555.         if (x1 <= x2) {
  556.                 p1x = x1;
  557.                 p2x = x2;
  558.         }
  559.         else {
  560.                 p1x = x2;
  561.                 p2x = x1;
  562.         }
  563.  
  564.         if (y1 <= y2) {
  565.                 p2y = y1;
  566.                 p1y = y2;
  567.         }
  568.         else {
  569.                 p2y = y2;
  570.                 p1y = y1;
  571.         }
  572.  
  573.         for (r = p1y; r >= p2y; r--) {
  574.                 for (c = p1x; c <= p2x; c++) {
  575.                        
  576.                         if (selection_moving_started) && (SelectTool_pointInSelection(c, r)) {
  577.                                 offset = calc(SelectionTool_buffer_c * calc(r - selection_start_y) + calc(c - selection_start_x)) * 4;
  578.                                 old_color = ESDWORD[SelectionTool_buffer + offset];
  579.                         }
  580.                         else {
  581.                                 old_color = image.get_pixel(r, c);
  582.                         }
  583.                        
  584.                         new_color = MixColors(old_color, SELECTION_COLOR, 64);
  585.                        
  586.                         DrawBar(c*zoom.value + canvas.x, r*zoom.value + canvas.y,
  587.                                 zoom.value, zoom.value, new_color);
  588.  
  589.                 }
  590.         }
  591. }