Skip to content

Commit

Permalink
feat(port): UI, accessibility updates, tweaks (cataclysmbnteam#4636)
Browse files Browse the repository at this point in the history
* Port UI, accessibility updates, tweaks

Co-Authored-By: Zhilkin Serg <ZhilkinSerg@users.noreply.github.com>
Co-Authored-By: Chaosvolt <chaosvolt@users.noreply.github.com>
Co-Authored-By: Jianxiang Wang (王健翔) <qrox@sina.com>
Co-Authored-By: Rob Kuijper <robkuijper@live.nl>
Co-Authored-By: Brambor <13402666+Brambor@users.noreply.github.com>
Co-Authored-By: eltank <8000047+eltank@users.noreply.github.com>
Co-Authored-By: David Seguin <davidseguin@live.ca>
Co-Authored-By: ZeroInternalReflection <89038572+zerointernalreflection@users.noreply.github.com>
Co-Authored-By: martinrhan <53336429+martinrhan@users.noreply.github.com>
Co-Authored-By: Mark Langsdorf <mlangsdo@redhat.com>
Co-Authored-By: BevapDin <5095435+bevapdin@users.noreply.github.com>

* style(autofix.ci): automated formatting

* Misc tweaks update

* Misc tweaks update

Co-Authored-By: Zhilkin Serg <ZhilkinSerg@users.noreply.github.com>
Co-Authored-By: Olanti <olanti-p@yandex.ru>
Co-Authored-By: Coolthulhu <Coolthulhu@gmail.com>

* style(autofix.ci): automated formatting

* Misc tweaks update

* Misc tweaks update

* Misc tweaks update

* Misc tweaks update

Co-Authored-By: Jianxiang Wang (王健翔) <qrox@sina.com>
Co-Authored-By: Coolthulhu <Coolthulhu@gmail.com>

* style(autofix.ci): automated formatting

* Misc tweaks update

* style(autofix.ci): automated formatting

* Misc tweaks update

* style(autofix.ci): automated formatting

* Misc tweaks update

* Misc tweaks update

---------

Co-Authored-By: Zhilkin Serg <ZhilkinSerg@users.noreply.github.com>
Co-Authored-By: Chaosvolt <chaosvolt@users.noreply.github.com>
Co-Authored-By: Jianxiang Wang (王健翔) <qrox@sina.com>
Co-Authored-By: Rob Kuijper <robkuijper@live.nl>
Co-Authored-By: Brambor <13402666+Brambor@users.noreply.github.com>
Co-Authored-By: eltank <8000047+eltank@users.noreply.github.com>
Co-Authored-By: David Seguin <davidseguin@live.ca>
Co-Authored-By: ZeroInternalReflection <89038572+zerointernalreflection@users.noreply.github.com>
Co-Authored-By: martinrhan <53336429+martinrhan@users.noreply.github.com>
Co-Authored-By: Mark Langsdorf <mlangsdo@redhat.com>
Co-Authored-By: BevapDin <5095435+bevapdin@users.noreply.github.com>
Co-Authored-By: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-Authored-By: Olanti <olanti-p@yandex.ru>
Co-Authored-By: Coolthulhu <Coolthulhu@gmail.com>
  • Loading branch information
15 people committed May 30, 2024
1 parent 27cf366 commit 3dac7c4
Show file tree
Hide file tree
Showing 60 changed files with 1,270 additions and 937 deletions.
45 changes: 11 additions & 34 deletions doc/src/content/docs/en/dev/explanation/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,14 @@
title: Compatibility with screen readers
---

There are people who uses screen readers to play Cataclysm DDA. In order for screen readers to
announce the most important information in a UI, the terminal cursor has to be placed at the correct
location. This information may be text such as selected item names in a list, etc, and the cursor
has to be placed exactly at the beginning of the text for screen readers to announce it.

`wmove` in `output.h|cpp` is the function to move the cursor to a specific location. After calling
`wmove` with the target `catacurses::window` and cursor position, `wrefresh` needs to be called
immediately afterwards for `wmove` to take effect.

Here is an example of placing the cursor explicitly at the beginning of a piece of text:

```cpp
catacurses::window win = ...; // target window

...

// display code
point cursor_position = ...; // default cursor position

...

cursor_position = point_zero; // record the start position of the text
fold_and_print( win, cursor_position, getmaxx( win ), c_white, _( "This text is important" ) );

...

// at the end of display code
wmove( win, cursor_position );
wrefresh( win );
// no output code should follow as they might change the cursor position
```
As shown in the above example, it is preferable to record the intended cursor position in a variable
when the text is printed, and move the cursor later using the variable to ensure consisitency.
There are people who use screen readers to play Cataclysm Bright Nights. In order for screen readers
to announce the most important information in a UI, the terminal cursor has to be placed at the
correct location. This information may be text such as selected item names in a list, etc, and the
cursor has to be placed exactly at the beginning of the text for screen readers to announce it.

The recommended way to place the cursor is to use `ui_adaptor`. This ensures the desired cursor
position is preserved when subsequent output code changes the cursor position. You can call
`ui_adaptor::set_cursor` and similar methods at any position in a redrawing callback, and the last
cursor position of the topmost UI set via the call will be used as the final cursor position. You
can also call `ui_adaptor::disable_cursor` to prevent a UI's cursor from being used as the final
cursor position.
30 changes: 17 additions & 13 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@
#include "vehicle_part.h"
#include "vpart_position.h"

enum creature_size : int;

static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" );
static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" );
static const activity_id ACT_ATM( "ACT_ATM" );
Expand Down Expand Up @@ -595,7 +597,7 @@ butchery_setup consider_butchery( const item &corpse_item, player &u, butcher_ty
inv.has_amount( itype_hd_tow_cable, 1 ) ||
inv.has_amount( itype_vine_30, 1 ) ||
inv.has_amount( itype_grapnel, 1 );
const bool big_corpse = corpse.size >= MS_MEDIUM;
const bool big_corpse = corpse.size >= creature_size::medium;

if( big_corpse ) {
if( has_rope && !has_tree_nearby && !b_rack_present ) {
Expand Down Expand Up @@ -635,7 +637,7 @@ butchery_setup consider_butchery( const item &corpse_item, player &u, butcher_ty
}

if( action == QUARTER ) {
if( corpse.size == MS_TINY ) {
if( corpse.size == creature_size::tiny ) {
not_this_one( _( "This corpse is too small to quarter without damaging." ),
butcherable_rating::too_small );
}
Expand Down Expand Up @@ -721,22 +723,22 @@ static void set_up_butchery_activity( player_activity &act, player &u, const but
act.index = false;
}

static int size_factor_in_time_to_cut( m_size size )
static int size_factor_in_time_to_cut( creature_size size )
{
switch( size ) {
// Time (roughly) in turns to cut up the corpse
case MS_TINY:
case creature_size::tiny:
return 150;
case MS_SMALL:
case creature_size::small:
return 300;
case MS_MEDIUM:
case creature_size::medium:
return 450;
case MS_LARGE:
case creature_size::large:
return 600;
case MS_HUGE:
case creature_size::huge:
return 1800;
default:
debugmsg( "Invalid m_size value for butchering corpse: %d", static_cast<int>( size ) );
debugmsg( "Invalid creature_size value for butchering corpse: %d", static_cast<int>( size ) );
break;
}
return 0;
Expand Down Expand Up @@ -950,7 +952,7 @@ static void butchery_drops_harvest( item *corpse_item, const mtype &mt, player &
roll = roll / 4;
} else if( entry.type == "bone" ) {
roll /= 2;
} else if( corpse_item->get_mtype()->size >= MS_MEDIUM && ( entry.type == "skin" ) ) {
} else if( corpse_item->get_mtype()->size >= creature_size::medium && ( entry.type == "skin" ) ) {
roll /= 2;
} else if( entry.type == "offal" ) {
roll /= 5;
Expand Down Expand Up @@ -1094,7 +1096,8 @@ static void butchery_drops_harvest( item *corpse_item, const mtype &mt, player &
// 20% of the original corpse weight is not an item, but liquid gore

if( action != DISSECT ) {
p.practice( skill_survival, std::max( 0, practice ), std::max( mt.size - MS_MEDIUM, 0 ) + 4 );
p.practice( skill_survival, std::max( 0, practice ), std::max( mt.size - creature_size::medium,
0 ) + 4 );
}
}

Expand Down Expand Up @@ -1252,8 +1255,9 @@ void activity_handlers::butcher_finish( player_activity *act, player *p )
extract_or_wreck_cbms( cbms, roll, *p );
// those lines are for XP gain with dissecting. It depends on the size of the corpse, time to dissect the corpse and the amount of bionics you would gather.
int time_to_cut = size_factor_in_time_to_cut( corpse->size );
int level_cap = std::min<int>( MAX_SKILL, ( corpse->size + ( cbms.size() * 2 + 1 ) ) );
int size_mult = corpse->size > MS_MEDIUM ? ( corpse->size * corpse->size ) : 8;
int level_cap = std::min<int>( MAX_SKILL,
( static_cast<int>( corpse->size ) + ( cbms.size() * 2 + 1 ) ) );
int size_mult = corpse->size > creature_size::medium ? ( corpse->size * corpse->size ) : 8;
int practice_amt = ( size_mult + 1 ) * ( ( time_to_cut / 150 ) + 1 ) *
( cbms.size() * cbms.size() / 2 + 1 );
p->practice( skill_firstaid, practice_amt, level_cap );
Expand Down
4 changes: 2 additions & 2 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,7 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe
// make sure nobody else is working on that corpse right now
if( i->is_corpse() && !i->has_var( "activity_var" ) ) {
const mtype corpse = *i->get_mtype();
if( corpse.size >= MS_MEDIUM ) {
if( corpse.size >= creature_size::medium ) {
big_count += 1;
} else {
small_count += 1;
Expand Down Expand Up @@ -2140,7 +2140,7 @@ static bool butcher_corpse_activity( player &p, const tripoint &src_loc,
for( auto &elem : items ) {
if( elem->is_corpse() && !elem->has_var( "activity_var" ) ) {
const mtype corpse = *elem->get_mtype();
if( corpse.size >= MS_MEDIUM && reason != do_activity_reason::NEEDS_BIG_BUTCHERING ) {
if( corpse.size >= creature_size::medium && reason != do_activity_reason::NEEDS_BIG_BUTCHERING ) {
continue;
}
elem->set_var( "activity_var", p.name );
Expand Down
4 changes: 2 additions & 2 deletions src/armor_layers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ void show_armor_layers_ui( Character &who )
int leftListSize = 0;
int rightListSize = 0;

ui.on_redraw( [&]( const ui_adaptor & ) {
ui.on_redraw( [&]( ui_adaptor & ui ) {
draw_grid( w_sort_armor, left_w, middle_w );

werase( w_sort_cat );
Expand Down Expand Up @@ -638,7 +638,7 @@ void show_armor_layers_ui( Character &who )
}

mvwprintz( w_encumb, point_east, c_white, _( "Encumbrance and Warmth" ) );
character_display::print_encumbrance( w_encumb, who, -1,
character_display::print_encumbrance( ui, w_encumb, who, -1,
( leftListSize > 0 ) ? *access_tmp_worn( leftListIndex ) : nullptr );

// Right header
Expand Down
6 changes: 3 additions & 3 deletions src/ballistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ static void drop_or_embed_projectile( dealt_projectile_attack &attack )
!proj.has_effect( ammo_effect_TANGLE );
// Don't embed in small creatures
if( embed ) {
const m_size critter_size = mon->get_size();
const creature_size critter_size = mon->get_size();
const units::volume vol = drop_item.volume();
embed = embed && ( critter_size > MS_TINY || vol < 250_ml );
embed = embed && ( critter_size > MS_SMALL || vol < 500_ml );
embed = embed && ( critter_size > creature_size::tiny || vol < 250_ml );
embed = embed && ( critter_size > creature_size::small || vol < 500_ml );
// And if we deal enough damage
// Item volume bumps up the required damage too
embed = embed &&
Expand Down
2 changes: 1 addition & 1 deletion src/catalua_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ void cata::detail::reg_enums( sol::state &lua )
reg_enum<mf_attitude>( lua );
reg_enum<m_flag>( lua );
reg_enum<monster_attitude>( lua );
reg_enum<m_size>( lua );
reg_enum<creature_size>( lua );
reg_enum<npc_attitude>( lua );
reg_enum<npc_need>( lua );
reg_enum<sfx::channel>( lua );
Expand Down
2 changes: 1 addition & 1 deletion src/catalua_bindings_creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void cata::detail::reg_creature( sol::state &lua )
SET_FX_T( get_hit, float() const );

SET_FX_T( get_speed, int() const );
SET_FX_T( get_size, m_size() const );
SET_FX_T( get_size, creature_size() const );
luna::set_fx( ut, "get_hp", []( const Creature & cr,
sol::optional<const bodypart_id &> bpid ) -> int {
if( bpid.has_value() )
Expand Down
4 changes: 2 additions & 2 deletions src/catalua_luna_doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum color_id : int;
enum damage_type : int;
enum game_message_type : int;
enum m_flag : int;
enum m_size : int;
enum creature_size : int;
enum mf_attitude : int;
enum monster_attitude : int;
enum npc_attitude : int;
Expand Down Expand Up @@ -164,7 +164,7 @@ LUNA_ENUM( game_message_type, "MsgType" )
LUNA_ENUM( mf_attitude, "MonsterFactionAttitude" )
LUNA_ENUM( m_flag, "MonsterFlag" )
LUNA_ENUM( monster_attitude, "MonsterAttitude" )
LUNA_ENUM( m_size, "MonsterSize" )
LUNA_ENUM( creature_size, "MonsterSize" )
LUNA_ENUM( npc_attitude, "NpcAttitude" )
LUNA_ENUM( npc_need, "NpcNeed" )
LUNA_ENUM( sfx::channel, "SfxChannel" )
Expand Down
26 changes: 14 additions & 12 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ void Character::mod_stat( const std::string &stat, float modifier )
}
}

m_size Character::get_size() const
creature_size Character::get_size() const
{
return size_class;
}
Expand Down Expand Up @@ -1404,7 +1404,7 @@ bool Character::check_mount_is_spooked()
// / 2 if horse has full tack and saddle.
// Monster in spear reach monster and average stat (8) player on saddled horse, 14% -2% -0.8% / 2 = ~5%
if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
const m_size mount_size = mounted_creature->get_size();
const creature_size mount_size = mounted_creature->get_size();
const bool saddled = mounted_creature->has_effect( effect_saddled );
for( const monster &critter : g->all_monsters() ) {
double chance = 1.0;
Expand Down Expand Up @@ -2495,7 +2495,7 @@ detached_ptr<item> Character::wear_item( detached_ptr<item> &&wear,
}

const bool was_deaf = is_deaf();
const bool supertinymouse = get_size() == MS_TINY;
const bool supertinymouse = get_size() == creature_size::tiny;
last_item = to_wear.typeId();


Expand Down Expand Up @@ -5402,7 +5402,7 @@ void Character::update_needs( int rate_multiplier )
}

// Huge folks take penalties for cramming themselves in vehicles
if( in_vehicle && ( get_size() == MS_HUGE )
if( in_vehicle && ( get_size() == creature_size::huge )
&& !( has_trait( trait_NOPAIN ) || has_effect( effect_narcosis ) ) ) {
vehicle *veh = veh_pointer_or_null( get_map().veh_at( pos() ) );
// it's painful to work the controls, but passengers in open topped vehicles are fine
Expand Down Expand Up @@ -7341,15 +7341,15 @@ std::string Character::height_string() const
int Character::height() const
{
switch( get_size() ) {
case MS_TINY:
case creature_size::tiny:
return init_height - 100;
case MS_SMALL:
case creature_size::small:
return init_height - 50;
case MS_MEDIUM:
case creature_size::medium:
return init_height;
case MS_LARGE:
case creature_size::large:
return init_height + 50;
case MS_HUGE:
case creature_size::huge:
return init_height + 100;
default:
break;
Expand Down Expand Up @@ -10556,7 +10556,7 @@ float Character::power_rating() const
} else if( dmg > 12 ) {
ret = 3; // Melee weapon or weapon-y tool
}
if( get_size() == MS_HUGE ) {
if( get_size() == creature_size::huge ) {
ret += 1;
}
if( is_wearing_power_armor( nullptr ) ) {
Expand Down Expand Up @@ -11569,7 +11569,8 @@ void Character::knock_back_to( const tripoint &to )

// First, see if we hit a monster
if( monster *const critter = g->critter_at<monster>( to ) ) {
deal_damage( critter, bodypart_id( "torso" ), damage_instance( DT_BASH, critter->type->size ) );
deal_damage( critter, bodypart_id( "torso" ), damage_instance( DT_BASH,
static_cast<float>( critter->type->size ) ) );
add_effect( effect_stunned, 1_turns );
/** @EFFECT_STR_MAX allows knocked back player to knock back, damage, stun some monsters */
if( ( str_max - 6 ) / 4 > critter->type->size ) {
Expand All @@ -11588,7 +11589,8 @@ void Character::knock_back_to( const tripoint &to )
}

if( npc *const np = g->critter_at<npc>( to ) ) {
deal_damage( np, bodypart_id( "torso" ), damage_instance( DT_BASH, np->get_size() + 1 ) );
deal_damage( np, bodypart_id( "torso" ), damage_instance( DT_BASH,
static_cast<float>( np->get_size() + 1 ) ) );
add_effect( effect_stunned, 1_turns );
np->deal_damage( this, bodypart_id( "torso" ), damage_instance( DT_BASH, 3 ) );
add_msg_player_or_npc( _( "You bounce off %s!" ), _( "<npcname> bounces off %s!" ),
Expand Down
4 changes: 2 additions & 2 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ class Character : public Creature, public location_visitable<Character>
void mod_stat( const std::string &stat, float modifier ) override;

/** Get size class of character **/
m_size get_size() const override;
creature_size get_size() const override;
/** Recalculate size class of character **/
void recalculate_size();

Expand Down Expand Up @@ -2209,7 +2209,7 @@ class Character : public Creature, public location_visitable<Character>
/**height at character creation*/
int init_height = 175;
/** Size class of character. */
m_size size_class = MS_MEDIUM;
creature_size size_class = creature_size::medium;

trap_map known_traps;
pimpl<char_encumbrance_data> encumbrance_cache;
Expand Down
Loading

0 comments on commit 3dac7c4

Please sign in to comment.