Some more tweaks to cursor handling

- Fix cursor turning into a sword during universe shifts
- Hide cursor along with menubar during splash screen
- Add watch cursor, used during splash screen
- Properly restore cursor after a dialog
- Use sword cursor for dialogs
- Show ibeam cursor in dialog text fields
- Move everything cursor-related out of graphtool
This commit is contained in:
2014-04-21 13:47:52 -04:00
parent 84192cd52f
commit 446bb1550d
13 changed files with 118 additions and 89 deletions

View File

@@ -408,6 +408,7 @@
914B2B9218E8005B007B6799 /* SND97.WAV in Copy Mac Sounds */ = {isa = PBXBuildFile; fileRef = 914B2B2C18E7FFEF007B6799 /* SND97.WAV */; };
914B2B9318E8005B007B6799 /* SND98.WAV in Copy Mac Sounds */ = {isa = PBXBuildFile; fileRef = 914B2B2D18E7FFEF007B6799 /* SND98.WAV */; };
914B2B9418E8005B007B6799 /* SND99.WAV in Copy Mac Sounds */ = {isa = PBXBuildFile; fileRef = 914B2B2E18E7FFEF007B6799 /* SND99.WAV */; };
914CA4441905789C00B6ADD1 /* watch.gif in Copy Mac Cursors */ = {isa = PBXBuildFile; fileRef = 914CA4431905788F00B6ADD1 /* watch.gif */; };
9156039018F4810200A50C51 /* many-str.xml in Copy Dialog Definitions */ = {isa = PBXBuildFile; fileRef = 9156038F18F43C8D00A50C51 /* many-str.xml */; };
919145FC18E3AB1B005CF3A4 /* boe.appleevents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 919145FB18E3A32F005CF3A4 /* boe.appleevents.mm */; };
9192C12018F2745C0088A580 /* menu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9192C11E18F271920088A580 /* menu.xib */; };
@@ -513,9 +514,9 @@
91C1FCAA0FCB6F7200EBAA65 /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBAB90FB91ADB001E34EA /* message.cpp */; };
91C1FCAB0FCB6F7300EBAA65 /* pict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBAA90FB8F733001E34EA /* pict.cpp */; };
91C6864A0FD5EEFD000F6D01 /* pc.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EF0A0F969BD300BF5B67 /* pc.graphics.cpp */; };
91C688E80FD702B9000F6D01 /* cursors.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mm */; };
91C688E90FD702B9000F6D01 /* cursors.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mm */; };
91C688EA0FD702B9000F6D01 /* cursors.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mm */; };
91C688E80FD702B9000F6D01 /* cursors.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mac.mm */; };
91C688E90FD702B9000F6D01 /* cursors.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mac.mm */; };
91C688EA0FD702B9000F6D01 /* cursors.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91C688E70FD702B9000F6D01 /* cursors.mac.mm */; };
91D634560F8FD77800674AB3 /* BoE.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2B8F435C0C0973680012E4A8 /* BoE.icns */; };
91E5C1F30F9E489B00C21460 /* graphtool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */; };
91E5C1F40F9E489B00C21460 /* soundtool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10F0F9779D000BF5B67 /* soundtool.cpp */; };
@@ -761,6 +762,7 @@
912CF46B0FE44AC20063B614 /* W.gif in Copy Mac Cursors */,
912CF46C0FE44AC20063B614 /* wait.gif in Copy Mac Cursors */,
912CF46D0FE44AC20063B614 /* wand.gif in Copy Mac Cursors */,
914CA4441905789C00B6ADD1 /* watch.gif in Copy Mac Cursors */,
);
name = "Copy Mac Cursors";
runOnlyForDeploymentPostprocessing = 0;
@@ -1525,6 +1527,7 @@
914B2B2D18E7FFEF007B6799 /* SND98.WAV */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = SND98.WAV; sourceTree = "<group>"; };
914B2B2E18E7FFEF007B6799 /* SND99.WAV */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = SND99.WAV; sourceTree = "<group>"; };
914B2BB518E892AA007B6799 /* dialog-converting.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "dialog-converting.txt"; path = "dialogxml/dialog-converting.txt"; sourceTree = SOURCE_ROOT; };
914CA4431905788F00B6ADD1 /* watch.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = watch.gif; sourceTree = "<group>"; };
9156038F18F43C8D00A50C51 /* many-str.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "many-str.xml"; sourceTree = "<group>"; };
917B573F100B956C0096C978 /* undo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = undo.h; sourceTree = "<group>"; };
918D59A718EA513900735B66 /* dialog.keys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dialog.keys.h; sourceTree = "<group>"; };
@@ -1618,7 +1621,7 @@
91BFA3DE19033E01001686E4 /* gzstream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gzstream.cpp; sourceTree = "<group>"; };
91BFA3DF19033E01001686E4 /* gzstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gzstream.h; sourceTree = "<group>"; };
91C688E60FD702B9000F6D01 /* cursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursors.h; sourceTree = "<group>"; };
91C688E70FD702B9000F6D01 /* cursors.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cursors.mm; sourceTree = "<group>"; };
91C688E70FD702B9000F6D01 /* cursors.mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cursors.mac.mm; sourceTree = "<group>"; };
91D62F330F8EB84800674AB3 /* bladesofexile.rsrc */ = {isa = PBXFileReference; lastKnownFileType = archive.rsrc; path = bladesofexile.rsrc; sourceTree = "<group>"; };
91D635AA0F90E7B500674AB3 /* stealth.exs */ = {isa = PBXFileReference; lastKnownFileType = file; path = stealth.exs; sourceTree = "<group>"; };
91D635AB0F90E7B500674AB3 /* stealth.meg */ = {isa = PBXFileReference; lastKnownFileType = file; path = stealth.meg; sourceTree = "<group>"; };
@@ -1916,6 +1919,7 @@
912CF3990FE44A9B0063B614 /* W.gif */,
912CF39A0FE44A9B0063B614 /* wait.gif */,
912CF39B0FE44A9B0063B614 /* wand.gif */,
914CA4431905788F00B6ADD1 /* watch.gif */,
);
path = cursors;
sourceTree = "<group>";
@@ -2102,7 +2106,7 @@
913D03340FA0FFFF00184C18 /* src */ = {
isa = PBXGroup;
children = (
91C688E70FD702B9000F6D01 /* cursors.mm */,
91C688E70FD702B9000F6D01 /* cursors.mac.mm */,
91E5C7A60F9F615400C21460 /* fileio.cpp */,
91B3F10A0F9779C300BF5B67 /* graphtool.cpp */,
91B3F11E0F97801F00BF5B67 /* mathutil.cpp */,
@@ -2821,7 +2825,7 @@
912287040FD330F300B21642 /* field.cpp in Sources */,
912287050FD330F300B21642 /* message.cpp in Sources */,
912287060FD330F300B21642 /* pict.cpp in Sources */,
91C688E80FD702B9000F6D01 /* cursors.mm in Sources */,
91C688E80FD702B9000F6D01 /* cursors.mac.mm in Sources */,
91A32D160FDE049900C4E957 /* ticpp.cpp in Sources */,
91A32D170FDE049900C4E957 /* tinystr.cpp in Sources */,
91A32D180FDE049900C4E957 /* tinyxml.cpp in Sources */,
@@ -2876,7 +2880,7 @@
912286FE0FD330EC00B21642 /* message.cpp in Sources */,
912286FF0FD330ED00B21642 /* pict.cpp in Sources */,
91C6864A0FD5EEFD000F6D01 /* pc.graphics.cpp in Sources */,
91C688E90FD702B9000F6D01 /* cursors.mm in Sources */,
91C688E90FD702B9000F6D01 /* cursors.mac.mm in Sources */,
91A32D1B0FDE049F00C4E957 /* ticpp.cpp in Sources */,
91A32D1C0FDE049F00C4E957 /* tinystr.cpp in Sources */,
91A32D1D0FDE04A000C4E957 /* tinyxml.cpp in Sources */,
@@ -2934,7 +2938,7 @@
91C1FCAB0FCB6F7300EBAA65 /* pict.cpp in Sources */,
912283C90FD0E16C00B21642 /* undo.cpp in Sources */,
912286F80FD330E500B21642 /* dlogutil.cpp in Sources */,
91C688EA0FD702B9000F6D01 /* cursors.mm in Sources */,
91C688EA0FD702B9000F6D01 /* cursors.mac.mm in Sources */,
91A32D200FDE04A500C4E957 /* ticpp.cpp in Sources */,
91A32D210FDE04A500C4E957 /* tinystr.cpp in Sources */,
91A32D220FDE04A600C4E957 /* tinyxml.cpp in Sources */,

View File

@@ -552,7 +552,7 @@ void shift_universe_left()
load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y),univ.out.outdoors[0][0]);
load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1),univ.out.outdoors[0][1]);
build_outdoors();
make_cursor_sword();
restore_cursor();
}
@@ -586,7 +586,7 @@ void shift_universe_right()
load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y),univ.out.outdoors[1][0]);
load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1),univ.out.outdoors[1][1]);
build_outdoors();
make_cursor_sword();
restore_cursor();
}
@@ -621,7 +621,7 @@ void shift_universe_up()
load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y),univ.out.outdoors[1][0]);
build_outdoors();
make_cursor_sword();
restore_cursor();
}
@@ -657,7 +657,7 @@ void shift_universe_down()
load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1),univ.out.outdoors[1][1]);
build_outdoors();
make_cursor_sword();
restore_cursor();
}

View File

@@ -211,7 +211,10 @@ void plop_fancy_startup()
RECT logo_from = {0,0,350,350};
RECT intro_from = {0,0,480,640};
if(display_mode != 5) hideMenuBar();
if(display_mode != 5) {
hideMenuBar();
mainPtr.setMouseCursorVisible(false);
}
// for (i = 0;i < 8; i++)
// OffsetRect(&trim_rects[i],61,37);
@@ -229,6 +232,7 @@ void plop_fancy_startup()
from_rect = RECT(pict_to_draw);
// TODO: Looping 10 times here is a bit of a hack; fix it
for(int k = 0; k < 10; k++) {
make_cursor_watch();
mainPtr.clear(sf::Color::Black);
rect_draw_some_item(pict_to_draw, from_rect, mainPtr, logo_from);
@@ -262,7 +266,10 @@ void plop_fancy_startup()
break;
}
}
if(display_mode != 5) showMenuBar();
if(display_mode != 5) {
showMenuBar();
mainPtr.setMouseCursorVisible(true);
}
}
void init_startup()

View File

@@ -1187,8 +1187,7 @@ void init_mini_map() {
void make_cursor_watch()
{
// TODO: If this doesn't work, which I suspect it won't, add a "custom" watch cursor and use that. Or conclude this isn't even needed.
setCursorWatch();
set_cursor(watch_curs);
}
////

View File

@@ -27,12 +27,12 @@
#include "dlogutil.h"
#include "scrollbar.h"
#include "boe.menus.h"
#include "cursors.h"
#include <CoreFoundation/CFByteOrder.h>
//extern short arrow_curs[3][3];
//extern short sword_curs, boot_curs, drop_curs, target_curs;
//extern short talk_curs, key_curs, look_curs, current_cursor;
extern cursor_type arrow_curs[3][3];
extern cursor_type current_cursor;
/* Mac stuff globals */
bool All_Done = false;
@@ -168,6 +168,7 @@ int main(int argc, char* argv[]) {
set_up_apple_events();
//import_template_terrain();
//import_anim_terrain(0);
make_cursor_watch();
plop_fancy_startup();
//PSD[SDF_NO_FRILLS] = 0;
@@ -201,6 +202,7 @@ int main(int argc, char* argv[]) {
init_mini_map();
menu_activate();
restore_cursor();
while (All_Done == false)
Handle_One_Event();
@@ -330,9 +332,7 @@ void Handle_One_Event()
break;
case sf::Event::MouseLeft:
// Make sure we don't have an invisible or arrow cursor when it's outside the window
// TODO: Would probably be better to reset the cursor to normal rather than making it a sword
mainPtr.setMouseCursorVisible(true);
// Make sure we don't have an arrow cursor when it's outside the window
make_cursor_sword();
break;

View File

@@ -21,9 +21,11 @@ using namespace ticpp;
#include "scrollbar.h"
#include "winutil.h"
#include "mathutil.h"
#include "cursors.h"
// TODO: Would be nice if I could avoid depending on mainPtr
extern sf::RenderWindow mainPtr;
extern cursor_type current_cursor;
extern sf::Texture bg_gworld;
extern bool play_sounds;
@@ -890,8 +892,8 @@ bool cDialog::remove(std::string key){
}
void cDialog::run(){
// We always need the cursor when we're in a dialog
mainPtr.setMouseCursorVisible(true);
cursor_type former_curs = current_cursor;
set_cursor(sword_curs);
using kb = sf::Keyboard;
kb::Key k;
cKey key;
@@ -1063,6 +1065,15 @@ void cDialog::run(){
where = {currentEvent.mouseButton.x, currentEvent.mouseButton.y};
itemHit = process_click(where, key.mod);
break;
case sf::Event::MouseMoved:
set_cursor(sword_curs);
for(auto& ctrl : controls) {
if(ctrl.second->getType() == CTRL_FIELD && ctrl.second->getBounds().contains(currentEvent.mouseMove.x, currentEvent.mouseMove.y)) {
set_cursor(text_curs);
break;
}
}
break;
}
if(itemHit.empty()) continue;;
ctrlIter ctrl = controls.find(itemHit);
@@ -1073,6 +1084,7 @@ void cDialog::run(){
win.setVisible(false);
sf::RenderWindow* parentWin = &(parent ? parent->win : mainPtr);
while(parentWin->pollEvent(currentEvent));
set_cursor(former_curs);
}
void cDialog::setBg(short n){

View File

@@ -15,6 +15,7 @@
#include "fileio.h"
#include "pc.menus.h"
#include "winutil.h"
#include "cursors.h"
#ifdef __APPLE__
#include <CoreFoundation/CFByteOrder.h>
#endif

View File

@@ -9,6 +9,35 @@
#ifndef BOE_CURSORS_H
#define BOE_CURSORS_H
enum cursor_type {
wand_curs = 0,
eyedropper_curs = 1,
brush_curs = 2,
spray_curs = 3,
eraser_curs = 4,
topleft_curs = 5,
bottomright_curs = 6,
hand_curs = 7,
NW_curs = 8,
N_curs = 9,
NE_curs = 10,
W_curs = 11,
wait_curs = 12,
E_curs = 13,
SW_curs = 14,
S_curs = 15,
SE_curs = 16,
sword_curs = 17,
boot_curs = 18,
drop_curs = 19,
target_curs = 20,
talk_curs = 21,
key_curs = 22,
look_curs = 23,
watch_curs,
text_curs, // Keep this one last
};
class Cursor {
void* ptr;
public:
@@ -17,8 +46,10 @@ public:
void apply();
};
void setCursorWatch();
// This hides the cursor until it moves
void obscureCursor();
void set_cursor(cursor_type which_curs);
void restore_cursor();
#endif

View File

@@ -8,8 +8,27 @@
#include "cursors.h"
#include <Cocoa/Cocoa.h>
#include <string>
#include "restypes.hpp"
static NSImage* ImageFromURL(CFURLRef url){
cursor_type current_cursor = sword_curs;
cursor_type arrow_curs[3][3] = {
{NW_curs, N_curs, NE_curs},
{W_curs,wait_curs,E_curs},
{SW_curs, S_curs, SE_curs},
};
const std::string cursors[25] = {
"wand", "eyedropper", "brush", "spraycan",
"eraser", "topleft", "bottomright", "hand",
"NW", "N", "NE",
"W", "wait", "E",
"SW", "S", "SE",
"sword", "boot", "drop", "target",
"talk", "key", "look", "watch",
};
static NSImage* imageFromURL(CFURLRef url){
CGImageSourceRef imageSource = CGImageSourceCreateWithURL(url, NULL);
CGImageRef theImage = nil;
@@ -43,7 +62,7 @@ Cursor::Cursor(const char* path, float hotSpotX, float hotSpotY){
FSPathMakeRef((UInt8*)path, &ref, NULL);
CFURLRef imgPath = CFURLCreateFromFSRef(NULL, &ref);
NSImage *img = ImageFromURL(imgPath);
NSImage *img = imageFromURL(imgPath);
NSCursor *cursor = [[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(hotSpotX, hotSpotY)];
[img release];
@@ -58,9 +77,21 @@ void Cursor::apply(){
[(NSCursor*)ptr set];
}
void setCursorWatch() {
}
void obscureCursor() {
[NSCursor setHiddenUntilMouseMoves: YES];
}
void set_cursor(cursor_type which_c) {
if(which_c != watch_curs)
current_cursor = which_c;
if(which_c == text_curs) {
[[NSCursor IBeamCursor] set];
} else {
Cursor& curs = *ResMgr::get<CursorRsrc>(cursors[which_c]);
curs.apply();
}
}
void restore_cursor(){
set_cursor(current_cursor);
}

View File

@@ -23,21 +23,6 @@
using boost::math::constants::pi;
cursor_type arrow_curs[3][3] = {
{NW_curs, N_curs, NE_curs},
{W_curs,wait_curs,E_curs},
{SW_curs, S_curs, SE_curs},
};
cursor_type current_cursor = sword_curs;
const std::string cursors[24] = {
"wand", "eyedropper", "brush", "spraycan",
"eraser", "topleft", "bottomright", "hand",
"NW", "N", "NE",
"W", "wait", "E",
"SW", "S", "SE",
"sword", "boot", "drop", "target",
"talk", "key", "look",
};
RECT bg[21];
RECT map_pat[30];
RECT bw_pats[6];
@@ -140,16 +125,6 @@ void init_graph_tool(){
bg_gworld.loadFromImage(*ResMgr::get<ImageRsrc>("pixpats"));
}
void set_cursor(cursor_type which_c) {
current_cursor = which_c;
Cursor& curs = *ResMgr::get<CursorRsrc>(cursors[current_cursor]);
curs.apply();
}
void restore_cursor(){
set_cursor(current_cursor);
}
static void rect_draw_some_item(const sf::Texture& src_gworld,RECT src_rect,sf::RenderTarget& targ_gworld,RECT targ_rect,sf::RenderStates mode);
void rect_draw_some_item(sf::RenderTarget& targ_gworld,RECT targ_rect) {

View File

@@ -20,33 +20,6 @@ namespace fs = boost::filesystem;
#define NUM_TER_SHEETS 7
#define NUM_MONST_SHEETS 11
enum cursor_type {
wand_curs = 0,
eyedropper_curs = 1,
brush_curs = 2,
spray_curs = 3,
eraser_curs = 4,
topleft_curs = 5,
bottomright_curs = 6,
hand_curs = 7,
NW_curs = 8,
N_curs = 9,
NE_curs = 10,
W_curs = 11,
wait_curs = 12,
E_curs = 13,
SW_curs = 14,
S_curs = 15,
SE_curs = 16,
sword_curs = 17,
boot_curs = 18,
drop_curs = 19,
target_curs = 20,
talk_curs = 21,
key_curs = 22,
look_curs = 23,
};
struct m_pic_index_t {
unsigned char i, x, y;
};
@@ -102,8 +75,6 @@ struct cCustomGraphics {
};
void init_graph_tool();
void set_cursor(cursor_type which_curs);
void restore_cursor();
void rect_draw_some_item(sf::RenderTarget& targ_gworld,RECT targ_rect);
void rect_draw_some_item(const sf::Texture& src_gworld,RECT src_rect,sf::RenderTarget& targ_gworld,RECT targ_rect,sf::BlendMode mode = sf::BlendNone);
void rect_draw_some_item(const sf::Texture& src_gworld,RECT src_rect,RECT targ_rect,location offset,sf::BlendMode mode = sf::BlendNone);
@@ -130,8 +101,6 @@ void clip_region(sf::RenderWindow& where, Region& region);
void undo_clip(sf::RenderTarget& where);
#ifndef GRAPHTOOL_CPP
extern cursor_type arrow_curs[3][3];
extern cursor_type current_cursor;
extern m_pic_index_t m_pic_index[200];
extern RECT bg[];
#endif

View File

@@ -45,7 +45,7 @@ namespace ResMgr {
{"W", {3, 9}}, {"wait", {8, 8}}, {"E", {8, 3}},
{"SW", {3, 12}}, {"S", {7, 13}}, {"SE", {3, 12}},
{"sword", {1, 1}}, {"boot", {7, 3}}, {"drop", {0, 14}}, {"target", {8, 8}},
{"talk", {6, 7}}, {"key", {3, 2}}, {"look", {7, 6}}
{"talk", {6, 7}}, {"key", {3, 2}}, {"look", {7, 6}}, {"watch", {7,8}},
};
fs::path fpath = resPool<CursorRsrc>::rel2abs(fname + ".gif");
fs::path hotpath = resPool<CursorRsrc>::rel2abs(fname + ".hot");
@@ -57,9 +57,9 @@ namespace ResMgr {
} else {
auto entry = cursor_hs.find(fname);
if(entry == cursor_hs.end())
fprintf(stderr,"Cursor hotspot missing: %s",fname.c_str());
fprintf(stderr,"Cursor hotspot missing: %s\n",fname.c_str());
else {
fprintf(stderr,"Cursor hotspot missing (using fallback value): %s",fname.c_str());
fprintf(stderr,"Cursor hotspot missing (using fallback value): %s\n",fname.c_str());
location hs = entry->second;
x = hs.x; y = hs.y;
}