| 193 | } |
| 194 | |
| 195 | bool execute_schema_callback(const nb::object& items_obj, |
| 196 | const nb::object& menu_instance, |
| 197 | int target_callback_index, |
| 198 | int& next_callback_index) { |
| 199 | if (!items_obj.is_valid() || items_obj.is_none()) |
| 200 | return false; |
| 201 | |
| 202 | for (nb::handle item_handle : items_obj) { |
| 203 | if (!nb::isinstance<nb::dict>(item_handle)) |
| 204 | continue; |
| 205 | nb::dict item = nb::borrow<nb::dict>(item_handle); |
| 206 | |
| 207 | if (is_submenu_item(item)) { |
| 208 | if (execute_schema_callback( |
| 209 | dict_get(item, "items"), menu_instance, |
| 210 | target_callback_index, next_callback_index)) { |
| 211 | return true; |
| 212 | } |
| 213 | continue; |
| 214 | } |
| 215 | |
| 216 | if (!is_callback_item(item)) |
| 217 | continue; |
| 218 | |
| 219 | const int current_index = next_callback_index++; |
| 220 | if (current_index != target_callback_index) |
| 221 | continue; |
| 222 | |
| 223 | nb::object callback = dict_get(item, "callback"); |
| 224 | if (callback.is_valid() && !callback.is_none()) { |
| 225 | nb::borrow<nb::callable>(callback)(); |
| 226 | return true; |
| 227 | } |
| 228 | |
| 229 | const auto action_id = object_to_string(dict_get(item, "action_id")); |
| 230 | if (!action_id.empty() && nb::hasattr(menu_instance, "on_menu_action")) { |
| 231 | menu_instance.attr("on_menu_action")(action_id); |
| 232 | return true; |
| 233 | } |
| 234 | |
| 235 | return true; |
| 236 | } |
| 237 | |
| 238 | return false; |
| 239 | } |
| 240 | |
| 241 | void draw_schema_menu_items(const nb::object& items_obj, const nb::object& menu_instance) { |
| 242 | if (!items_obj.is_valid() || items_obj.is_none()) |
no test coverage detected