| 1090 | | // @@@ replace prototype by function body: |
| 1091 | | static ED4_terminal *get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, const ED4_TerminalPredicate& predicate); |
| | 1090 | static ED4_terminal *get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, const ED4_TerminalPredicate& predicate) { |
| | 1091 | // current_y is y-position of terminal at which search starts. |
| | 1092 | // It may be in world or screen coordinates (isScreen marks which is used) |
| | 1093 | // This is needed to move the cursor from top- to middle-area w/o scrolling middle-area to top-position. |
| | 1094 | |
| | 1095 | ED4_terminal *result = 0; |
| | 1096 | |
| | 1097 | int m = 0; |
| | 1098 | int last_m = starting_point->children->members()-1; |
| | 1099 | int incr = 1; |
| | 1100 | |
| | 1101 | if (cursor_move == ED4_C_UP) { |
| | 1102 | std::swap(m, last_m); incr = -1; // revert search direction |
| | 1103 | e4_assert(!isScreen); // use screen coordinates for ED4_C_DOWN only! |
| | 1104 | } |
| | 1105 | |
| | 1106 | while (!result) { |
| | 1107 | ED4_base *member = starting_point->children->member(m); |
| | 1108 | |
| | 1109 | if (member->is_manager()) { |
| | 1110 | if (!member->flag.hidden) { // step over hidden managers (e.g. folded groups) |
| | 1111 | result = get_upper_lower_cursor_pos(member->to_manager(), cursor_move, current_y, isScreen, predicate); |
| | 1112 | } |
| | 1113 | } |
| | 1114 | else { |
| | 1115 | if (member->dynamic_prop & ED4_P_CURSOR_ALLOWED) { |
| | 1116 | AW_pos x, y; |
| | 1117 | member->calc_world_coords(&x, &y); |
| | 1118 | if (isScreen) current_ed4w()->world_to_win_coords(&x, &y); // if current_y is screen, convert x/y to screen-coordinates as well |
| | 1119 | |
| | 1120 | bool pos_beyond = (cursor_move == ED4_C_UP) ? y<current_y : y>current_y; |
| | 1121 | if (pos_beyond) { |
| | 1122 | bool skip_top_scrolled = false; |
| | 1123 | if (isScreen) { |
| | 1124 | ED4_multi_species_manager *marea_man = NULL; |
| | 1125 | if (member->get_area_level(&marea_man) == ED4_A_MIDDLE_AREA) { |
| | 1126 | // previous position was in top-area -> avoid selecting scrolled-out terminals |
| | 1127 | AW_pos y_area = marea_man->parent->extension.position[Y_POS]; |
| | 1128 | skip_top_scrolled = y<y_area; |
| | 1129 | } |
| | 1130 | } |
| | 1131 | |
| | 1132 | if (!skip_top_scrolled) { |
| | 1133 | ED4_terminal *term = member->to_terminal(); |
| | 1134 | if (predicate.fulfilled_by(term)) result = term; |
| | 1135 | } |
| | 1136 | } |
| | 1137 | } |
| | 1138 | } |
| | 1139 | |
| | 1140 | if (m == last_m) break; |
| | 1141 | m += incr; |
| | 1142 | } |
| | 1143 | |
| | 1144 | return result; |
| | 1145 | } |
| 1378 | | static ED4_terminal *get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, const ED4_TerminalPredicate& predicate) { |
| 1379 | | // current_y is y-position of terminal at which search starts. |
| 1380 | | // It may be in world or screen coordinates (isScreen marks which is used) |
| 1381 | | // This is needed to move the cursor from top- to middle-area w/o scrolling middle-area to top-position. |
| 1382 | | |
| 1383 | | ED4_terminal *result = 0; |
| 1384 | | |
| 1385 | | int m = 0; |
| 1386 | | int last_m = starting_point->children->members()-1; |
| 1387 | | int incr = 1; |
| 1388 | | |
| 1389 | | if (cursor_move == ED4_C_UP) { |
| 1390 | | std::swap(m, last_m); incr = -1; // revert search direction |
| 1391 | | e4_assert(!isScreen); // use screen coordinates for ED4_C_DOWN only! |
| 1392 | | } |
| 1393 | | |
| 1394 | | while (!result) { |
| 1395 | | ED4_base *member = starting_point->children->member(m); |
| 1396 | | |
| 1397 | | if (member->is_manager()) { |
| 1398 | | if (!member->flag.hidden) { // step over hidden managers (e.g. folded groups) |
| 1399 | | result = get_upper_lower_cursor_pos(member->to_manager(), cursor_move, current_y, isScreen, predicate); |
| 1400 | | } |
| 1401 | | } |
| 1402 | | else { |
| 1403 | | if (member->dynamic_prop & ED4_P_CURSOR_ALLOWED) { |
| 1404 | | AW_pos x, y; |
| 1405 | | member->calc_world_coords(&x, &y); |
| 1406 | | if (isScreen) current_ed4w()->world_to_win_coords(&x, &y); // if current_y is screen, convert x/y to screen-coordinates as well |
| 1407 | | |
| 1408 | | bool pos_beyond = (cursor_move == ED4_C_UP) ? y<current_y : y>current_y; |
| 1409 | | if (pos_beyond) { |
| 1410 | | bool skip_top_scrolled = false; |
| 1411 | | if (isScreen) { |
| 1412 | | ED4_multi_species_manager *marea_man = NULL; |
| 1413 | | if (member->get_area_level(&marea_man) == ED4_A_MIDDLE_AREA) { |
| 1414 | | // previous position was in top-area -> avoid selecting scrolled-out terminals |
| 1415 | | AW_pos y_area = marea_man->parent->extension.position[Y_POS]; |
| 1416 | | skip_top_scrolled = y<y_area; |
| 1417 | | } |
| 1418 | | } |
| 1419 | | |
| 1420 | | if (!skip_top_scrolled) { |
| 1421 | | ED4_terminal *term = member->to_terminal(); |
| 1422 | | if (predicate.fulfilled_by(term)) result = term; |
| 1423 | | } |
| 1424 | | } |
| 1425 | | } |
| 1426 | | } |
| 1427 | | |
| 1428 | | if (m == last_m) break; |
| 1429 | | m += incr; |
| 1430 | | } |
| 1431 | | |
| 1432 | | return result; |
| 1433 | | } |
| 1434 | | |