diff options
Diffstat (limited to 'editor/plugins/tile_map_editor_plugin.cpp')
| -rw-r--r-- | editor/plugins/tile_map_editor_plugin.cpp | 272 |
1 files changed, 174 insertions, 98 deletions
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index ea133cd749..19646f37b5 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -133,16 +133,14 @@ void TileMapEditor::_menu_option(int p_option) { if (!selection_active) return; - undo_redo->create_action(TTR("Erase Selection")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Erase Selection")); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { - _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false); + _set_cell(Point2i(j, i), invalid_cell, false, false, false); } } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); selection_active = false; copydata.clear(); @@ -188,30 +186,84 @@ void TileMapEditor::_canvas_mouse_exit() { canvas_item_editor->update(); } -int TileMapEditor::get_selected_tile() const { +Vector<int> TileMapEditor::get_selected_tiles() const { + + Vector<int> items = palette->get_selected_items(); + + if (items.size() == 0) { + items.push_back(TileMap::INVALID_CELL); + return items; + } + + for (int i = items.size() - 1; i >= 0; i--) { + items[i] = palette->get_item_metadata(items[i]); + } + return items; +} + +void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) { + + palette->unselect_all(); + + for (int i = p_tiles.size() - 1; i >= 0; i--) { + int idx = palette->find_metadata(p_tiles[i]); + + if (idx >= 0) { + palette->select(idx, false); + } + } + + palette->ensure_current_is_visible(); +} + +void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) { + + Dictionary cell_old; + Dictionary cell_new; + + cell_old["id"] = p_cell_old.idx; + cell_old["flip_h"] = p_cell_old.xf; + cell_old["flip_y"] = p_cell_old.yf; + cell_old["transpose"] = p_cell_old.tr; + cell_old["auto_coord"] = p_cell_old.ac; + + cell_new["id"] = p_cell_new.idx; + cell_new["flip_h"] = p_cell_new.xf; + cell_new["flip_y"] = p_cell_new.yf; + cell_new["transpose"] = p_cell_new.tr; + cell_new["auto_coord"] = p_cell_new.ac; - int item = palette->get_current(); + undo_redo->add_undo_method(node, "set_celld", p_vec, cell_old); + undo_redo->add_do_method(node, "set_celld", p_vec, cell_new); +} - if (item == -1) - return TileMap::INVALID_CELL; +void TileMapEditor::_start_undo(const String &p_action) { - return palette->get_item_metadata(item); + undo_data.clear(); + undo_redo->create_action(p_action); } -void TileMapEditor::set_selected_tile(int p_tile) { +void TileMapEditor::_finish_undo() { - int idx = palette->find_metadata(p_tile); + if (undo_data.size()) { + for (Map<Point2i, CellOp>::Element *E = undo_data.front(); E; E = E->next()) { + _create_set_cell_undo(E->key(), E->get(), _get_op_from_cell(E->key())); + } - if (idx >= 0) { - palette->select(idx, true); - palette->ensure_current_is_visible(); + undo_data.clear(); } + + undo_redo->commit_action(); } -void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose) { +void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h, bool p_flip_v, bool p_transpose) { ERR_FAIL_COND(!node); + if (p_values.size() == 0) + return; + + int p_value = p_values[Math::rand() % p_values.size()]; int prev_val = node->get_cell(p_pos.x, p_pos.y); bool prev_flip_h = node->is_cell_x_flipped(p_pos.x, p_pos.y); @@ -234,6 +286,15 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose && prev_position == position) return; //check that it's actually different + for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { + for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { + Point2i p = Point2i(x, y); + if (!undo_data.has(p)) { + undo_data[p] = _get_op_from_cell(p); + } + } + } + node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose); if (manual_autotile) { if (current != -1) { @@ -292,7 +353,7 @@ void TileMapEditor::_update_palette() { if (!node) return; - int selected = get_selected_tile(); + Vector<int> selected = get_selected_tiles(); palette->clear(); manual_palette->clear(); manual_palette->hide(); @@ -381,14 +442,17 @@ void TileMapEditor::_update_palette() { palette->set_item_metadata(palette->get_item_count() - 1, entries[i].id); } - if (selected != -1) - set_selected_tile(selected); - else + int sel_tile = selected.get(0); + if (selected.get(0) != TileMap::INVALID_CELL) { + set_selected_tiles(selected); + sel_tile = selected.get(Math::rand() % selected.size()); + } else { palette->select(0); + } - if (manual_autotile && tileset->tile_get_tile_mode(get_selected_tile()) == TileSet::AUTO_TILE) { + if (manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) { - const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(get_selected_tile()); + const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile); Vector<Vector2> entries; for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) { @@ -396,7 +460,7 @@ void TileMapEditor::_update_palette() { } entries.sort(); - Ref<Texture> tex = tileset->tile_get_texture(get_selected_tile()); + Ref<Texture> tex = tileset->tile_get_texture(sel_tile); for (int i = 0; i < entries.size(); i++) { @@ -404,9 +468,9 @@ void TileMapEditor::_update_palette() { if (tex.is_valid()) { - Rect2 region = tileset->tile_get_region(get_selected_tile()); - int spacing = tileset->autotile_get_spacing(get_selected_tile()); - region.size = tileset->autotile_get_size(get_selected_tile()); + Rect2 region = tileset->tile_get_region(sel_tile); + int spacing = tileset->autotile_get_spacing(sel_tile); + region.size = tileset->autotile_get_size(sel_tile); // !! region.position += (region.size + Vector2(spacing, spacing)) * entries[i]; if (!region.has_no_area()) @@ -441,7 +505,10 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) { _update_palette(); } - set_selected_tile(id); + Vector<int> selected; + + selected.push_back(id); + set_selected_tiles(selected); mirror_x->set_pressed(node->is_cell_x_flipped(p_pos.x, p_pos.y)); mirror_y->set_pressed(node->is_cell_y_flipped(p_pos.x, p_pos.y)); @@ -454,18 +521,21 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) { PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, bool preview) { int prev_id = node->get_cell(p_start.x, p_start.y); - int id = TileMap::INVALID_CELL; + Vector<int> ids; + ids.push_back(TileMap::INVALID_CELL); if (!erase) { - id = get_selected_tile(); + ids = get_selected_tiles(); - if (id == TileMap::INVALID_CELL) + if (ids.size() == 0 && ids[0] == TileMap::INVALID_CELL) return PoolVector<Vector2>(); } else if (prev_id == TileMap::INVALID_CELL) { return PoolVector<Vector2>(); } - if (id == prev_id) { - return PoolVector<Vector2>(); + for (int i = ids.size() - 1; i >= 0; i--) { + if (ids[i] == prev_id) { + return PoolVector<Vector2>(); + } } Rect2i r = node->_edit_get_rect(); @@ -555,13 +625,13 @@ void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dicti int len = p_points.size(); PoolVector<Vector2>::Read pr = p_points.read(); - int id = p_op["id"]; + Vector<int> ids = p_op["id"]; bool xf = p_op["flip_h"]; bool yf = p_op["flip_v"]; bool tr = p_op["transpose"]; for (int i = 0; i < len; i++) { - _set_cell(pr[i], id, xf, yf, tr); + _set_cell(pr[i], ids, xf, yf, tr); node->make_bitmask_area_dirty(pr[i]); } node->update_dirty_bitmask(); @@ -574,7 +644,7 @@ void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) { for (int i = 0; i < len; i++) { - _set_cell(pr[i], TileMap::INVALID_CELL); + _set_cell(pr[i], invalid_cell); } } @@ -838,14 +908,13 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (tool == TOOL_PAINTING) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id != TileMap::INVALID_CELL) { + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { tool = TOOL_PAINTING; - undo_redo->create_action(TTR("Paint TileMap")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Paint TileMap")); } } else if (tool == TOOL_PICKING) { @@ -864,30 +933,27 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (tool == TOOL_PAINTING) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id != TileMap::INVALID_CELL) { + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { - _set_cell(over_tile, id, flip_h, flip_v, transpose); - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _set_cell(over_tile, ids, flip_h, flip_v, transpose); + _finish_undo(); paint_undo.clear(); } } else if (tool == TOOL_LINE_PAINT) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id != TileMap::INVALID_CELL) { + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { - undo_redo->create_action(TTR("Line Draw")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Line Draw")); for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { - _set_cell(E->key(), id, flip_h, flip_v, transpose); + _set_cell(E->key(), ids, flip_h, flip_v, transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); paint_undo.clear(); @@ -895,35 +961,34 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } } else if (tool == TOOL_RECTANGLE_PAINT) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id != TileMap::INVALID_CELL) { + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { - undo_redo->create_action(TTR("Rectangle Paint")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Rectangle Paint")); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { - _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose); + _set_cell(Point2i(j, i), ids, flip_h, flip_v, transpose); } } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); canvas_item_editor->update(); } } else if (tool == TOOL_DUPLICATING) { Point2 ofs = over_tile - rectangle.position; + Vector<int> ids; - undo_redo->create_action(TTR("Duplicate")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Duplicate")); + ids.push_back(0); for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) { - _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose); + ids[0] = E->get().cell; + _set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); copydata.clear(); @@ -931,21 +996,22 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } else if (tool == TOOL_MOVING) { Point2 ofs = over_tile - rectangle.position; + Vector<int> ids; - undo_redo->create_action(TTR("Move")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Move")); + ids.push_back(TileMap::INVALID_CELL); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { - _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false); + _set_cell(Point2i(j, i), ids, false, false, false); } } for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) { - _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose); + ids[0] = E->get().cell; + _set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); copydata.clear(); selection_active = false; @@ -964,17 +1030,15 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return false; undo_redo->create_action(TTR("Bucket Fill")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); Dictionary op; - op["id"] = get_selected_tile(); + op["id"] = get_selected_tiles(); op["flip_h"] = flip_h; op["flip_v"] = flip_v; op["transpose"] = transpose; _fill_points(points, op); - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); undo_redo->commit_action(); // We want to keep the bucket-tool active @@ -1026,8 +1090,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2 local = node->world_to_map(xform_inv.xform(mb->get_position())); - undo_redo->create_action(TTR("Erase TileMap")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Erase TileMap")); if (mb->get_shift()) { #ifdef APPLE_STYLE_KEYS @@ -1045,7 +1108,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { tool = TOOL_ERASING; - _set_cell(local, TileMap::INVALID_CELL); + _set_cell(local, invalid_cell); } return true; @@ -1054,8 +1117,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } else { if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) { - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) { canvas_item_editor->update(); @@ -1067,8 +1129,10 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } else if (tool == TOOL_BUCKET) { + Vector<int> ids; + ids.push_back(node->get_cell(over_tile.x, over_tile.y)); Dictionary pop; - pop["id"] = node->get_cell(over_tile.x, over_tile.y); + pop["id"] = ids; pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y); pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y); pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y); @@ -1116,7 +1180,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { // Paint using bresenham line to prevent holes in painting if the user moves fast Vector<Point2i> points = line(old_over_tile.x, over_tile.x, old_over_tile.y, over_tile.y); - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); for (int i = 0; i < points.size(); ++i) { @@ -1126,7 +1190,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { paint_undo[pos] = _get_op_from_cell(pos); } - _set_cell(pos, id, flip_h, flip_v, transpose); + _set_cell(pos, ids, flip_h, flip_v, transpose); } return true; @@ -1142,7 +1206,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2i pos = points[i]; - _set_cell(pos, TileMap::INVALID_CELL); + _set_cell(pos, invalid_cell); } return true; @@ -1157,20 +1221,23 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (tool == TOOL_LINE_PAINT || tool == TOOL_LINE_ERASE) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); + Vector<int> tmp_cell; bool erasing = (tool == TOOL_LINE_ERASE); + tmp_cell.push_back(0); if (erasing && paint_undo.size()) { for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { - _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); + tmp_cell[0] = E->get().idx; + _set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr); } } paint_undo.clear(); - if (id != TileMap::INVALID_CELL) { + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y); @@ -1179,7 +1246,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { paint_undo[points[i]] = _get_op_from_cell(points[i]); if (erasing) - _set_cell(points[i], TileMap::INVALID_CELL); + _set_cell(points[i], invalid_cell); } canvas_item_editor->update(); @@ -1189,6 +1256,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } if (tool == TOOL_RECTANGLE_PAINT || tool == TOOL_RECTANGLE_ERASE) { + Vector<int> tmp_cell; + tmp_cell.push_back(0); + _select(rectangle_begin, over_tile); if (tool == TOOL_RECTANGLE_ERASE) { @@ -1197,7 +1267,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { - _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); + tmp_cell[0] = E->get().idx; + _set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr); } } @@ -1209,7 +1280,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2i tile = Point2i(j, i); paint_undo[tile] = _get_op_from_cell(tile); - _set_cell(tile, TileMap::INVALID_CELL); + _set_cell(tile, invalid_cell); } } } @@ -1466,27 +1537,27 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { if (paint_undo.empty()) return; - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id == TileMap::INVALID_CELL) + if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL) return; for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { - _draw_cell(id, E->key(), flip_h, flip_v, transpose, xform); + _draw_cell(ids[0], E->key(), flip_h, flip_v, transpose, xform); } } else if (tool == TOOL_RECTANGLE_PAINT) { - int id = get_selected_tile(); + Vector<int> ids = get_selected_tiles(); - if (id == TileMap::INVALID_CELL) + if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL) return; for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { - _draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform); + _draw_cell(ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform); } } } else if (tool == TOOL_DUPLICATING || tool == TOOL_MOVING) { @@ -1524,17 +1595,17 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { } else if (tool == TOOL_BUCKET) { - int tile = get_selected_tile(); - _draw_fill_preview(tile, over_tile, flip_h, flip_v, transpose, xform); + Vector<int> tiles = get_selected_tiles(); + _draw_fill_preview(tiles[0], over_tile, flip_h, flip_v, transpose, xform); } else { - int st = get_selected_tile(); + Vector<int> st = get_selected_tiles(); - if (st == TileMap::INVALID_CELL) + if (st.size() == 1 && st[0] == TileMap::INVALID_CELL) return; - _draw_cell(st, over_tile, flip_h, flip_v, transpose, xform); + _draw_cell(st[0], over_tile, flip_h, flip_v, transpose, xform); } } } @@ -1621,6 +1692,7 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i &p_pos) { op.yf = true; if (node->is_cell_transposed(p_pos.x, p_pos.y)) op.tr = true; + op.ac = node->get_cell_autotile_coord(p_pos.x, p_pos.y); } return op; } @@ -1679,6 +1751,9 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { bucket_cache_tile = -1; bucket_cache_visited = 0; + invalid_cell.resize(1); + invalid_cell[0] = TileMap::INVALID_CELL; + ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE); ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F); ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T); @@ -1725,6 +1800,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { palette->set_max_columns(0); palette->set_icon_mode(ItemList::ICON_MODE_TOP); palette->set_max_text_lines(2); + palette->set_select_mode(ItemList::SELECT_MULTI); palette->connect("item_selected", this, "_palette_selected"); palette_container->add_child(palette); |
