added support for cursors
This commit is contained in:
parent
35a30b1fa0
commit
14ed0e4385
13 changed files with 186 additions and 3 deletions
BIN
images/cursors-bw/attack.png
Normal file
BIN
images/cursors-bw/attack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 304 B |
BIN
images/cursors-bw/move.png
Normal file
BIN
images/cursors-bw/move.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 192 B |
BIN
images/cursors-bw/normal.png
Normal file
BIN
images/cursors-bw/normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 181 B |
BIN
images/cursors-bw/wait.png
Normal file
BIN
images/cursors-bw/wait.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 280 B |
115
src/cursor.cpp
Normal file
115
src/cursor.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "cursor.hpp"
|
||||
#include "image.hpp"
|
||||
#include "preferences.hpp"
|
||||
#include "scoped_resource.hpp"
|
||||
#include "sdl_utils.hpp"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
SDL_Cursor* create_cursor(SDL_Surface* surface)
|
||||
{
|
||||
const scoped_sdl_surface surf(make_neutral_surface(surface));
|
||||
if(surf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//the width must be a multiple of 8 (SDL requirement)
|
||||
size_t cursor_width = surf->w;
|
||||
if((cursor_width%8) != 0) {
|
||||
cursor_width += 8 - (cursor_width%8);
|
||||
}
|
||||
|
||||
std::vector<Uint8> data((cursor_width*surf->h)/8,0);
|
||||
std::vector<Uint8> mask(data.size(),0);
|
||||
|
||||
//see http://sdldoc.csn.ul.ie/sdlcreatecursor.php for documentation on
|
||||
//the format that data has to be in to pass to SDL_CreateCursor
|
||||
surface_lock lock(surf);
|
||||
const Uint32* const pixels = reinterpret_cast<Uint32*>(lock.pixels());
|
||||
for(size_t y = 0; y != surf->h; ++y) {
|
||||
for(size_t x = 0; x != surf->w; ++x) {
|
||||
Uint8 r,g,b,a;
|
||||
SDL_GetRGBA(pixels[y*surf->w + x],surf->format,&r,&g,&b,&a);
|
||||
|
||||
const size_t index = y*cursor_width + x;
|
||||
|
||||
const size_t shift = 7 - (index%8);
|
||||
|
||||
const Uint8 trans = (a < 128 ? 0 : 1) << shift;
|
||||
const Uint8 black = (trans == 0 || (r+g+b)/3 > 128 ? 0 : 1) << shift;
|
||||
|
||||
data[index/8] |= black;
|
||||
mask[index/8] |= trans;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_CreateCursor(&data[0],&mask[0],cursor_width,surf->h,0,0);
|
||||
}
|
||||
|
||||
SDL_Cursor* cache[cursor::NUM_CURSORS] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
//this array must have members corresponding to cursor::CURSOR_TYPE enum members
|
||||
const std::string images[cursor::NUM_CURSORS] = { "normal.png", "wait.png", "move.png", "attack.png" };
|
||||
|
||||
cursor::CURSOR_TYPE current_cursor = cursor::NUM_CURSORS;
|
||||
|
||||
SDL_Cursor* get_cursor(cursor::CURSOR_TYPE type)
|
||||
{
|
||||
if(cache[type] == NULL) {
|
||||
static const std::string prefix = "cursors-bw/";
|
||||
const scoped_sdl_surface surf(image::get_image(prefix + images[type],image::UNSCALED));
|
||||
cache[type] = create_cursor(surf);
|
||||
}
|
||||
|
||||
return cache[type];
|
||||
}
|
||||
|
||||
void clear_cache()
|
||||
{
|
||||
for(size_t n = 0; n != cursor::NUM_CURSORS; ++n) {
|
||||
if(cache[n] != NULL) {
|
||||
SDL_FreeCursor(cache[n]);
|
||||
cache[n] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace cursor
|
||||
{
|
||||
|
||||
manager::manager()
|
||||
{
|
||||
}
|
||||
|
||||
manager::~manager()
|
||||
{
|
||||
clear_cache();
|
||||
}
|
||||
|
||||
void set(CURSOR_TYPE type)
|
||||
{
|
||||
SDL_Cursor* const cursor = get_cursor(type);
|
||||
if(cursor != NULL) {
|
||||
SDL_SetCursor(cursor);
|
||||
current_cursor = type;
|
||||
}
|
||||
}
|
||||
|
||||
setter::setter(CURSOR_TYPE type) : old_(current_cursor)
|
||||
{
|
||||
set(type);
|
||||
}
|
||||
|
||||
setter::~setter()
|
||||
{
|
||||
set(old_);
|
||||
}
|
||||
|
||||
}
|
28
src/cursor.hpp
Normal file
28
src/cursor.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef CURSOR_HPP_INCLUDED
|
||||
#define CURSOR_HPP_INCLUDED
|
||||
|
||||
namespace cursor
|
||||
{
|
||||
|
||||
struct manager
|
||||
{
|
||||
manager();
|
||||
~manager();
|
||||
};
|
||||
|
||||
enum CURSOR_TYPE { NORMAL, WAIT, MOVE, ATTACK, NUM_CURSORS };
|
||||
|
||||
void set(CURSOR_TYPE type);
|
||||
|
||||
struct setter
|
||||
{
|
||||
setter(CURSOR_TYPE type);
|
||||
~setter();
|
||||
|
||||
private:
|
||||
CURSOR_TYPE old_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,6 +17,7 @@
|
|||
#include "actions.hpp"
|
||||
#include "ai.hpp"
|
||||
#include "config.hpp"
|
||||
#include "cursor.hpp"
|
||||
#include "dialogs.hpp"
|
||||
#include "display.hpp"
|
||||
#include "events.hpp"
|
||||
|
@ -210,6 +211,7 @@ int play_game(int argc, char** argv)
|
|||
const preferences::manager prefs_manager;
|
||||
const image::manager image_manager;
|
||||
const events::event_context main_event_context;
|
||||
const cursor::manager cursor_manager;
|
||||
|
||||
std::cerr << "initialized managers\n";
|
||||
|
||||
|
@ -336,6 +338,8 @@ int play_game(int argc, char** argv)
|
|||
<< resolution.second << "x16 is not supported\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
cursor::set(cursor::NORMAL);
|
||||
} else {
|
||||
video.make_fake();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "cursor.hpp"
|
||||
#include "events.hpp"
|
||||
#include "game_events.hpp"
|
||||
#include "hotkeys.hpp"
|
||||
|
@ -416,6 +417,7 @@ redo_turn:
|
|||
gui.recalculate_minimap();
|
||||
|
||||
const hotkey::basic_handler key_events_handler(gui);
|
||||
const cursor::setter cursor_setter(cursor::WAIT);
|
||||
|
||||
const int start_command = recorder.ncommands();
|
||||
|
||||
|
|
|
@ -295,6 +295,24 @@ void turn_info::mouse_motion(const SDL_MouseMotionEvent& event)
|
|||
|
||||
gui_.highlight_hex(new_hex);
|
||||
|
||||
|
||||
//see if we should show the normal cursor, the movement cursor, or
|
||||
//the attack cursor
|
||||
|
||||
const unit_map::const_iterator selected_unit = units_.find(selected_hex_);
|
||||
const unit_map::const_iterator mouseover_unit = units_.find(new_hex);
|
||||
if(selected_unit != units_.end() && current_paths_.routes.count(new_hex)) {
|
||||
if(mouseover_unit == units_.end()) {
|
||||
cursor::set(cursor::MOVE);
|
||||
} else if(current_team.is_enemy(mouseover_unit->second.side())) {
|
||||
cursor::set(cursor::ATTACK);
|
||||
} else {
|
||||
cursor::set(cursor::NORMAL);
|
||||
}
|
||||
} else {
|
||||
cursor::set(cursor::NORMAL);
|
||||
}
|
||||
|
||||
if(enemy_paths_) {
|
||||
enemy_paths_ = false;
|
||||
current_paths_ = paths();
|
||||
|
|
|
@ -394,6 +394,11 @@ void set_theme(const std::string& theme)
|
|||
}
|
||||
}
|
||||
|
||||
bool use_colour_cursors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void show_preferences_dialog(display& disp)
|
||||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
|
|
|
@ -82,6 +82,8 @@ namespace preferences {
|
|||
void set_ask_delete_saves(bool value);
|
||||
bool ask_delete_saves();
|
||||
|
||||
bool use_colour_cursors();
|
||||
|
||||
std::string client_type();
|
||||
|
||||
void set_theme(const std::string& theme);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "config.hpp"
|
||||
#include "cursor.hpp"
|
||||
#include "events.hpp"
|
||||
#include "font.hpp"
|
||||
#include "image.hpp"
|
||||
|
@ -37,8 +38,15 @@ namespace gui {
|
|||
|
||||
bool in_dialog() { return is_in_dialog; }
|
||||
|
||||
dialog_manager::dialog_manager() : reset_to(is_in_dialog) {is_in_dialog = true;}
|
||||
dialog_manager::~dialog_manager() { is_in_dialog = reset_to; }
|
||||
dialog_manager::dialog_manager() : cursor::setter(cursor::NORMAL), reset_to(is_in_dialog)
|
||||
{
|
||||
is_in_dialog = true;
|
||||
}
|
||||
|
||||
dialog_manager::~dialog_manager()
|
||||
{
|
||||
is_in_dialog = reset_to;
|
||||
}
|
||||
|
||||
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define SHOW_DIALOG_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "cursor.hpp"
|
||||
#include "display.hpp"
|
||||
#include "network.hpp"
|
||||
#include "unit.hpp"
|
||||
|
@ -30,7 +31,7 @@ namespace gui
|
|||
|
||||
bool in_dialog();
|
||||
|
||||
struct dialog_manager {
|
||||
struct dialog_manager : private cursor::setter {
|
||||
dialog_manager();
|
||||
~dialog_manager();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue