static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool, const size_t tool_offset, const int ob_mode, const char *tool_name, int create_missing, int toggle) { Brush *brush, *brush_orig = BKE_paint_brush(paint); if (toggle) brush = brush_tool_toggle(bmain, brush_orig, tool, tool_offset, ob_mode); else brush = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode); if (!brush && brush_tool(brush_orig, tool_offset) != tool && create_missing) { brush = BKE_brush_add(bmain, tool_name); brush_tool_set(brush, tool_offset, tool); brush->ob_mode = ob_mode; brush->toggle_brush = brush_orig; } if (brush) { BKE_paint_brush_set(paint, brush); BKE_paint_invalidate_overlay_all(); WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
/* generic functions for setting the active brush based on the tool */ static Brush *brush_tool_cycle(Main *bmain, Brush *brush_orig, const int tool, const size_t tool_offset, const int ob_mode) { Brush *brush, *first_brush; if (!brush_orig && !(brush_orig = bmain->brush.first)) { return NULL; } if (brush_tool(brush_orig, tool_offset) != tool) { /* If current brush's tool is different from what we need, * start cycling from the beginning of the list. * Such logic will activate the same exact brush not relating from * which tool user requests other tool. */ first_brush = bmain->brush.first; } else { /* If user wants to switch to brush with the same tool as * currently active brush do a cycling via all possible * brushes with requested tool. */ first_brush = brush_orig->id.next ? brush_orig->id.next : bmain->brush.first; } /* get the next brush with the active tool */ brush = first_brush; do { if ((brush->ob_mode & ob_mode) && (brush_tool(brush, tool_offset) == tool)) { return brush; } brush = brush->id.next ? brush->id.next : bmain->brush.first; } while (brush != first_brush); return NULL; }
static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool, const size_t tool_offset, const int ob_mode) { if (!brush_orig || brush_tool(brush_orig, tool_offset) != tool) { Brush *br; /* if the current brush is not using the desired tool, look * for one that is */ br = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode); /* store the previously-selected brush */ if (br) br->toggle_brush = brush_orig; return br; } else if (brush_orig->toggle_brush) { /* if current brush is using the desired tool, try to toggle * back to the previously selected brush. */ return brush_orig->toggle_brush; } else return NULL; }
/* generic functions for setting the active brush based on the tool */ static Brush *brush_tool_cycle(Main *bmain, Brush *brush_orig, const int tool, const size_t tool_offset, const int ob_mode) { struct Brush *brush; if (!brush_orig && !(brush_orig = bmain->brush.first)) { return NULL; } /* get the next brush with the active tool */ for (brush = brush_orig->id.next ? brush_orig->id.next : bmain->brush.first; brush != brush_orig; brush = brush->id.next ? brush->id.next : bmain->brush.first) { if ((brush->ob_mode & ob_mode) && (brush_tool(brush, tool_offset) == tool)) { return brush; } } return NULL; }