Changeset 8331 for branches

Show
Ignore:
Timestamp:
19/01/12 14:13:16 (4 months ago)
Author:
westram
Message:
  • get_upper_lower_cursor_pos
    • no longer a member of ED4_cursor
    • replaced callback+cb-arg-param by terminal predicate
    • loop backwards through hierarchy when moving cursor up
    • DRYed duplicated code in loop
  • calc_world_coords now const
Location:
branches/e4fix/EDIT4
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/e4fix/EDIT4/ED4_base.cxx

    r8330 r8331  
    12221222 
    12231223int ED4_base::currTimestamp = 1; 
    1224 void ED4_base::update_world_coords_cache() { 
     1224void ED4_base::update_world_coords_cache() const { 
    12251225    if (parent) { 
    12261226        parent->calc_world_coords(&lastXpos, &lastYpos); 
  • branches/e4fix/EDIT4/ED4_cursor.cxx

    r8329 r8331  
    10621062} 
    10631063 
    1064 static bool has_gap_or_base_at(ED4_base *terminal, bool test_for_base, int seq_pos) { 
    1065     bool test_succeeded = false; 
    1066  
    1067     if (terminal->is_sequence_terminal()) { 
    1068         ED4_sequence_terminal *seqTerm = terminal->to_sequence_terminal(); 
    1069         int len; 
    1070         char *seq = seqTerm->resolve_pointer_to_string_copy(&len); 
    1071         if (seq) { 
    1072             test_succeeded = len>seq_pos && bool(ADPP_IS_ALIGN_CHARACTER(seq[seq_pos]))!=test_for_base; 
    1073         } 
    1074         free(seq); 
    1075     } 
    1076  
    1077 #if defined(DEBUG) && 0 
    1078     printf("test_for_base=%i test_succeeded=%i\n", int(test_for_base), int(test_succeeded)); 
    1079 #endif // DEBUG 
    1080     return test_succeeded; 
    1081 } 
    1082  
    1083 static bool has_base_at(ED4_base *terminal, int seq_pos) { return has_gap_or_base_at(terminal, true,  seq_pos); } 
    1084 static bool has_gap_at(ED4_base *terminal, int seq_pos) { return has_gap_or_base_at(terminal, false, seq_pos); } 
    1085  
     1064class has_base_at : public ED4_TerminalPredicate { 
     1065    int  seq_pos; 
     1066    bool want_base; 
     1067public: 
     1068    has_base_at(int seq_pos_, bool want_base_) : seq_pos(seq_pos_), want_base(want_base_) {} 
     1069    bool fulfilled_by(const ED4_terminal *terminal) const { 
     1070        bool test_succeeded = false; 
     1071 
     1072        if (terminal->is_sequence_terminal()) { 
     1073            const ED4_sequence_terminal *seqTerm = terminal->to_sequence_terminal(); 
     1074            int len; 
     1075            char *seq = seqTerm->resolve_pointer_to_string_copy(&len); 
     1076            if (seq) { 
     1077                test_succeeded = len>seq_pos && bool(ADPP_IS_ALIGN_CHARACTER(seq[seq_pos]))!=want_base; 
     1078            } 
     1079            free(seq); 
     1080        } 
     1081 
     1082        return test_succeeded; 
     1083    } 
     1084}; 
     1085 
     1086struct acceptAnyTerminal : public ED4_TerminalPredicate { 
     1087    bool fulfilled_by(const ED4_terminal *) const { return true; } 
     1088}; 
     1089 
     1090// @@@ replace prototype by function body: 
     1091static 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); 
    10861092 
    10871093ED4_returncode ED4_cursor::move_cursor(AW_event *event) { 
     
    11111117        if (result == ED4_R_OK) { 
    11121118            AW_pos x_dummy, y_world; 
    1113              
     1119 
    11141120            owner_of_cursor->calc_world_coords(&x_dummy, &y_world); 
    11151121 
    1116             int       seq_pos        = get_sequence_pos(); 
    1117             ED4_base *target_terminal = 0; 
     1122            int seq_pos = get_sequence_pos(); 
     1123            ED4_terminal *target_terminal = 0; 
    11181124 
    11191125            if (event->keymodifier & AW_KEYMODE_CONTROL) { 
    1120                 bool has_base = has_base_at(owner_of_cursor, seq_pos); 
     1126                bool has_base = has_base_at(seq_pos, true).fulfilled_by(owner_of_cursor->to_terminal()); 
    11211127 
    11221128                // stay in current area 
    1123                 ED4_manager *start_at_manager = 0; 
    1124                 if (owner_of_cursor->has_parent(ED4_ROOT->top_area_man)) { 
    1125                     start_at_manager = ED4_ROOT->top_area_man; 
    1126                 } 
    1127                 else { 
    1128                     start_at_manager = ED4_ROOT->middle_area_man; 
    1129                 } 
     1129                ED4_multi_species_manager *start_at_manager = 0; 
     1130                owner_of_cursor->get_area_level(&start_at_manager); 
    11301131 
    11311132                if (!endHome) { // not End or Home 
    1132                     target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_base ? has_gap_at : has_base_at, seq_pos); 
     1133                    target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_base_at(seq_pos, !has_base)); 
    11331134                    if (target_terminal && !has_base && ED4_ROOT->aw_root->awar(ED4_AWAR_FAST_CURSOR_JUMP)->read_int()) {  // if jump_over group 
    11341135                        target_terminal->calc_world_coords(&x_dummy, &y_world); 
    1135                         target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_gap_at, seq_pos); 
     1136                        target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_base_at(seq_pos, false)); 
    11361137                    } 
    11371138                } 
     
    11421143                                                                 dir == ED4_C_UP ? ED4_C_DOWN : ED4_C_UP, // use opposite movement direction 
    11431144                                                                 dir == ED4_C_UP ? 0 : INT_MAX, false, // search for top-/bottom-most terminal 
    1144                                                                  0, seq_pos); 
     1145                                                                 acceptAnyTerminal()); 
    11451146                } 
    11461147            } 
     
    11551156                    } 
    11561157                } 
    1157                 target_terminal = get_upper_lower_cursor_pos(ED4_ROOT->main_manager, dir, y_world, isScreen, 0, seq_pos); 
     1158                target_terminal = get_upper_lower_cursor_pos(ED4_ROOT->main_manager, dir, y_world, isScreen, acceptAnyTerminal()); 
    11581159            } 
    11591160 
    11601161            if (target_terminal) { 
    1161                 set_to_terminal(target_terminal->to_terminal(), seq_pos, ED4_JUMP_KEEP_VISIBLE); 
     1162                set_to_terminal(target_terminal, seq_pos, ED4_JUMP_KEEP_VISIBLE); 
    11621163            } 
    11631164        } 
     
    13751376} 
    13761377 
    1377 ED4_terminal *ED4_cursor::get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, ED4_TerminalTest terminal_is_appropriate, int seq_pos) 
    1378 { 
     1378static 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) { 
    13791379    // current_y is y-position of terminal at which search starts. 
    13801380    // It may be in world or screen coordinates (isScreen marks which is used) 
     
    13831383    ED4_terminal *result = 0; 
    13841384 
    1385     for (int i=0; i<starting_point->children->members(); i++) { 
    1386         ED4_base *member = starting_point->children->member(i); 
    1387  
    1388         AW_pos x, y; 
    1389         member->calc_world_coords(&x, &y); 
    1390  
    1391         switch (cursor_move) { 
    1392             case ED4_C_UP: 
    1393                 e4_assert(!isScreen); // use screen coordinates for ED4_C_DOWN only! 
    1394  
    1395                 if (y < current_y) { 
    1396                     if ((member->is_manager()) && !member->flag.hidden) { 
    1397                         ED4_terminal *result_in_manager = get_upper_lower_cursor_pos(member->to_manager(), cursor_move, current_y, isScreen, terminal_is_appropriate, seq_pos); 
    1398                         if (result_in_manager) result   = result_in_manager; 
    1399                     } 
    1400  
    1401                     if ((member->dynamic_prop & ED4_P_CURSOR_ALLOWED)) { 
    1402                         if (terminal_is_appropriate==0 || terminal_is_appropriate(member, seq_pos)) { 
    1403                             result = member->to_terminal(); // overwrite (i.e. take last matching terminal) 
     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; 
    14041417                        } 
    14051418                    } 
    1406                 } 
    1407                 break; 
    1408  
    1409             case ED4_C_DOWN: 
    1410                 if (!result) { // don't overwrite (i.e. take first matching terminal) 
    1411                     if ((member->is_manager()) && !member->flag.hidden) { 
    1412                         result = get_upper_lower_cursor_pos(member->to_manager(), cursor_move, current_y, isScreen, terminal_is_appropriate, seq_pos); 
    1413                     } 
    1414  
    1415                     if (isScreen) window()->world_to_win_coords(&x, &y); // if current_y is screen, convert x/y to screen-coordinates as well 
    1416  
    1417                     if ((member->dynamic_prop & ED4_P_CURSOR_ALLOWED) && y > current_y) { 
    1418                         ED4_multi_species_manager *marea_man = NULL; // probably multi_species_manager of middle_area, otherwise just a dummy 
    1419                         ED4_AREA_LEVEL level                 = member->get_area_level(&marea_man); 
    1420  
    1421                         if (level != ED4_A_MIDDLE_AREA) { 
    1422                             if (terminal_is_appropriate==0 || terminal_is_appropriate(member, seq_pos)) { 
    1423                                 result = member->to_terminal(); 
    1424                             } 
    1425                         } 
    1426                         else if (level == ED4_A_MIDDLE_AREA) { 
    1427                             AW_pos y_area = marea_man->parent->extension.position[Y_POS]; 
    1428                             if (y > y_area) { 
    1429                                 member = starting_point->children->member(i); 
    1430                                 if (terminal_is_appropriate==0 || terminal_is_appropriate(member, seq_pos)) { 
    1431                                     result = member->to_terminal(); 
    1432                                 } 
    1433                             } 
    1434                         } 
     1419 
     1420                    if (!skip_top_scrolled) { 
     1421                        ED4_terminal *term = member->to_terminal(); 
     1422                        if (predicate.fulfilled_by(term)) result = term; 
    14351423                    } 
    14361424                } 
    1437                 break; 
    1438  
    1439             default: 
    1440                 e4_assert(0); 
    1441                 break; 
    1442         } 
     1425            } 
     1426        } 
     1427 
     1428        if (m == last_m) break; 
     1429        m += incr; 
    14431430    } 
    14441431 
    14451432    return result; 
    14461433} 
     1434 
    14471435 
    14481436/* -------------------------------------------------------------------------------- 
  • branches/e4fix/EDIT4/ed4_class.hxx

    r8306 r8331  
    612612extern int ED4_update_global_cursor_awars_allowed; 
    613613 
    614 typedef bool (*ED4_TerminalTest)(ED4_base *terminal, int seqPos); 
     614struct ED4_TerminalPredicate { 
     615    virtual ~ED4_TerminalPredicate() {} 
     616    virtual bool fulfilled_by(const ED4_terminal *) const = 0; 
     617}; 
    615618 
    616619class ED4_WinContextFree { // denies usage of the following functions in classes derived from this 
     
    633636    ED4_returncode  draw_cursor(AW_pos x, AW_pos y); 
    634637    ED4_returncode  delete_cursor(AW_pos del_mark,  ED4_base *target_terminal); 
    635     ED4_terminal *get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, ED4_TerminalTest terminal_is_appropriate, int seq_pos); 
    636     void          updateAwars(); 
     638 
     639    void updateAwars(); 
    637640 
    638641    ED4_cursor(const ED4_cursor&); // copy-constructor not allowed 
     
    10121015    // cache world coordinates: 
    10131016 
    1014     static int currTimestamp; 
    1015     AW_pos    lastXpos; 
    1016     AW_pos    lastYpos; 
    1017     int        timestamp; 
     1017    static int     currTimestamp; 
     1018    mutable AW_pos lastXpos; 
     1019    mutable AW_pos lastYpos; 
     1020    mutable int    timestamp; 
    10181021 
    10191022public: 
     
    10721075    // functions concerned with coordinate transformation 
    10731076 
    1074     void update_world_coords_cache(); 
     1077    void update_world_coords_cache() const; 
    10751078    void calc_rel_coords(AW_pos *x, AW_pos *y); 
    10761079 
    1077     void calc_world_coords(AW_pos *x, AW_pos *y) { 
     1080    void calc_world_coords(AW_pos *x, AW_pos *y) const { 
    10781081        bool cache_up_to_date = timestamp == currTimestamp; 
    10791082        if (!cache_up_to_date) { 
     
    22442247#endif 
    22452248 
    2246  
    2247