diff --git a/docs/ux/mockups/gen_offer_table.py b/docs/ux/mockups/gen_offer_table.py index ebb847a4ed..92b19e5bfa 100644 --- a/docs/ux/mockups/gen_offer_table.py +++ b/docs/ux/mockups/gen_offer_table.py @@ -92,6 +92,7 @@ def main(): " // address fixed (L4.1) while the variants hang one level below it, mirroring the toolbar's", " // grouping instead of flattening 19 create tools into one wall.", " const char* family;", + " const char* icon; // resources/images name, or nullptr — the offer draws it beside the row", "};", "", "// Row labels, in ratified order.", @@ -111,13 +112,13 @@ def main(): mask |= 1 << sels.index(a) n = v.get("needs") or {} lines.append( - " {%s, %s, %d, %s, %s, %s, 0x%08xu, %d, %d, %s, %s, %s}," % ( + " {%s, %s, %d, %s, %s, %s, 0x%08xu, %d, %d, %s, %s, %s, %s}," % ( cstr(v["id"]), cstr(v["name"]), slots.index(v["slot"]), cstr(v.get("key")), cstr(v.get("action")), cstr(v.get("refusal")), mask, n.get("bodies", 0), n.get("sketches", 0), "true" if n.get("sheet") else "false", "true" if v.get("mode") == "sketch" else "false", - cstr(v.get("family")))) + cstr(v.get("family")), cstr(v.get("icon")))) lines += [ "};", f"static const int kOfferVerbCount = {len(A['verbs'])};", diff --git a/docs/ux/tool_atlas.json b/docs/ux/tool_atlas.json index 36ecd479ad..e2d9860eb0 100644 --- a/docs/ux/tool_atlas.json +++ b/docs/ux/tool_atlas.json @@ -225,7 +225,8 @@ "needs": {}, "refusal": "Click a face or a reference plane in the viewport, then a sketch tool", "gui": true, - "action": "key:S+S" + "action": "key:S+S", + "icon": "design_sketch" }, { "id": "extrude", @@ -241,7 +242,8 @@ "needs": {}, "refusal": "Create a sketch, or pick a solid face, first", "gui": true, - "action": "key:S+E" + "action": "key:S+E", + "icon": "design_extrude" }, { "id": "revolve", @@ -256,7 +258,8 @@ "needs": {}, "refusal": "Create a sketch profile to revolve first", "gui": true, - "action": "key:S+R" + "action": "key:S+R", + "icon": "design_revolve" }, { "id": "sweep", @@ -273,7 +276,8 @@ }, "refusal": "Create a profile sketch to sweep first", "gui": true, - "action": "key:S+W" + "action": "key:S+W", + "icon": "design_sweep" }, { "id": "loft", @@ -290,7 +294,8 @@ }, "refusal": "Create at least two profile sketches to loft", "gui": true, - "action": "key:S+L" + "action": "key:S+L", + "icon": "design_loft" }, { "id": "thicken", @@ -308,7 +313,8 @@ }, "refusal": "Thicken needs a solid body — add or import one first", "gui": true, - "action": "fly:material#4" + "action": "fly:material#4", + "icon": "design_thicken" }, { "id": "rib", @@ -325,7 +331,8 @@ }, "refusal": "Rib needs a solid body — add or import one first", "gui": true, - "action": "fly:material#5" + "action": "fly:material#5", + "icon": "design_rib" }, { "id": "boolean", @@ -342,7 +349,8 @@ }, "refusal": "Boolean needs two bodies — create or import a second solid", "gui": true, - "action": "btn:bool#0" + "action": "btn:bool#0", + "icon": "design_boolean" }, { "id": "bool_subtract", @@ -360,7 +368,8 @@ "refusal": "Boolean needs two bodies — create or import a second solid", "gui": true, "action": "btn:bool#1", - "mode": null + "mode": null, + "icon": "design_boolean" }, { "id": "bool_intersect", @@ -378,7 +387,8 @@ "refusal": "Boolean needs two bodies — create or import a second solid", "gui": true, "action": "btn:bool#2", - "mode": null + "mode": null, + "icon": "design_boolean" }, { "id": "surf_extrude", @@ -393,7 +403,8 @@ "needs": {}, "refusal": "Create a sketch first", "gui": true, - "action": "key:S+G" + "action": "key:S+G", + "icon": "design_extrude" }, { "id": "surf_revolve", @@ -408,7 +419,8 @@ "needs": {}, "refusal": "Create a sketch profile to revolve first", "gui": true, - "action": "fly:surface#1" + "action": "fly:surface#1", + "icon": "design_revolve" }, { "id": "surf_loft", @@ -425,7 +437,8 @@ }, "refusal": "Create at least two profile sketches to loft", "gui": true, - "action": "fly:surface#2" + "action": "fly:surface#2", + "icon": "design_loft" }, { "id": "surf_fill", @@ -440,7 +453,8 @@ "needs": {}, "refusal": "Create a closed sketch first", "gui": true, - "action": "fly:surface#3" + "action": "fly:surface#3", + "icon": "design_surface" }, { "id": "thicken_surf", @@ -457,7 +471,8 @@ }, "refusal": "target is not a sheet body", "gui": true, - "action": "fly:surface#5" + "action": "fly:surface#5", + "icon": "design_thicken" }, { "id": "hole", @@ -475,7 +490,8 @@ }, "refusal": "Pick a face or a plane to drill into", "gui": true, - "action": "key:S+H" + "action": "key:S+H", + "icon": "design_hole" }, { "id": "thread", @@ -493,7 +509,8 @@ }, "refusal": "Pick a cylindrical surface (bore / outer) or a circular edge for a thread", "gui": true, - "action": "key:S+T" + "action": "key:S+T", + "icon": "design_thread" }, { "id": "shell", @@ -511,7 +528,8 @@ }, "refusal": "Shell needs a solid body", "gui": true, - "action": "key:S+K" + "action": "key:S+K", + "icon": "design_shell" }, { "id": "cut", @@ -529,7 +547,8 @@ }, "refusal": "Create a solid body to cut first", "gui": true, - "action": "key:S+X" + "action": "key:S+X", + "icon": "design_cut" }, { "id": "split", @@ -546,7 +565,8 @@ }, "refusal": "Split needs a solid body", "gui": false, - "action": null + "action": null, + "icon": null }, { "id": "fillet", @@ -566,7 +586,8 @@ }, "refusal": "Pick an edge to round", "gui": true, - "action": "btn:dress#0" + "action": "btn:dress#0", + "icon": "design_filletedge" }, { "id": "chamfer", @@ -586,7 +607,8 @@ }, "refusal": "Pick an edge to bevel", "gui": true, - "action": "btn:dress#1" + "action": "btn:dress#1", + "icon": "design_chamfer" }, { "id": "draft", @@ -604,7 +626,8 @@ }, "refusal": "Pick a face to taper", "gui": true, - "action": "key:S+D" + "action": "key:S+D", + "icon": "design_draft" }, { "id": "surf_offset", @@ -621,7 +644,8 @@ }, "refusal": "target is not a sheet body", "gui": true, - "action": "fly:surface#4" + "action": "fly:surface#4", + "icon": "design_offset" }, { "id": "pattern", @@ -641,7 +665,8 @@ }, "refusal": "Create a solid body to pattern first", "gui": true, - "action": "btn:pat#0" + "action": "btn:pat#0", + "icon": "design_array" }, { "id": "pattern_circular", @@ -662,7 +687,8 @@ "refusal": "Create a solid body to pattern first", "gui": true, "action": "btn:pat#1", - "mode": null + "mode": null, + "icon": "design_polararray" }, { "id": "mirror", @@ -680,7 +706,8 @@ }, "refusal": "Mirror needs a body — add or import one first", "gui": true, - "action": "key:S+Z" + "action": "key:S+Z", + "icon": "design_mirror" }, { "id": "pat_curve", @@ -698,7 +725,8 @@ }, "refusal": "Pattern on curve needs a body and a curve", "gui": false, - "action": null + "action": null, + "icon": null }, { "id": "transform", @@ -717,7 +745,8 @@ }, "refusal": "Transform needs a body — add or import one first", "gui": true, - "action": "key:S+Y" + "action": "key:S+Y", + "icon": "design_move" }, { "id": "mate", @@ -736,7 +765,8 @@ }, "refusal": "A mate needs two coordinate systems", "gui": true, - "action": "fly:placement#2" + "action": "fly:placement#2", + "icon": "design_c_coincident" }, { "id": "align", @@ -753,7 +783,8 @@ }, "refusal": "Align needs a body", "gui": false, - "action": null + "action": null, + "icon": null }, { "id": "plane", @@ -772,7 +803,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:S+P" + "action": "key:S+P", + "icon": "design_plane" }, { "id": "axis", @@ -791,7 +823,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:S+A" + "action": "key:S+A", + "icon": "design_line" }, { "id": "coordsys_v", @@ -808,7 +841,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:S+C" + "action": "key:S+C", + "icon": "design_point" }, { "id": "helix", @@ -825,7 +859,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "fly:plane#3" + "action": "fly:plane#3", + "icon": "design_thread" }, { "id": "project", @@ -844,7 +879,8 @@ }, "refusal": "Project needs a body — add or import one first", "gui": true, - "action": "fly:plane#4" + "action": "fly:plane#4", + "icon": "design_sketch" }, { "id": "measure", @@ -870,7 +906,8 @@ "needs": {}, "refusal": null, "gui": false, - "action": null + "action": null, + "icon": null }, { "id": "mass_props", @@ -887,7 +924,8 @@ }, "refusal": null, "gui": true, - "action": "btn:mass" + "action": "btn:mass", + "icon": "info" }, { "id": "interference", @@ -904,7 +942,8 @@ }, "refusal": null, "gui": false, - "action": null + "action": null, + "icon": null }, { "id": "edit_feature", @@ -928,7 +967,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "btn:edit" + "action": "btn:edit", + "icon": "design_edit" }, { "id": "delete_face", @@ -947,7 +987,8 @@ }, "refusal": "Delete Face needs a body — add or import one first", "gui": true, - "action": "fly:dressup#3" + "action": "fly:dressup#3", + "icon": "design_delete" }, { "id": "colour", @@ -965,7 +1006,8 @@ }, "refusal": null, "gui": true, - "action": "btn:colour" + "action": "btn:colour", + "icon": "color_palette" }, { "id": "delete", @@ -991,7 +1033,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "btn:delete" + "action": "btn:delete", + "icon": "design_delete" }, { "id": "sk_line_t", @@ -1012,7 +1055,8 @@ "refusal": null, "gui": true, "action": "key:L", - "family": "Line" + "family": "Line", + "icon": "design_line" }, { "id": "sk_polyline", @@ -1033,7 +1077,8 @@ "gui": true, "action": "fly:design_line#1", "mode": "sketch", - "family": "Line" + "family": "Line", + "icon": "design_polyline" }, { "id": "sk_rect", @@ -1054,7 +1099,8 @@ "refusal": null, "gui": true, "action": "key:R", - "family": "Rectangle" + "family": "Rectangle", + "icon": "design_rect" }, { "id": "sk_rect_center", @@ -1075,7 +1121,8 @@ "gui": true, "action": "fly:design_rect#1", "mode": "sketch", - "family": "Rectangle" + "family": "Rectangle", + "icon": "design_crect" }, { "id": "sk_rect_oblique", @@ -1096,7 +1143,8 @@ "gui": true, "action": "fly:design_rect#2", "mode": "sketch", - "family": "Rectangle" + "family": "Rectangle", + "icon": "design_rect_oblique" }, { "id": "sk_rect_rounded", @@ -1117,7 +1165,8 @@ "gui": true, "action": "fly:design_rect#3", "mode": "sketch", - "family": "Rectangle" + "family": "Rectangle", + "icon": "design_rect_rounded" }, { "id": "sk_circle", @@ -1138,7 +1187,8 @@ "refusal": null, "gui": true, "action": "key:C", - "family": "Circle" + "family": "Circle", + "icon": "design_circle" }, { "id": "sk_circle_2pt", @@ -1159,7 +1209,8 @@ "gui": true, "action": "fly:design_circle#1", "mode": "sketch", - "family": "Circle" + "family": "Circle", + "icon": "design_circle2pt" }, { "id": "sk_circle_3pt", @@ -1180,7 +1231,8 @@ "gui": true, "action": "fly:design_circle#2", "mode": "sketch", - "family": "Circle" + "family": "Circle", + "icon": "design_circle3pt" }, { "id": "sk_arc_t", @@ -1201,7 +1253,8 @@ "refusal": null, "gui": true, "action": "key:A", - "family": "Arc" + "family": "Arc", + "icon": "design_arc3pt" }, { "id": "sk_arc_tangent", @@ -1222,7 +1275,8 @@ "gui": true, "action": "fly:design_arc3pt#1", "mode": "sketch", - "family": "Arc" + "family": "Arc", + "icon": "design_tangentarc" }, { "id": "sk_arc_center", @@ -1243,7 +1297,8 @@ "gui": true, "action": "fly:design_arc3pt#2", "mode": "sketch", - "family": "Arc" + "family": "Arc", + "icon": "design_arc_center" }, { "id": "sk_slot", @@ -1264,7 +1319,8 @@ "refusal": null, "gui": true, "action": "key:S", - "family": "Slot" + "family": "Slot", + "icon": "design_slot" }, { "id": "sk_slot_arc", @@ -1285,7 +1341,8 @@ "gui": true, "action": "fly:design_slot#1", "mode": "sketch", - "family": "Slot" + "family": "Slot", + "icon": "design_slot_arc" }, { "id": "sk_ellipse", @@ -1306,7 +1363,8 @@ "refusal": null, "gui": true, "action": "key:E", - "family": "Ellipse" + "family": "Ellipse", + "icon": "design_ellipse" }, { "id": "sk_ellipse_arc", @@ -1327,7 +1385,8 @@ "gui": true, "action": "fly:design_ellipse#1", "mode": "sketch", - "family": "Ellipse" + "family": "Ellipse", + "icon": "design_ellipse_arc" }, { "id": "sk_spline", @@ -1347,7 +1406,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:B" + "action": "key:B", + "icon": "design_bspline" }, { "id": "sk_poly_3", @@ -1368,7 +1428,8 @@ "gui": true, "action": "btn:poly#3", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_4", @@ -1389,7 +1450,8 @@ "gui": true, "action": "btn:poly#4", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_5", @@ -1410,7 +1472,8 @@ "gui": true, "action": "btn:poly#5", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_polygon", @@ -1431,7 +1494,8 @@ "refusal": null, "gui": true, "action": "btn:poly#6", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_8", @@ -1452,7 +1516,8 @@ "gui": true, "action": "btn:poly#8", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_12", @@ -1473,7 +1538,8 @@ "gui": true, "action": "btn:poly#12", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_inscribed", @@ -1494,7 +1560,8 @@ "gui": true, "action": "btn:polyfit#0", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_poly_circumscribed", @@ -1515,7 +1582,8 @@ "gui": true, "action": "btn:polyfit#1", "mode": "sketch", - "family": "Polygon" + "family": "Polygon", + "icon": "design_polygon" }, { "id": "sk_point_t", @@ -1535,7 +1603,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:P" + "action": "key:P", + "icon": "design_point" }, { "id": "sk_text", @@ -1555,7 +1624,8 @@ "refusal": null, "gui": true, "action": "btn:text", - "mode": "sketch" + "mode": "sketch", + "icon": "design_text" }, { "id": "sk_svg", @@ -1575,7 +1645,8 @@ "refusal": null, "gui": true, "action": "btn:svg", - "mode": "sketch" + "mode": "sketch", + "icon": "design_svg" }, { "id": "sk_offset", @@ -1593,7 +1664,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:O" + "action": "key:O", + "icon": "design_offset" }, { "id": "sk_trim", @@ -1611,7 +1683,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:T" + "action": "key:T", + "icon": "design_trim" }, { "id": "sk_fillet", @@ -1628,7 +1701,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:F" + "action": "key:F", + "icon": "design_filletedge" }, { "id": "sk_chamfer", @@ -1645,7 +1719,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:H" + "action": "key:H", + "icon": "design_chamfer" }, { "id": "sk_array", @@ -1664,7 +1739,8 @@ "gui": true, "action": "fly:design_array#0", "mode": "sketch", - "family": "Array" + "family": "Array", + "icon": "design_array" }, { "id": "sk_array_polar", @@ -1683,7 +1759,8 @@ "gui": true, "action": "fly:design_array#1", "mode": "sketch", - "family": "Array" + "family": "Array", + "icon": "design_polararray" }, { "id": "sk_mirror", @@ -1701,7 +1778,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:M" + "action": "key:M", + "icon": "design_mirror" }, { "id": "sk_move", @@ -1721,7 +1799,8 @@ "refusal": null, "gui": true, "action": "fly:design_move#0", - "family": "Move" + "family": "Move", + "icon": "design_move" }, { "id": "sk_rotate", @@ -1741,7 +1820,8 @@ "gui": true, "action": "fly:design_move#1", "mode": "sketch", - "family": "Move" + "family": "Move", + "icon": "design_rotate" }, { "id": "sk_scale", @@ -1761,7 +1841,8 @@ "gui": true, "action": "fly:design_move#2", "mode": "sketch", - "family": "Move" + "family": "Move", + "icon": "design_scale" }, { "id": "sk_dimension", @@ -1781,7 +1862,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:D" + "action": "key:D", + "icon": "design_dimension" }, { "id": "sk_constrain", @@ -1800,7 +1882,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:K" + "action": "key:K", + "icon": "design_constrain" }, { "id": "sk_construct", @@ -1819,7 +1902,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:Q" + "action": "key:Q", + "icon": null }, { "id": "sk_extend", @@ -1837,7 +1921,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "key:X" + "action": "key:X", + "icon": "design_extend" }, { "id": "sk_delete", @@ -1856,7 +1941,8 @@ "needs": {}, "refusal": null, "gui": true, - "action": "btn:delete" + "action": "btn:delete", + "icon": "design_delete" } ], "chrome_only": { diff --git a/src/slic3r/GUI/DesignOffer.hpp b/src/slic3r/GUI/DesignOffer.hpp index 875b87c9c7..d3721cbca3 100644 --- a/src/slic3r/GUI/DesignOffer.hpp +++ b/src/slic3r/GUI/DesignOffer.hpp @@ -63,6 +63,7 @@ struct OfferVerb { // address fixed (L4.1) while the variants hang one level below it, mirroring the toolbar's // grouping instead of flattening 19 create tools into one wall. const char* family; + const char* icon; // resources/images name, or nullptr — the offer draws it beside the row }; // Row labels, in ratified order. @@ -79,92 +80,92 @@ static const char* const kOfferRowNames[] = { static const int kOfferRowCount = 8; static const OfferVerb kOfferVerbs[] = { - {"sketch", "Sketch", 0, "Shift+S", "key:S+S", "Click a face or a reference plane in the viewport, then a sketch tool", 0x00000403u, 0, 0, false, false, nullptr}, - {"extrude", "Extrude", 1, "Shift+E", "key:S+E", "Create a sketch, or pick a solid face, first", 0x00004002u, 0, 0, false, false, nullptr}, - {"revolve", "Revolve", 1, "Shift+R", "key:S+R", "Create a sketch profile to revolve first", 0x00004000u, 0, 0, false, false, nullptr}, - {"sweep", "Sweep", 1, "Shift+W", "key:S+W", "Create a profile sketch to sweep first", 0x00004000u, 0, 2, false, false, nullptr}, - {"loft", "Loft", 1, "Shift+L", "key:S+L", "Create at least two profile sketches to loft", 0x00004000u, 0, 2, false, false, nullptr}, - {"thicken", "Thicken", 1, nullptr, "fly:material#4", "Thicken needs a solid body — add or import one first", 0x0000000au, 1, 0, false, false, nullptr}, - {"rib", "Rib", 1, nullptr, "fly:material#5", "Rib needs a solid body — add or import one first", 0x00010000u, 1, 0, false, false, nullptr}, - {"boolean", "Union", 1, "Shift+B", "btn:bool#0", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr}, - {"bool_subtract", "Subtract", 1, nullptr, "btn:bool#1", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr}, - {"bool_intersect", "Intersect", 1, nullptr, "btn:bool#2", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr}, - {"surf_extrude", "Surface Extrude", 1, "Shift+G", "key:S+G", "Create a sketch first", 0x00004000u, 0, 0, false, false, nullptr}, - {"surf_revolve", "Surface Revolve", 1, nullptr, "fly:surface#1", "Create a sketch profile to revolve first", 0x00004000u, 0, 0, false, false, nullptr}, - {"surf_loft", "Surface Loft", 1, nullptr, "fly:surface#2", "Create at least two profile sketches to loft", 0x00004000u, 0, 2, false, false, nullptr}, - {"surf_fill", "Surface Fill", 1, nullptr, "fly:surface#3", "Create a closed sketch first", 0x00004000u, 0, 0, false, false, nullptr}, - {"thicken_surf", "Thicken Surface", 1, nullptr, "fly:surface#5", "target is not a sheet body", 0x00000100u, 0, 0, true, false, nullptr}, - {"hole", "Hole", 2, "Shift+H", "key:S+H", "Pick a face or a plane to drill into", 0x00000402u, 1, 0, false, false, nullptr}, - {"thread", "Thread", 2, "Shift+T", "key:S+T", "Pick a cylindrical surface (bore / outer) or a circular edge for a thread", 0x00000024u, 1, 0, false, false, nullptr}, - {"shell", "Shell", 2, "Shift+K", "key:S+K", "Shell needs a solid body", 0x00000082u, 1, 0, false, false, nullptr}, - {"cut", "Cut", 2, "Shift+X", "key:S+X", "Create a solid body to cut first", 0x00000480u, 1, 0, false, false, nullptr}, - {"split", "Split", 2, nullptr, nullptr, "Split needs a solid body", 0x00000080u, 1, 0, false, false, nullptr}, - {"fillet", "Fillet", 3, "Shift+F", "btn:dress#0", "Pick an edge to round", 0x000000b2u, 1, 0, false, false, nullptr}, - {"chamfer", "Chamfer", 3, nullptr, "btn:dress#1", "Pick an edge to bevel", 0x000000b2u, 1, 0, false, false, nullptr}, - {"draft", "Draft", 3, "Shift+D", "key:S+D", "Pick a face to taper", 0x0000000au, 1, 0, false, false, nullptr}, - {"surf_offset", "Surface Offset", 3, nullptr, "fly:surface#4", "target is not a sheet body", 0x00000100u, 0, 0, true, false, nullptr}, - {"pattern", "Linear pattern", 4, "Shift+N", "btn:pat#0", "Create a solid body to pattern first", 0x00006082u, 1, 0, false, false, nullptr}, - {"pattern_circular", "Circular pattern", 4, nullptr, "btn:pat#1", "Create a solid body to pattern first", 0x00006082u, 1, 0, false, false, nullptr}, - {"mirror", "Mirror", 4, "Shift+Z", "key:S+Z", "Mirror needs a body — add or import one first", 0x00000480u, 1, 0, false, false, nullptr}, - {"pat_curve", "Pattern on Curve", 4, nullptr, nullptr, "Pattern on curve needs a body and a curve", 0x00000090u, 1, 0, false, false, nullptr}, - {"transform", "Move", 5, "Shift+Y", "key:S+Y", "Transform needs a body — add or import one first", 0x00002180u, 1, 0, false, false, nullptr}, - {"mate", "Mate", 5, nullptr, "fly:placement#2", "A mate needs two coordinate systems", 0x00001202u, 2, 0, false, false, nullptr}, - {"align", "Align to", 5, nullptr, nullptr, "Align needs a body", 0x00000002u, 1, 0, false, false, nullptr}, - {"plane", "Plane", 6, "Shift+P", "key:S+P", nullptr, 0x00000453u, 0, 0, false, false, nullptr}, - {"axis", "Axis", 6, "Shift+A", "key:S+A", nullptr, 0x00000057u, 0, 0, false, false, nullptr}, - {"coordsys_v", "Coord Sys", 6, "Shift+C", "key:S+C", nullptr, 0x00000043u, 0, 0, false, false, nullptr}, - {"helix", "Helix", 6, nullptr, "fly:plane#3", nullptr, 0x00000405u, 0, 0, false, false, nullptr}, - {"project", "Project", 6, nullptr, "fly:plane#4", "Project needs a body — add or import one first", 0x00000482u, 1, 0, false, false, nullptr}, - {"measure", "Measure", 6, nullptr, nullptr, nullptr, 0x000b03feu, 0, 0, false, false, nullptr}, - {"mass_props", "Mass", 6, nullptr, "btn:mass", nullptr, 0x00000080u, 1, 0, false, false, nullptr}, - {"interference", "Interference", 6, nullptr, nullptr, nullptr, 0x00000200u, 2, 0, false, false, nullptr}, - {"edit_feature", "Edit", 7, nullptr, "btn:edit", nullptr, 0x00007d8eu, 0, 0, false, false, nullptr}, - {"delete_face", "Delete Face", 7, nullptr, "fly:dressup#3", "Delete Face needs a body — add or import one first", 0x0000000eu, 1, 0, false, false, nullptr}, - {"colour", "Colour", 7, nullptr, "btn:colour", nullptr, 0x00000180u, 1, 0, false, false, nullptr}, - {"delete", "Delete", 7, "Del", "btn:delete", nullptr, 0x000f7f80u, 0, 0, false, false, nullptr}, - {"sk_line_t", "Line", 0, "L", "key:L", nullptr, 0x000f8000u, 0, 0, false, true, "Line"}, - {"sk_polyline", "Polyline", 0, nullptr, "fly:design_line#1", nullptr, 0x000f8000u, 0, 0, false, true, "Line"}, - {"sk_rect", "Corner rectangle", 0, "R", "key:R", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle"}, - {"sk_rect_center", "Centre rectangle", 0, nullptr, "fly:design_rect#1", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle"}, - {"sk_rect_oblique", "Oblique rectangle", 0, nullptr, "fly:design_rect#2", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle"}, - {"sk_rect_rounded", "Rounded rectangle", 0, nullptr, "fly:design_rect#3", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle"}, - {"sk_circle", "Centre circle", 0, "C", "key:C", nullptr, 0x000f8000u, 0, 0, false, true, "Circle"}, - {"sk_circle_2pt", "2-point circle", 0, nullptr, "fly:design_circle#1", nullptr, 0x000f8000u, 0, 0, false, true, "Circle"}, - {"sk_circle_3pt", "3-point circle", 0, nullptr, "fly:design_circle#2", nullptr, 0x000f8000u, 0, 0, false, true, "Circle"}, - {"sk_arc_t", "3-point arc", 0, "A", "key:A", nullptr, 0x000f8000u, 0, 0, false, true, "Arc"}, - {"sk_arc_tangent", "Tangent arc", 0, nullptr, "fly:design_arc3pt#1", nullptr, 0x000f8000u, 0, 0, false, true, "Arc"}, - {"sk_arc_center", "Centre-point arc", 0, nullptr, "fly:design_arc3pt#2", nullptr, 0x000f8000u, 0, 0, false, true, "Arc"}, - {"sk_slot", "Slot", 0, "S", "key:S", nullptr, 0x000f8000u, 0, 0, false, true, "Slot"}, - {"sk_slot_arc", "Arc slot", 0, nullptr, "fly:design_slot#1", nullptr, 0x000f8000u, 0, 0, false, true, "Slot"}, - {"sk_ellipse", "Ellipse", 0, "E", "key:E", nullptr, 0x000f8000u, 0, 0, false, true, "Ellipse"}, - {"sk_ellipse_arc", "Elliptical arc", 0, nullptr, "fly:design_ellipse#1", nullptr, 0x000f8000u, 0, 0, false, true, "Ellipse"}, - {"sk_spline", "Spline", 0, "B", "key:B", nullptr, 0x000f8000u, 0, 0, false, true, nullptr}, - {"sk_poly_3", "Triangle", 0, nullptr, "btn:poly#3", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_4", "Square", 0, nullptr, "btn:poly#4", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_5", "Pentagon", 0, nullptr, "btn:poly#5", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_polygon", "Hexagon", 0, "G", "btn:poly#6", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_8", "Octagon", 0, nullptr, "btn:poly#8", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_12", "Dodecagon", 0, nullptr, "btn:poly#12", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_inscribed", "Inscribed", 0, nullptr, "btn:polyfit#0", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_poly_circumscribed", "Circumscribed", 0, nullptr, "btn:polyfit#1", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon"}, - {"sk_point_t", "Point", 0, "P", "key:P", nullptr, 0x000f8000u, 0, 0, false, true, nullptr}, - {"sk_text", "Text", 0, nullptr, "btn:text", nullptr, 0x000f8000u, 0, 0, false, true, nullptr}, - {"sk_svg", "SVG", 0, nullptr, "btn:svg", nullptr, 0x000f8000u, 0, 0, false, true, nullptr}, - {"sk_offset", "Offset", 1, "O", "key:O", nullptr, 0x000b0000u, 0, 0, false, true, nullptr}, - {"sk_trim", "Trim", 2, "T", "key:T", nullptr, 0x000b0000u, 0, 0, false, true, nullptr}, - {"sk_fillet", "Fillet", 3, "F", "key:F", nullptr, 0x00090000u, 0, 0, false, true, nullptr}, - {"sk_chamfer", "Chamfer", 3, "H", "key:H", nullptr, 0x00090000u, 0, 0, false, true, nullptr}, - {"sk_array", "Linear array", 4, nullptr, "fly:design_array#0", nullptr, 0x000b0000u, 0, 0, false, true, "Array"}, - {"sk_array_polar", "Polar array", 4, nullptr, "fly:design_array#1", nullptr, 0x000b0000u, 0, 0, false, true, "Array"}, - {"sk_mirror", "Mirror", 4, "M", "key:M", nullptr, 0x000b0000u, 0, 0, false, true, nullptr}, - {"sk_move", "Move", 5, nullptr, "fly:design_move#0", nullptr, 0x000f0000u, 0, 0, false, true, "Move"}, - {"sk_rotate", "Rotate", 5, nullptr, "fly:design_move#1", nullptr, 0x000f0000u, 0, 0, false, true, "Move"}, - {"sk_scale", "Scale", 5, nullptr, "fly:design_move#2", nullptr, 0x000f0000u, 0, 0, false, true, "Move"}, - {"sk_dimension", "Dimension", 6, "D", "key:D", nullptr, 0x000f8000u, 0, 0, false, true, nullptr}, - {"sk_constrain", "Constrain", 6, "K", "key:K", nullptr, 0x000f0000u, 0, 0, false, true, nullptr}, - {"sk_construct", "Construction", 6, "Q", "key:Q", nullptr, 0x000b8000u, 0, 0, false, true, nullptr}, - {"sk_extend", "Extend", 7, "X", "key:X", nullptr, 0x000b0000u, 0, 0, false, true, nullptr}, - {"sk_delete", "Delete", 7, "Del", "btn:delete", nullptr, 0x000f0000u, 0, 0, false, true, nullptr}, + {"sketch", "Sketch", 0, "Shift+S", "key:S+S", "Click a face or a reference plane in the viewport, then a sketch tool", 0x00000403u, 0, 0, false, false, nullptr, "design_sketch"}, + {"extrude", "Extrude", 1, "Shift+E", "key:S+E", "Create a sketch, or pick a solid face, first", 0x00004002u, 0, 0, false, false, nullptr, "design_extrude"}, + {"revolve", "Revolve", 1, "Shift+R", "key:S+R", "Create a sketch profile to revolve first", 0x00004000u, 0, 0, false, false, nullptr, "design_revolve"}, + {"sweep", "Sweep", 1, "Shift+W", "key:S+W", "Create a profile sketch to sweep first", 0x00004000u, 0, 2, false, false, nullptr, "design_sweep"}, + {"loft", "Loft", 1, "Shift+L", "key:S+L", "Create at least two profile sketches to loft", 0x00004000u, 0, 2, false, false, nullptr, "design_loft"}, + {"thicken", "Thicken", 1, nullptr, "fly:material#4", "Thicken needs a solid body — add or import one first", 0x0000000au, 1, 0, false, false, nullptr, "design_thicken"}, + {"rib", "Rib", 1, nullptr, "fly:material#5", "Rib needs a solid body — add or import one first", 0x00010000u, 1, 0, false, false, nullptr, "design_rib"}, + {"boolean", "Union", 1, "Shift+B", "btn:bool#0", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr, "design_boolean"}, + {"bool_subtract", "Subtract", 1, nullptr, "btn:bool#1", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr, "design_boolean"}, + {"bool_intersect", "Intersect", 1, nullptr, "btn:bool#2", "Boolean needs two bodies — create or import a second solid", 0x00000200u, 2, 0, false, false, nullptr, "design_boolean"}, + {"surf_extrude", "Surface Extrude", 1, "Shift+G", "key:S+G", "Create a sketch first", 0x00004000u, 0, 0, false, false, nullptr, "design_extrude"}, + {"surf_revolve", "Surface Revolve", 1, nullptr, "fly:surface#1", "Create a sketch profile to revolve first", 0x00004000u, 0, 0, false, false, nullptr, "design_revolve"}, + {"surf_loft", "Surface Loft", 1, nullptr, "fly:surface#2", "Create at least two profile sketches to loft", 0x00004000u, 0, 2, false, false, nullptr, "design_loft"}, + {"surf_fill", "Surface Fill", 1, nullptr, "fly:surface#3", "Create a closed sketch first", 0x00004000u, 0, 0, false, false, nullptr, "design_surface"}, + {"thicken_surf", "Thicken Surface", 1, nullptr, "fly:surface#5", "target is not a sheet body", 0x00000100u, 0, 0, true, false, nullptr, "design_thicken"}, + {"hole", "Hole", 2, "Shift+H", "key:S+H", "Pick a face or a plane to drill into", 0x00000402u, 1, 0, false, false, nullptr, "design_hole"}, + {"thread", "Thread", 2, "Shift+T", "key:S+T", "Pick a cylindrical surface (bore / outer) or a circular edge for a thread", 0x00000024u, 1, 0, false, false, nullptr, "design_thread"}, + {"shell", "Shell", 2, "Shift+K", "key:S+K", "Shell needs a solid body", 0x00000082u, 1, 0, false, false, nullptr, "design_shell"}, + {"cut", "Cut", 2, "Shift+X", "key:S+X", "Create a solid body to cut first", 0x00000480u, 1, 0, false, false, nullptr, "design_cut"}, + {"split", "Split", 2, nullptr, nullptr, "Split needs a solid body", 0x00000080u, 1, 0, false, false, nullptr, nullptr}, + {"fillet", "Fillet", 3, "Shift+F", "btn:dress#0", "Pick an edge to round", 0x000000b2u, 1, 0, false, false, nullptr, "design_filletedge"}, + {"chamfer", "Chamfer", 3, nullptr, "btn:dress#1", "Pick an edge to bevel", 0x000000b2u, 1, 0, false, false, nullptr, "design_chamfer"}, + {"draft", "Draft", 3, "Shift+D", "key:S+D", "Pick a face to taper", 0x0000000au, 1, 0, false, false, nullptr, "design_draft"}, + {"surf_offset", "Surface Offset", 3, nullptr, "fly:surface#4", "target is not a sheet body", 0x00000100u, 0, 0, true, false, nullptr, "design_offset"}, + {"pattern", "Linear pattern", 4, "Shift+N", "btn:pat#0", "Create a solid body to pattern first", 0x00006082u, 1, 0, false, false, nullptr, "design_array"}, + {"pattern_circular", "Circular pattern", 4, nullptr, "btn:pat#1", "Create a solid body to pattern first", 0x00006082u, 1, 0, false, false, nullptr, "design_polararray"}, + {"mirror", "Mirror", 4, "Shift+Z", "key:S+Z", "Mirror needs a body — add or import one first", 0x00000480u, 1, 0, false, false, nullptr, "design_mirror"}, + {"pat_curve", "Pattern on Curve", 4, nullptr, nullptr, "Pattern on curve needs a body and a curve", 0x00000090u, 1, 0, false, false, nullptr, nullptr}, + {"transform", "Move", 5, "Shift+Y", "key:S+Y", "Transform needs a body — add or import one first", 0x00002180u, 1, 0, false, false, nullptr, "design_move"}, + {"mate", "Mate", 5, nullptr, "fly:placement#2", "A mate needs two coordinate systems", 0x00001202u, 2, 0, false, false, nullptr, "design_c_coincident"}, + {"align", "Align to", 5, nullptr, nullptr, "Align needs a body", 0x00000002u, 1, 0, false, false, nullptr, nullptr}, + {"plane", "Plane", 6, "Shift+P", "key:S+P", nullptr, 0x00000453u, 0, 0, false, false, nullptr, "design_plane"}, + {"axis", "Axis", 6, "Shift+A", "key:S+A", nullptr, 0x00000057u, 0, 0, false, false, nullptr, "design_line"}, + {"coordsys_v", "Coord Sys", 6, "Shift+C", "key:S+C", nullptr, 0x00000043u, 0, 0, false, false, nullptr, "design_point"}, + {"helix", "Helix", 6, nullptr, "fly:plane#3", nullptr, 0x00000405u, 0, 0, false, false, nullptr, "design_thread"}, + {"project", "Project", 6, nullptr, "fly:plane#4", "Project needs a body — add or import one first", 0x00000482u, 1, 0, false, false, nullptr, "design_sketch"}, + {"measure", "Measure", 6, nullptr, nullptr, nullptr, 0x000b03feu, 0, 0, false, false, nullptr, nullptr}, + {"mass_props", "Mass", 6, nullptr, "btn:mass", nullptr, 0x00000080u, 1, 0, false, false, nullptr, "info"}, + {"interference", "Interference", 6, nullptr, nullptr, nullptr, 0x00000200u, 2, 0, false, false, nullptr, nullptr}, + {"edit_feature", "Edit", 7, nullptr, "btn:edit", nullptr, 0x00007d8eu, 0, 0, false, false, nullptr, "design_edit"}, + {"delete_face", "Delete Face", 7, nullptr, "fly:dressup#3", "Delete Face needs a body — add or import one first", 0x0000000eu, 1, 0, false, false, nullptr, "design_delete"}, + {"colour", "Colour", 7, nullptr, "btn:colour", nullptr, 0x00000180u, 1, 0, false, false, nullptr, "color_palette"}, + {"delete", "Delete", 7, "Del", "btn:delete", nullptr, 0x000f7f80u, 0, 0, false, false, nullptr, "design_delete"}, + {"sk_line_t", "Line", 0, "L", "key:L", nullptr, 0x000f8000u, 0, 0, false, true, "Line", "design_line"}, + {"sk_polyline", "Polyline", 0, nullptr, "fly:design_line#1", nullptr, 0x000f8000u, 0, 0, false, true, "Line", "design_polyline"}, + {"sk_rect", "Corner rectangle", 0, "R", "key:R", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle", "design_rect"}, + {"sk_rect_center", "Centre rectangle", 0, nullptr, "fly:design_rect#1", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle", "design_crect"}, + {"sk_rect_oblique", "Oblique rectangle", 0, nullptr, "fly:design_rect#2", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle", "design_rect_oblique"}, + {"sk_rect_rounded", "Rounded rectangle", 0, nullptr, "fly:design_rect#3", nullptr, 0x000f8000u, 0, 0, false, true, "Rectangle", "design_rect_rounded"}, + {"sk_circle", "Centre circle", 0, "C", "key:C", nullptr, 0x000f8000u, 0, 0, false, true, "Circle", "design_circle"}, + {"sk_circle_2pt", "2-point circle", 0, nullptr, "fly:design_circle#1", nullptr, 0x000f8000u, 0, 0, false, true, "Circle", "design_circle2pt"}, + {"sk_circle_3pt", "3-point circle", 0, nullptr, "fly:design_circle#2", nullptr, 0x000f8000u, 0, 0, false, true, "Circle", "design_circle3pt"}, + {"sk_arc_t", "3-point arc", 0, "A", "key:A", nullptr, 0x000f8000u, 0, 0, false, true, "Arc", "design_arc3pt"}, + {"sk_arc_tangent", "Tangent arc", 0, nullptr, "fly:design_arc3pt#1", nullptr, 0x000f8000u, 0, 0, false, true, "Arc", "design_tangentarc"}, + {"sk_arc_center", "Centre-point arc", 0, nullptr, "fly:design_arc3pt#2", nullptr, 0x000f8000u, 0, 0, false, true, "Arc", "design_arc_center"}, + {"sk_slot", "Slot", 0, "S", "key:S", nullptr, 0x000f8000u, 0, 0, false, true, "Slot", "design_slot"}, + {"sk_slot_arc", "Arc slot", 0, nullptr, "fly:design_slot#1", nullptr, 0x000f8000u, 0, 0, false, true, "Slot", "design_slot_arc"}, + {"sk_ellipse", "Ellipse", 0, "E", "key:E", nullptr, 0x000f8000u, 0, 0, false, true, "Ellipse", "design_ellipse"}, + {"sk_ellipse_arc", "Elliptical arc", 0, nullptr, "fly:design_ellipse#1", nullptr, 0x000f8000u, 0, 0, false, true, "Ellipse", "design_ellipse_arc"}, + {"sk_spline", "Spline", 0, "B", "key:B", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_bspline"}, + {"sk_poly_3", "Triangle", 0, nullptr, "btn:poly#3", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_4", "Square", 0, nullptr, "btn:poly#4", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_5", "Pentagon", 0, nullptr, "btn:poly#5", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_polygon", "Hexagon", 0, "G", "btn:poly#6", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_8", "Octagon", 0, nullptr, "btn:poly#8", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_12", "Dodecagon", 0, nullptr, "btn:poly#12", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_inscribed", "Inscribed", 0, nullptr, "btn:polyfit#0", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_poly_circumscribed", "Circumscribed", 0, nullptr, "btn:polyfit#1", nullptr, 0x000f8000u, 0, 0, false, true, "Polygon", "design_polygon"}, + {"sk_point_t", "Point", 0, "P", "key:P", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_point"}, + {"sk_text", "Text", 0, nullptr, "btn:text", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_text"}, + {"sk_svg", "SVG", 0, nullptr, "btn:svg", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_svg"}, + {"sk_offset", "Offset", 1, "O", "key:O", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_offset"}, + {"sk_trim", "Trim", 2, "T", "key:T", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_trim"}, + {"sk_fillet", "Fillet", 3, "F", "key:F", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_filletedge"}, + {"sk_chamfer", "Chamfer", 3, "H", "key:H", nullptr, 0x00090000u, 0, 0, false, true, nullptr, "design_chamfer"}, + {"sk_array", "Linear array", 4, nullptr, "fly:design_array#0", nullptr, 0x000b0000u, 0, 0, false, true, "Array", "design_array"}, + {"sk_array_polar", "Polar array", 4, nullptr, "fly:design_array#1", nullptr, 0x000b0000u, 0, 0, false, true, "Array", "design_polararray"}, + {"sk_mirror", "Mirror", 4, "M", "key:M", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_mirror"}, + {"sk_move", "Move", 5, nullptr, "fly:design_move#0", nullptr, 0x000f0000u, 0, 0, false, true, "Move", "design_move"}, + {"sk_rotate", "Rotate", 5, nullptr, "fly:design_move#1", nullptr, 0x000f0000u, 0, 0, false, true, "Move", "design_rotate"}, + {"sk_scale", "Scale", 5, nullptr, "fly:design_move#2", nullptr, 0x000f0000u, 0, 0, false, true, "Move", "design_scale"}, + {"sk_dimension", "Dimension", 6, "D", "key:D", nullptr, 0x000f8000u, 0, 0, false, true, nullptr, "design_dimension"}, + {"sk_constrain", "Constrain", 6, "K", "key:K", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_constrain"}, + {"sk_construct", "Construction", 6, "Q", "key:Q", nullptr, 0x000b8000u, 0, 0, false, true, nullptr, nullptr}, + {"sk_extend", "Extend", 7, "X", "key:X", nullptr, 0x000b0000u, 0, 0, false, true, nullptr, "design_extend"}, + {"sk_delete", "Delete", 7, "Del", "btn:delete", nullptr, 0x000f0000u, 0, 0, false, true, nullptr, "design_delete"}, }; static const int kOfferVerbCount = 86; diff --git a/src/slic3r/GUI/DesignPanel.cpp b/src/slic3r/GUI/DesignPanel.cpp index 75a09492fe..2bea7e6134 100644 --- a/src/slic3r/GUI/DesignPanel.cpp +++ b/src/slic3r/GUI/DesignPanel.cpp @@ -5155,6 +5155,28 @@ wxPoint DesignPanel::offer_anchor() const return wxPoint(r.x + r.width / 2, r.y + r.height / 2); } +// Append a verb row carrying the same glyph its toolbar button shows. The icon name comes from +// the atlas, so a verb and its icon are declared in one place; a null or unknown name leaves +// the row text-only rather than drawing a blank square. +// +// THE BITMAP MUST BE SET BEFORE Append(). wxGTK builds the GtkMenuItem inside Append and reads +// GetBitmap() right there (gtk/menu.cpp) — it makes a gtk_image_menu_item only if a bitmap is +// already present, and a plain one otherwise. Setting it on the item Append() returns is too +// late and silently does nothing, which is exactly how the first attempt failed. This is why +// Orca's own append_menu_item() constructs, sets, then appends. +wxMenuItem* DesignPanel::append_offer_item(wxMenu* menu, int id, const wxString& text, + const OfferVerb& v) +{ + auto* item = new wxMenuItem(menu, id, text); + if (v.icon != nullptr && *v.icon != '\0') { + const wxBitmap bmp = create_scaled_bitmap(v.icon, this, 16); + if (bmp.IsOk()) + item->SetBitmap(bmp); + } + menu->Append(item); + return item; +} + void DesignPanel::show_offer_menu(const wxPoint& screen_pos) { const int kind = offer_selection_kind(); @@ -5225,7 +5247,7 @@ void DesignPanel::show_offer_menu(const wxPoint& screen_pos) menu.Append(base + int(bound.size()), s)->Enable(false); bound.push_back(nullptr); } else if (live.size() == 1) { - menu.Append(base + int(bound.size()), label(*live[0])) + append_offer_item(&menu, base + int(bound.size()), label(*live[0]), *live[0]) ->Enable(live[0]->action != nullptr); bound.push_back(live[0]); } else { @@ -5249,7 +5271,7 @@ void DesignPanel::show_offer_menu(const wxPoint& screen_pos) target = it->second; } } - target->Append(base + int(bound.size()), label(*v)) + append_offer_item(target, base + int(bound.size()), label(*v), *v) ->Enable(v->action != nullptr); bound.push_back(v); } diff --git a/src/slic3r/GUI/DesignPanel.hpp b/src/slic3r/GUI/DesignPanel.hpp index c45c30c26a..034f98c7b6 100644 --- a/src/slic3r/GUI/DesignPanel.hpp +++ b/src/slic3r/GUI/DesignPanel.hpp @@ -622,6 +622,10 @@ private: // DesignOffer.hpp; this map is how a row reaches the code that already implements it, for // the verbs that have no keyboard shortcut to route through. std::map> m_verb_actions; + // Append an offer row with its toolbar glyph. The bitmap must be set BEFORE Append — + // wxGTK builds the GtkMenuItem there and only makes an image item if one is present. + wxMenuItem* append_offer_item(wxMenu* menu, int id, const wxString& text, + const struct OfferVerb& v); void show_offer_menu(const wxPoint& screen_pos); // Where the offer opens when no mouse press anchors it: the keyboard route, and the automatic // open on entering Sketch. The pointer if it is over the viewport, else the viewport's centre.