Subversion Repositories Kolibri OS

Rev

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