Merge lp:~nha/widelands/fixes into lp:widelands

Proposed by Nicolai Hähnle
Status: Merged
Merged at revision: not available
Proposed branch: lp:~nha/widelands/fixes
Merge into: lp:widelands
Diff against target: 700 lines (+225/-79)
14 files modified
src/log.cc (+2/-2)
src/log.h (+2/-0)
src/logic/bob.cc (+0/-8)
src/logic/bob.h (+7/-1)
src/logic/immovable.cc (+25/-3)
src/logic/immovable.h (+9/-0)
src/logic/instances.cc (+3/-0)
src/logic/map.cc (+2/-0)
src/logic/soldier.cc (+64/-55)
src/logic/worker.cc (+41/-9)
src/logic/worker.h (+3/-0)
src/ui_basic/editbox.cc (+58/-1)
src/ui_basic/editbox.h (+2/-0)
src/wlapplication.cc (+7/-0)
To merge this branch: bzr merge lp:~nha/widelands/fixes
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+22326@code.launchpad.net

Description of the change

Various small fixes and behavior changes that I suggest for merging after the release of build15.

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

Nicolai, most of these are no brainers and i agree of merging them.

However about the reserved thing please see my comment on the bug report.

Revision history for this message
Raul Ferriz (raul.ferriz) wrote :

I have checked the code, but not try to compile and run. It is safe, some clean up and longer waiting checks for soldiers when waiting a signal.
The only but is that I think that this can break replays.

Revision history for this message
Nicolai Hähnle (nha) wrote :

Yes, it does break replays. I don't think this is a problem, since we have never guaranteed compatibility of replays.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/log.cc'
--- src/log.cc 2010-03-27 23:50:23 +0000
+++ src/log.cc 2010-04-13 18:44:39 +0000
@@ -25,6 +25,8 @@
2525
26extern std::ostream & wout;26extern std::ostream & wout;
2727
28bool g_verbose = false;
29
28void log(const char * const fmt, ...) {30void log(const char * const fmt, ...) {
29 char buffer[2048];31 char buffer[2048];
30 va_list va;32 va_list va;
@@ -33,8 +35,6 @@
33 vsnprintf(buffer, sizeof(buffer), fmt, va);35 vsnprintf(buffer, sizeof(buffer), fmt, va);
34 va_end(va);36 va_end(va);
3537
36 //TODO: use iostreams instead of vprintf because other parts of
37 // Widelands use iostreams
38 wout << buffer;38 wout << buffer;
39 wout.flush();39 wout.flush();
40}40}
4141
=== modified file 'src/log.h'
--- src/log.h 2010-03-27 23:50:23 +0000
+++ src/log.h 2010-04-13 18:44:39 +0000
@@ -33,4 +33,6 @@
33// wout is either std::cout or specified logfile.33// wout is either std::cout or specified logfile.
34void log(const char *, ...) PRINTF_FORMAT(1, 2);34void log(const char *, ...) PRINTF_FORMAT(1, 2);
3535
36extern bool g_verbose;
37
36#endif38#endif
3739
=== modified file 'src/logic/bob.cc'
--- src/logic/bob.cc 2010-04-04 12:32:35 +0000
+++ src/logic/bob.cc 2010-04-13 18:44:39 +0000
@@ -692,10 +692,6 @@
692void Bob::movepath_update(Game & game, State & state)692void Bob::movepath_update(Game & game, State & state)
693{693{
694 if (get_signal().size()) {694 if (get_signal().size()) {
695 if (serial() == 3755)
696 molog
697 ("[movepath_update] signal '%s'; popping task\n",
698 get_signal().c_str());
699 return pop_task(game);695 return pop_task(game);
700 }696 }
701697
@@ -919,10 +915,6 @@
919 m_walkstart = game.get_gametime();915 m_walkstart = game.get_gametime();
920 m_walkend = m_walkstart + tdelta;916 m_walkend = m_walkstart + tdelta;
921917
922 if (serial() == 3755)
923 molog
924 ("[start_walk]: changint position from (%i, %i) to (%i, %i)\n",
925 get_position().x, get_position().y, newnode.x, newnode.y);
926 set_position(game, newnode);918 set_position(game, newnode);
927 set_animation(game, a);919 set_animation(game, a);
928920
929921
=== modified file 'src/logic/bob.h'
--- src/logic/bob.h 2010-04-03 16:44:44 +0000
+++ src/logic/bob.h 2010-04-13 18:44:39 +0000
@@ -323,11 +323,17 @@
323 bool is_walking() {return m_walking != IDLE;}323 bool is_walking() {return m_walking != IDLE;}
324324
325325
326 /**
327 * This is a hack that should not be used, if possible.
328 * It is only introduced here because profiling showed
329 * that soldiers spend a lot of time in the node blocked check.
330 */
331 Bob * get_next_on_field() const {return m_linknext;}
332
326protected:333protected:
327 Bob(const Descr & descr);334 Bob(const Descr & descr);
328 virtual ~Bob();335 virtual ~Bob();
329336
330
331private:337private:
332 void do_act(Game &);338 void do_act(Game &);
333 void do_pop_task(Game &);339 void do_pop_task(Game &);
334340
=== modified file 'src/logic/immovable.cc'
--- src/logic/immovable.cc 2010-04-01 11:19:48 +0000
+++ src/logic/immovable.cc 2010-04-13 18:44:39 +0000
@@ -337,7 +337,8 @@
337m_anim (0),337m_anim (0),
338m_program (0),338m_program (0),
339m_program_ptr (0),339m_program_ptr (0),
340m_program_step(0)340m_program_step(0),
341m_reserved_by_worker(false)
341{}342{}
342343
343344
@@ -471,6 +472,22 @@
471 dst.drawanim(pos, m_anim, game.get_gametime() - m_animstart, 0);472 dst.drawanim(pos, m_anim, game.get_gametime() - m_animstart, 0);
472}473}
473474
475/**
476 * Returns whether this immovable was reserved by a worker.
477 */
478bool Immovable::is_reserved_by_worker() const
479{
480 return m_reserved_by_worker;
481}
482
483/**
484 * Change whether this immovable is marked as reserved by a worker.
485 */
486void Immovable::set_reserved_by_worker(bool reserve)
487{
488 m_reserved_by_worker = reserve;
489}
490
474491
475/*492/*
476==============================493==============================
@@ -480,7 +497,7 @@
480==============================497==============================
481*/498*/
482499
483#define IMMOVABLE_SAVEGAME_VERSION 2500#define IMMOVABLE_SAVEGAME_VERSION 3
484501
485void Immovable::Loader::load(FileRead & fr, uint8_t const version)502void Immovable::Loader::load(FileRead & fr, uint8_t const version)
486{503{
@@ -537,6 +554,9 @@
537 }554 }
538555
539 imm.m_program_step = fr.Signed32();556 imm.m_program_step = fr.Signed32();
557
558 if (version >= 3)
559 imm.m_reserved_by_worker = fr.Unsigned8();
540}560}
541561
542void Immovable::Loader::load_pointers()562void Immovable::Loader::load_pointers()
@@ -560,7 +580,7 @@
560void Immovable::save580void Immovable::save
561 (Editor_Game_Base & egbase, Map_Map_Object_Saver & mos, FileWrite & fw)581 (Editor_Game_Base & egbase, Map_Map_Object_Saver & mos, FileWrite & fw)
562{582{
563 // This is in front because it is required to obtain the descriptiong583 // This is in front because it is required to obtain the description
564 // necessary to create the Immovable584 // necessary to create the Immovable
565 fw.Unsigned8(header_Immovable);585 fw.Unsigned8(header_Immovable);
566 fw.Unsigned8(IMMOVABLE_SAVEGAME_VERSION);586 fw.Unsigned8(IMMOVABLE_SAVEGAME_VERSION);
@@ -586,6 +606,8 @@
586606
587 fw.Unsigned32(m_program_ptr);607 fw.Unsigned32(m_program_ptr);
588 fw.Signed32(m_program_step);608 fw.Signed32(m_program_step);
609
610 fw.Unsigned8(m_reserved_by_worker);
589}611}
590612
591Map_Object::Loader * Immovable::load613Map_Object::Loader * Immovable::load
592614
=== modified file 'src/logic/immovable.h'
--- src/logic/immovable.h 2010-02-28 18:40:36 +0000
+++ src/logic/immovable.h 2010-04-13 18:44:39 +0000
@@ -153,6 +153,9 @@
153 return descr().get_owner_tribe();153 return descr().get_owner_tribe();
154 }154 }
155155
156 bool is_reserved_by_worker() const;
157 void set_reserved_by_worker(bool reserve);
158
156protected:159protected:
157 Coords m_position;160 Coords m_position;
158161
@@ -163,6 +166,12 @@
163 uint32_t m_program_ptr; ///< index of next instruction to execute166 uint32_t m_program_ptr; ///< index of next instruction to execute
164 int32_t m_program_step; ///< time of next step167 int32_t m_program_step; ///< time of next step
165168
169 /**
170 * Immovables like trees are reserved by a worker that is walking
171 * towards them, so that e.g. two lumberjacks don't attempt to
172 * work on the same tree simultaneously.
173 */
174 bool m_reserved_by_worker;
166175
167 // Load/save support176 // Load/save support
168protected:177protected:
169178
=== modified file 'src/logic/instances.cc'
--- src/logic/instances.cc 2010-03-27 23:50:23 +0000
+++ src/logic/instances.cc 2010-04-13 18:44:39 +0000
@@ -437,6 +437,9 @@
437 */437 */
438void Map_Object::molog(char const * fmt, ...) const438void Map_Object::molog(char const * fmt, ...) const
439{439{
440 if (!g_verbose && !m_logsink)
441 return;
442
440 va_list va;443 va_list va;
441 char buffer[2048];444 char buffer[2048];
442445
443446
=== modified file 'src/logic/map.cc'
--- src/logic/map.cc 2010-04-03 16:44:44 +0000
+++ src/logic/map.cc 2010-04-13 18:44:39 +0000
@@ -1892,6 +1892,7 @@
18921892
1893 // Recursively check integrity1893 // Recursively check integrity
1894 void debug(uint32_t const node, char const * const str) {1894 void debug(uint32_t const node, char const * const str) {
1895#if 0
1895 uint32_t l = node * 2 + 1;1896 uint32_t l = node * 2 + 1;
1896 uint32_t r = node * 2 + 2;1897 uint32_t r = node * 2 + 2;
1897 if (m_data[node]->heap_index != static_cast<int32_t>(node)) {1898 if (m_data[node]->heap_index != static_cast<int32_t>(node)) {
@@ -1912,6 +1913,7 @@
1912 }1913 }
1913 debug(r, str);1914 debug(r, str);
1914 }1915 }
1916#endif
1915 }1917 }
19161918
1917private:1919private:
19181920
=== modified file 'src/logic/soldier.cc'
--- src/logic/soldier.cc 2010-04-04 12:32:35 +0000
+++ src/logic/soldier.cc 2010-04-13 18:44:39 +0000
@@ -781,7 +781,9 @@
781 if (signal == "blocked")781 if (signal == "blocked")
782 // Wait before we try again. Note that this must come *after*782 // Wait before we try again. Note that this must come *after*
783 // we check for a battle783 // we check for a battle
784 return start_task_idle(game, get_animation("idle"), 250);784 // Note that we *should* be woken via sendSpaceSignals,
785 // so the timeout is just an additional safety net.
786 return start_task_idle(game, get_animation("idle"), 5000);
785787
786 if (!location) {788 if (!location) {
787 molog("[attack] our location disappeared during a battle\n");789 molog("[attack] our location disappeared during a battle\n");
@@ -854,7 +856,7 @@
854 (start_task_movepath856 (start_task_movepath
855 (game,857 (game,
856 baseflag.get_position(),858 baseflag.get_position(),
857 0,859 4, // use larger persist when returning home
858 descr().get_right_walk_anims(does_carry_ware())))860 descr().get_right_walk_anims(does_carry_ware())))
859 return;861 return;
860 else {862 else {
@@ -870,7 +872,7 @@
870 (start_task_movepath872 (start_task_movepath
871 (game,873 (game,
872 enemy->base_flag().get_position(),874 enemy->base_flag().get_position(),
873 2,875 3,
874 descr().get_right_walk_anims(does_carry_ware())))876 descr().get_right_walk_anims(does_carry_ware())))
875 return;877 return;
876 else {878 else {
@@ -1015,7 +1017,9 @@
1015 if (signal == "blocked")1017 if (signal == "blocked")
1016 // Wait before we try again. Note that this must come *after*1018 // Wait before we try again. Note that this must come *after*
1017 // we check for a battle1019 // we check for a battle
1018 return start_task_idle(game, get_animation("idle"), 250);1020 // Note that we *should* be woken via sendSpaceSignals,
1021 // so the timeout is just an additional safety net.
1022 return start_task_idle(game, get_animation("idle"), 5000);
10191023
1020 // If we only are defending our home ...1024 // If we only are defending our home ...
1021 if (state.ivar1 & CF_DEFEND_STAYHOME) {1025 if (state.ivar1 & CF_DEFEND_STAYHOME) {
@@ -1103,7 +1107,7 @@
1103 (start_task_movepath1107 (start_task_movepath
1104 (game,1108 (game,
1105 baseflag.get_position(),1109 baseflag.get_position(),
1106 0,1110 4, // use larger persist when returning home
1107 descr().get_right_walk_anims(does_carry_ware())))1111 descr().get_right_walk_anims(does_carry_ware())))
1108 return;1112 return;
11091113
@@ -1153,7 +1157,7 @@
1153 (start_task_movepath1157 (start_task_movepath
1154 (game,1158 (game,
1155 target.s->get_position(),1159 target.s->get_position(),
1156 1,1160 3,
1157 descr().get_right_walk_anims(does_carry_ware()),1161 descr().get_right_walk_anims(does_carry_ware()),
1158 false,1162 false,
1159 1))1163 1))
@@ -1506,62 +1510,67 @@
1506bool Soldier::checkNodeBlocked1510bool Soldier::checkNodeBlocked
1507 (Game & game, FCoords const & field, bool const commit)1511 (Game & game, FCoords const & field, bool const commit)
1508{1512{
1509 if (!isOnBattlefield())1513 State * attackdefense = get_state(taskAttack);
1510 return false;1514
15111515 if (!attackdefense)
1512 if (upcast(Building, building, get_location(game))) {1516 attackdefense = get_state(taskDefense);
1513 if (field == building->get_position()) {
1514 if (commit)
1515 sendSpaceSignals(game);
1516 return false; // we can always walk home
1517 }
1518 }
1519
1520 std::vector<Bob *> soldiers;
1521 game.map().find_bobs
1522 (Area<FCoords>(field, 0), &soldiers, FindBobSoldierOnBattlefield());
15231517
1524 if1518 if
1525 (soldiers.size() &&1519 (!attackdefense ||
1526 (!m_battle ||1520 (attackdefense->ivar1 & CF_RETREAT_WHEN_INJURED and
1527 std::find(soldiers.begin(), soldiers.end(), m_battle->opponent(*this))1521 attackdefense->ui32var3 > get_current_hitpoints()))
1528 ==
1529 soldiers.end()))
1530 {1522 {
1531 if (commit && soldiers.size() == 1) {1523 // Retreating or non-combatant soldiers act like normal bobs
1532 Soldier & soldier = ref_cast<Soldier, Bob>(*soldiers[0]);1524 return Bob::checkNodeBlocked(game, field, commit);
1533 if (soldier.get_owner() != get_owner() && soldier.canBeChallenged()) {1525 }
1526
1527 if (field.field->get_immovable() && field.field->get_immovable() == get_location(game)) {
1528 if (commit)
1529 sendSpaceSignals(game);
1530 return false; // we can always walk home
1531 }
1532
1533 Soldier * foundsoldier = 0;
1534 bool foundbattle = false;
1535 bool foundopponent = false;
1536 bool multiplesoldiers = false;
1537
1538 for (Bob * bob = field.field->get_first_bob(); bob; bob = bob->get_next_on_field()) {
1539 if (upcast(Soldier, soldier, bob)) {
1540 if (!soldier->isOnBattlefield() || !soldier->get_current_hitpoints())
1541 continue;
1542
1543 if (!foundsoldier) {
1544 foundsoldier = soldier;
1545 } else {
1546 multiplesoldiers = true;
1547 }
1548
1549 if (soldier->getBattle()) {
1550 foundbattle = true;
1551
1552 if (m_battle && m_battle->opponent(*this) == soldier)
1553 foundopponent = true;
1554 }
1555 }
1556 }
1557
1558 if (!foundopponent && (foundbattle || foundsoldier)) {
1559 if (commit && !foundbattle && !multiplesoldiers) {
1560 if (foundsoldier->get_owner() != get_owner() && foundsoldier->canBeChallenged()) {
1534 molog1561 molog
1535 ("[checkNodeBlocked] attacking a soldier (%u)\n",1562 ("[checkNodeBlocked] attacking a soldier (%u)\n",
1536 soldier.serial());1563 foundsoldier->serial());
1537 new Battle(game, *this, soldier);1564 new Battle(game, *this, *foundsoldier);
1538 }1565 }
1539 }1566 }
15401567
1541 /// Only battles block retreating soldiers
1542 State * state = 0;
1543
1544 if (get_state(taskAttack)) {
1545 state = get_state(taskAttack);
1546 }
1547 if (get_state(taskDefense)) {
1548 state = get_state(taskDefense);
1549 }
1550 if (state) {
1551 if
1552 (state->ivar1 & CF_RETREAT_WHEN_INJURED and
1553 state->ui32var3 > get_current_hitpoints())
1554 {
1555 // Retreating soldiers act like normal bobs
1556 return Bob::checkNodeBlocked(game, field, commit);
1557 }
1558 }
1559 return true;1568 return true;
1569 } else {
1570 if (commit)
1571 sendSpaceSignals(game);
1572 return false;
1560 }1573 }
1561
1562 if (commit)
1563 sendSpaceSignals(game);
1564 return false;
1565}1574}
15661575
15671576
15681577
=== modified file 'src/logic/worker.cc'
--- src/logic/worker.cc 2010-03-21 20:09:51 +0000
+++ src/logic/worker.cc 2010-04-13 18:44:39 +0000
@@ -453,15 +453,18 @@
453453
454 Map & map = game.map();454 Map & map = game.map();
455 Area<FCoords> area (map.get_fcoords(get_position()), 0);455 Area<FCoords> area (map.get_fcoords(get_position()), 0);
456 if (action.sparam1 == "immovable")456 if (action.sparam1 == "immovable") {
457 bool found_reserved = false;
458
457 for (;; ++area.radius) {459 for (;; ++area.radius) {
458 if (action.iparam1 < area.radius) {460 if (action.iparam1 < area.radius) {
459 send_signal(game, "fail"); // no object found, cannot run program461 send_signal(game, "fail"); // no object found, cannot run program
460 pop_task(game);462 pop_task(game);
461 informPlayer463 if (!found_reserved)
462 (game,464 informPlayer
463 ref_cast<Building, PlayerImmovable>(*get_location(game)),465 (game,
464 Map_Object_Descr::get_attribute_name(action.iparam2));466 ref_cast<Building, PlayerImmovable>(*get_location(game)),
467 Map_Object_Descr::get_attribute_name(action.iparam2));
465 return true;468 return true;
466 }469 }
467 std::vector<ImmovableFound> list;470 std::vector<ImmovableFound> list;
@@ -472,12 +475,21 @@
472 map.find_reachable_immovables475 map.find_reachable_immovables
473 (area, &list, cstep, FindImmovableAttribute(action.iparam2));476 (area, &list, cstep, FindImmovableAttribute(action.iparam2));
474477
478 for (int idx = list.size() - 1; idx >= 0; idx--) {
479 if (upcast(Immovable, imm, list[idx].object)) {
480 if (imm->is_reserved_by_worker()) {
481 found_reserved = true;
482 list.erase(list.begin() + idx);
483 }
484 }
485 }
486
475 if (list.size()) {487 if (list.size()) {
476 state.objvar1 = list[game.logic_rand() % list.size()].object;488 set_program_objvar(game, state, list[game.logic_rand() % list.size()].object);
477 break;489 break;
478 }490 }
479 }491 }
480 else492 } else {
481 for (;; ++area.radius) {493 for (;; ++area.radius) {
482 if (action.iparam1 < area.radius) {494 if (action.iparam1 < area.radius) {
483 send_signal(game, "fail"); // no object found, cannot run program495 send_signal(game, "fail"); // no object found, cannot run program
@@ -497,10 +509,11 @@
497 (area, &list, cstep, FindBobAttribute(action.iparam2));509 (area, &list, cstep, FindBobAttribute(action.iparam2));
498510
499 if (list.size()) {511 if (list.size()) {
500 state.objvar1 = list[game.logic_rand() % list.size()];512 set_program_objvar(game, state, list[game.logic_rand() % list.size()]);
501 break;513 break;
502 }514 }
503 }515 }
516 }
504517
505 ++state.ivar1;518 ++state.ivar1;
506 schedule_act(game, 10);519 schedule_act(game, 10);
@@ -1701,7 +1714,7 @@
1701 "program",1714 "program",
1702 static_cast<Bob::Ptr>(&Worker::program_update),1715 static_cast<Bob::Ptr>(&Worker::program_update),
1703 0,1716 0,
1704 0,1717 static_cast<Bob::Ptr>(&Worker::program_pop),
1705 false1718 false
1706};1719};
17071720
@@ -1739,6 +1752,25 @@
1739 }1752 }
1740}1753}
17411754
1755void Worker::program_pop(Game & game, State & state)
1756{
1757 set_program_objvar(game, state, 0);
1758}
1759
1760void Worker::set_program_objvar(Game & game, State & state, Map_Object * obj)
1761{
1762 assert(state.task == &taskProgram);
1763
1764 if (upcast(Immovable, imm, state.objvar1.get(game))) {
1765 imm->set_reserved_by_worker(false);
1766 }
1767
1768 state.objvar1 = obj;
1769
1770 if (upcast(Immovable, imm, obj)) {
1771 imm->set_reserved_by_worker(true);
1772 }
1773}
17421774
1743const Bob::Task Worker::taskGowarehouse = {1775const Bob::Task Worker::taskGowarehouse = {
1744 "gowarehouse",1776 "gowarehouse",
17451777
=== modified file 'src/logic/worker.h'
--- src/logic/worker.h 2010-02-28 18:40:36 +0000
+++ src/logic/worker.h 2010-04-13 18:44:39 +0000
@@ -181,6 +181,8 @@
181181
182 bool does_carry_ware() {return m_carried_item.is_set();}182 bool does_carry_ware() {return m_carried_item.is_set();}
183183
184 void set_program_objvar(Game &, State &, Map_Object * obj);
185
184public:186public:
185 static const Task taskTransfer;187 static const Task taskTransfer;
186 static const Task taskBuildingwork;188 static const Task taskBuildingwork;
@@ -203,6 +205,7 @@
203 void buildingwork_update(Game &, State &);205 void buildingwork_update(Game &, State &);
204 void return_update(Game &, State &);206 void return_update(Game &, State &);
205 void program_update(Game &, State &);207 void program_update(Game &, State &);
208 void program_pop(Game &, State &);
206 void gowarehouse_update(Game &, State &);209 void gowarehouse_update(Game &, State &);
207 void gowarehouse_signalimmediate210 void gowarehouse_signalimmediate
208 (Game &,211 (Game &,
209212
=== modified file 'src/ui_basic/editbox.cc'
--- src/ui_basic/editbox.cc 2010-03-27 23:50:23 +0000
+++ src/ui_basic/editbox.cc 2010-04-13 18:44:39 +0000
@@ -46,6 +46,9 @@
46 /// Position of the caret.46 /// Position of the caret.
47 uint32_t caret;47 uint32_t caret;
4848
49 /// Current scrolling offset to the text anchor position, in pixels
50 int32_t scrolloffset;
51
49 /// Alignment of the text. Vertical alignment is always centered.52 /// Alignment of the text. Vertical alignment is always centered.
50 Align align;53 Align align;
51};54};
@@ -69,8 +72,9 @@
6972
70 m->id = id;73 m->id = id;
71 m->align = static_cast<Align>((_align & Align_Horizontal) | Align_VCenter);74 m->align = static_cast<Align>((_align & Align_Horizontal) | Align_VCenter);
75 m->caret = 0;
76 m->scrolloffset = 0;
72 // yes, use *signed* max as maximum length; just a small safe-guard.77 // yes, use *signed* max as maximum length; just a small safe-guard.
73 m->caret = 0;
74 m->maxLength = std::numeric_limits<int32_t>::max();78 m->maxLength = std::numeric_limits<int32_t>::max();
7579
76 set_handle_mouse(true);80 set_handle_mouse(true);
@@ -138,6 +142,7 @@
138 if (m->caret > m->text.size())142 if (m->caret > m->text.size())
139 m->caret = m->text.size();143 m->caret = m->text.size();
140144
145 check_caret();
141 update();146 update();
142 }147 }
143}148}
@@ -163,6 +168,8 @@
163 _align = static_cast<Align>((_align & Align_Horizontal) | Align_VCenter);168 _align = static_cast<Align>((_align & Align_Horizontal) | Align_VCenter);
164 if (_align != m->align) {169 if (_align != m->align) {
165 m->align = _align;170 m->align = _align;
171 m->scrolloffset = 0;
172 check_caret();
166 update();173 update();
167 }174 }
168}175}
@@ -220,6 +227,7 @@
220 while ((m->text[--m->caret] & 0xc0) == 0x80)227 while ((m->text[--m->caret] & 0xc0) == 0x80)
221 m->text.erase(m->text.begin() + m->caret);228 m->text.erase(m->text.begin() + m->caret);
222 m->text.erase(m->text.begin() + m->caret);229 m->text.erase(m->text.begin() + m->caret);
230 check_caret();
223 changed.call();231 changed.call();
224 changedid.call(m->id);232 changedid.call(m->id);
225 update();233 update();
@@ -233,6 +241,7 @@
233 for (uint32_t new_caret = m->caret;; m->caret = new_caret)241 for (uint32_t new_caret = m->caret;; m->caret = new_caret)
234 if (0 == new_caret or isspace(m->text[--new_caret]))242 if (0 == new_caret or isspace(m->text[--new_caret]))
235 break;243 break;
244 check_caret();
236 update();245 update();
237 }246 }
238 return true;247 return true;
@@ -250,6 +259,7 @@
250 m->caret = new_caret;259 m->caret = new_caret;
251 break;260 break;
252 }261 }
262 check_caret();
253 update();263 update();
254 }264 }
255 return true;265 return true;
@@ -257,6 +267,7 @@
257 case SDLK_HOME:267 case SDLK_HOME:
258 if (m->caret != 0) {268 if (m->caret != 0) {
259 m->caret = 0;269 m->caret = 0;
270 check_caret();
260 update();271 update();
261 }272 }
262 return true;273 return true;
@@ -264,6 +275,7 @@
264 case SDLK_END:275 case SDLK_END:
265 if (m->caret != m->text.size()) {276 if (m->caret != m->text.size()) {
266 m->caret = m->text.size();277 m->caret = m->text.size();
278 check_caret();
267 update();279 update();
268 }280 }
269 return true;281 return true;
@@ -296,6 +308,7 @@
296 (m->text.begin() + m->caret++,308 (m->text.begin() + m->caret++,
297 ((code.unicode & 0x3f) | 0x80));309 ((code.unicode & 0x3f) | 0x80));
298 }310 }
311 check_caret();
299 changed.call();312 changed.call();
300 changedid.call(m->id);313 changedid.call(m->id);
301 update();314 update();
@@ -354,6 +367,8 @@
354 break;367 break;
355 }368 }
356369
370 pos.x += m->scrolloffset;
371
357 UI::g_fh->draw_string372 UI::g_fh->draw_string
358 (dst,373 (dst,
359 m_fontname, m_fontsize, m_fontcolor, UI_FONT_CLR_BG,374 m_fontname, m_fontsize, m_fontcolor, UI_FONT_CLR_BG,
@@ -367,4 +382,46 @@
367 std::numeric_limits<uint32_t>::max());382 std::numeric_limits<uint32_t>::max());
368}383}
369384
385/**
386 * Check the caret's position and scroll it into view if necessary.
387 */
388void EditBox::check_caret()
389{
390 std::string leftstr(m->text, 0, m->caret);
391 std::string rightstr(m->text, m->caret, std::string::npos);
392 uint32_t leftw;
393 uint32_t rightw;
394 uint32_t tmp;
395
396 UI::g_fh->get_size(m_fontname, m_fontsize, leftstr, leftw, tmp);
397 UI::g_fh->get_size(m_fontname, m_fontsize, rightstr, rightw, tmp);
398
399 int32_t caretpos;
400
401 switch (m->align & Align_Horizontal) {
402 case Align_HCenter:
403 caretpos = (get_w() - static_cast<int32_t>(leftw + rightw)) / 2 + m->scrolloffset + leftw;
404 break;
405 case Align_Right:
406 caretpos = get_w() - 4 + m->scrolloffset - rightw;
407 break;
408 default:
409 caretpos = 4 + m->scrolloffset + leftw;
410 break;
411 }
412
413 if (caretpos < 4)
414 m->scrolloffset += 4 - caretpos + get_w()/5;
415 else if (caretpos > get_w() - 4)
416 m->scrolloffset -= caretpos - get_w() + 4 + get_w()/5;
417
418 if ((m->align & Align_Horizontal) == Align_Left) {
419 if (m->scrolloffset > 0)
420 m->scrolloffset = 0;
421 } else if ((m->align & Align_Horizontal) == Align_Right) {
422 if (m->scrolloffset < 0)
423 m->scrolloffset = 0;
424 }
425}
426
370}427}
371428
=== modified file 'src/ui_basic/editbox.h'
--- src/ui_basic/editbox.h 2010-03-27 23:50:23 +0000
+++ src/ui_basic/editbox.h 2010-04-13 18:44:39 +0000
@@ -74,6 +74,8 @@
74 RGBColor m_fontcolor;74 RGBColor m_fontcolor;
7575
76 boost::scoped_ptr<EditBoxImpl> m;76 boost::scoped_ptr<EditBoxImpl> m;
77
78 void check_caret();
77};79};
7880
79}81}
8082
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2010-04-12 09:11:24 +0000
+++ src/wlapplication.cc 2010-04-13 18:44:39 +0000
@@ -1116,6 +1116,12 @@
1116 m_commandline.erase("double");1116 m_commandline.erase("double");
1117 }1117 }
11181118
1119 if (m_commandline.count("verbose")) {
1120 g_verbose = true;
1121
1122 m_commandline.erase("verbose");
1123 }
1124
1119 if (m_commandline.count("editor")) {1125 if (m_commandline.count("editor")) {
1120 m_filename = m_commandline["editor"];1126 m_filename = m_commandline["editor"];
1121 if (m_filename.size() and *m_filename.rbegin() == '/')1127 if (m_filename.size() and *m_filename.rbegin() == '/')
@@ -1332,6 +1338,7 @@
1332 " testing)\n\n");1338 " testing)\n\n");
1333#endif1339#endif
1334#endif1340#endif
1341 wout << _(" --verbose Enable verbose debug messages\n") << endl;
1335 wout << _(" --help Show this help\n") << endl;1342 wout << _(" --help Show this help\n") << endl;
1336 wout1343 wout
1337 <<1344 <<

Subscribers

People subscribed via source and target branches

to status/vote changes: