Editor search field for terrains, monsters, items in palette
This commit is contained in:
@@ -646,89 +646,99 @@ void cDialog::stackWindowsCorrectly() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method handles one event received by the dialog.
|
cKey translate_sfml_key(sf::Event::KeyEvent key_event) {
|
||||||
void cDialog::handle_one_event(const sf::Event& currentEvent, cFramerateLimiter& fps_limiter) {
|
|
||||||
using Key = sf::Keyboard::Key;
|
using Key = sf::Keyboard::Key;
|
||||||
|
|
||||||
cKey key;
|
cKey key;
|
||||||
|
switch(key_event.code){
|
||||||
|
case Key::Up:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_up;
|
||||||
|
break;
|
||||||
|
case Key::Right:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_right;
|
||||||
|
break;
|
||||||
|
case Key::Left:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_left;
|
||||||
|
break;
|
||||||
|
case Key::Down:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_down;
|
||||||
|
break;
|
||||||
|
case Key::Escape:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_esc;
|
||||||
|
break;
|
||||||
|
case Key::Return: // TODO: Also enter (keypad)
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_enter;
|
||||||
|
break;
|
||||||
|
case Key::BackSpace:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_bsp;
|
||||||
|
break;
|
||||||
|
case Key::Delete:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_del;
|
||||||
|
break;
|
||||||
|
case Key::Tab:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_tab;
|
||||||
|
break;
|
||||||
|
case Key::Insert:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_insert;
|
||||||
|
break;
|
||||||
|
case Key::F1:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_help;
|
||||||
|
break;
|
||||||
|
case Key::Home:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_home;
|
||||||
|
break;
|
||||||
|
case Key::End:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_end;
|
||||||
|
break;
|
||||||
|
case Key::PageUp:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_pgup;
|
||||||
|
break;
|
||||||
|
case Key::PageDown:
|
||||||
|
key.spec = true;
|
||||||
|
key.k = key_pgdn;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
key.spec = false;
|
||||||
|
key.c = keyToChar(key_event.code, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
key.mod = mod_none;
|
||||||
|
if(key_event.*systemKey)
|
||||||
|
key.mod += mod_ctrl;
|
||||||
|
if(key_event.shift) key.mod += mod_shift;
|
||||||
|
if(key_event.alt) key.mod += mod_alt;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method handles one event received by the dialog.
|
||||||
|
void cDialog::handle_one_event(const sf::Event& currentEvent, cFramerateLimiter& fps_limiter) {
|
||||||
|
|
||||||
// HACK: This needs to be stored between consecutive invocations of this function
|
// HACK: This needs to be stored between consecutive invocations of this function
|
||||||
static cKey pendingKey = {true};
|
static cKey pendingKey = {true};
|
||||||
std::string itemHit = "";
|
std::string itemHit = "";
|
||||||
location where;
|
location where;
|
||||||
|
cKey key;
|
||||||
switch(currentEvent.type) {
|
switch(currentEvent.type) {
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
switch(currentEvent.key.code){
|
key = translate_sfml_key(currentEvent.key);
|
||||||
case Key::Up:
|
|
||||||
key.spec = true;
|
// Handles button hotkeys. Note that the event still falls through to text fields.
|
||||||
key.k = key_up;
|
// It probably shouldn't, because right now we have to be careful not to put a button
|
||||||
break;
|
// on the same dialog as a field if its hotkey is a typable character.
|
||||||
case Key::Right:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_right;
|
|
||||||
break;
|
|
||||||
case Key::Left:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_left;
|
|
||||||
break;
|
|
||||||
case Key::Down:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_down;
|
|
||||||
break;
|
|
||||||
case Key::Escape:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_esc;
|
|
||||||
break;
|
|
||||||
case Key::Return: // TODO: Also enter (keypad)
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_enter;
|
|
||||||
break;
|
|
||||||
case Key::BackSpace:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_bsp;
|
|
||||||
break;
|
|
||||||
case Key::Delete:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_del;
|
|
||||||
break;
|
|
||||||
case Key::Tab:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_tab;
|
|
||||||
break;
|
|
||||||
case Key::Insert:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_insert;
|
|
||||||
break;
|
|
||||||
case Key::F1:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_help;
|
|
||||||
break;
|
|
||||||
case Key::Home:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_home;
|
|
||||||
break;
|
|
||||||
case Key::End:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_end;
|
|
||||||
break;
|
|
||||||
case Key::PageUp:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_pgup;
|
|
||||||
break;
|
|
||||||
case Key::PageDown:
|
|
||||||
key.spec = true;
|
|
||||||
key.k = key_pgdn;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
key.spec = false;
|
|
||||||
key.c = keyToChar(currentEvent.key.code, false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
key.mod = mod_none;
|
|
||||||
if(currentEvent.key.*systemKey)
|
|
||||||
key.mod += mod_ctrl;
|
|
||||||
if(currentEvent.key.shift) key.mod += mod_shift;
|
|
||||||
if(currentEvent.key.alt) key.mod += mod_alt;
|
|
||||||
process_keystroke(key);
|
process_keystroke(key);
|
||||||
// Now check for focused fields.
|
// Now check for focused fields.
|
||||||
if(currentFocus.empty()) break;
|
if(currentFocus.empty()) break;
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
/// Dialog-related classes and types.
|
/// Dialog-related classes and types.
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -55,6 +56,8 @@ protected:
|
|||||||
void increment();
|
void increment();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cKey translate_sfml_key(sf::Event::KeyEvent);
|
||||||
|
|
||||||
/// Defines a fancy dialog box with various controls.
|
/// Defines a fancy dialog box with various controls.
|
||||||
class cDialog : public iComponent, public iNameGiver {
|
class cDialog : public iComponent, public iNameGiver {
|
||||||
friend class cDialogIterator;
|
friend class cDialogIterator;
|
||||||
|
@@ -715,3 +715,8 @@ void cControl::restore(storage_t to) {
|
|||||||
if(to.find("visible") != to.end())
|
if(to.find("visible") != to.end())
|
||||||
boost::any_cast<bool>(to["visible"]) ? show() : hide();
|
boost::any_cast<bool>(to["visible"]) ? show() : hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translate raw x/y position using the view of the current rendering target
|
||||||
|
location cControl::translated_location(const sf::Vector2i point) const {
|
||||||
|
return location { const_cast<cControl*>(this)->getWindow().mapPixelToCoords(point) };
|
||||||
|
}
|
@@ -493,6 +493,7 @@ protected:
|
|||||||
/// Plays the proper sound for this control being clicked on
|
/// Plays the proper sound for this control being clicked on
|
||||||
void playClickSound();
|
void playClickSound();
|
||||||
static std::string generateRandomString();
|
static std::string generateRandomString();
|
||||||
|
location translated_location(const sf::Vector2i) const;
|
||||||
private:
|
private:
|
||||||
friend class cDialog; // This is so it can access parseColour and anchor
|
friend class cDialog; // This is so it can access parseColour and anchor
|
||||||
friend class cContainer; // This is so it can access anchor
|
friend class cContainer; // This is so it can access anchor
|
||||||
|
@@ -139,6 +139,66 @@ void cTextField::replay_selection(ticpp::Element& next_action) {
|
|||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parentless text field handle input
|
||||||
|
bool cTextField::handle_event(const sf::Event& event) {
|
||||||
|
// Not visible -> not interested
|
||||||
|
if(!this->isVisible())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
static cKey pendingKey;
|
||||||
|
|
||||||
|
switch(event.type) {
|
||||||
|
case sf::Event::MouseButtonPressed:
|
||||||
|
return this->handle_mouse_pressed(event);
|
||||||
|
case sf::Event::KeyPressed:
|
||||||
|
return this->handle_key_pressed(event, pendingKey);
|
||||||
|
case sf::Event::TextEntered:
|
||||||
|
if(!pendingKey.spec && haveFocus) {
|
||||||
|
pendingKey.c = event.text.unicode;
|
||||||
|
if(pendingKey.c != '\t')
|
||||||
|
handleInput(pendingKey, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTextField::handle_key_pressed(const sf::Event& event, cKey& pendingKey) {
|
||||||
|
if(haveFocus){
|
||||||
|
cKey key = translate_sfml_key(event.key);
|
||||||
|
// TODO if multiple parentless fields ever exist, tab order will need to be handled
|
||||||
|
|
||||||
|
// If it's a character key, and the system key (control/command) is not pressed,
|
||||||
|
// we have an upcoming TextEntered event which contains more information.
|
||||||
|
// Otherwise, handle it right away. But never handle enter or escape.
|
||||||
|
if((key.spec && key.k != key_enter && key.k != key_esc) || mod_contains(key.mod, mod_ctrl))
|
||||||
|
handleInput(key, true);
|
||||||
|
pendingKey = key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parentless text field toggle focus on click
|
||||||
|
bool cTextField::handle_mouse_pressed(const sf::Event& event) {
|
||||||
|
location event_location = this->translated_location({
|
||||||
|
event.mouseButton.x,
|
||||||
|
event.mouseButton.y
|
||||||
|
});
|
||||||
|
|
||||||
|
bool in_bounds = event_location.in(this->getBounds());
|
||||||
|
// TODO if multiple parentless fields ever exist, focus must be taken from the other one here
|
||||||
|
haveFocus = in_bounds;
|
||||||
|
insertionPoint = 0;
|
||||||
|
if(haveFocus){
|
||||||
|
static cFramerateLimiter fps_limiter;
|
||||||
|
handleClick(event_location, fps_limiter);
|
||||||
|
}
|
||||||
|
return in_bounds;
|
||||||
|
}
|
||||||
|
|
||||||
bool cTextField::handleClick(location clickLoc, cFramerateLimiter& fps_limiter) {
|
bool cTextField::handleClick(location clickLoc, cFramerateLimiter& fps_limiter) {
|
||||||
if(!haveFocus && getDialog() && !getDialog()->setFocus(this)) return true;
|
if(!haveFocus && getDialog() && !getDialog()->setFocus(this)) return true;
|
||||||
haveFocus = true;
|
haveFocus = true;
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#include "control.hpp"
|
#include "control.hpp"
|
||||||
#include "gfx/render_text.hpp"
|
#include "gfx/render_text.hpp"
|
||||||
#include "tools/undo.hpp"
|
#include "tools/undo.hpp"
|
||||||
|
#include "tools/drawable.hpp"
|
||||||
|
#include "tools/event_listener.hpp"
|
||||||
|
|
||||||
/// The field's expected input type.
|
/// The field's expected input type.
|
||||||
enum eFldType {
|
enum eFldType {
|
||||||
@@ -31,7 +33,7 @@ enum eFldType {
|
|||||||
/// (If there's a current selection, the mobile end of the selection is kept in view.)
|
/// (If there's a current selection, the mobile end of the selection is kept in view.)
|
||||||
/// Mouse support is currently nonexistent, except for focusing when clicked.
|
/// Mouse support is currently nonexistent, except for focusing when clicked.
|
||||||
/// There is no Unicode support.
|
/// There is no Unicode support.
|
||||||
class cTextField : public cControl {
|
class cTextField : public cControl, public iEventListener, public iDrawable {
|
||||||
public:
|
public:
|
||||||
bool parseAttribute(ticpp::Attribute& attr, std::string tagName, std::string fname) override;
|
bool parseAttribute(ticpp::Attribute& attr, std::string tagName, std::string fname) override;
|
||||||
bool parseContent(ticpp::Node& content, int n, std::string tagName, std::string fname, std::string& text) override;
|
bool parseContent(ticpp::Node& content, int n, std::string tagName, std::string fname, std::string& text) override;
|
||||||
@@ -43,6 +45,9 @@ public:
|
|||||||
return {EVT_FOCUS, EVT_DEFOCUS};
|
return {EVT_FOCUS, EVT_DEFOCUS};
|
||||||
}
|
}
|
||||||
bool handleClick(location where, cFramerateLimiter& fps_limiter) override;
|
bool handleClick(location where, cFramerateLimiter& fps_limiter) override;
|
||||||
|
bool handle_event(const sf::Event&) override;
|
||||||
|
bool handle_mouse_pressed(const sf::Event&);
|
||||||
|
bool handle_key_pressed(const sf::Event&, cKey& pendingKey);
|
||||||
void setText(std::string to) override;
|
void setText(std::string to) override;
|
||||||
storage_t store() const override;
|
storage_t store() const override;
|
||||||
void restore(storage_t to) override;
|
void restore(storage_t to) override;
|
||||||
|
@@ -111,12 +111,6 @@ eScrollStyle cScrollbar::getStyle() const {
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: centralize this translation somewhere
|
|
||||||
// Translate raw x/y position using the view of the current rendering target
|
|
||||||
location cScrollbar::translated_location(const sf::Vector2i point) const {
|
|
||||||
return location { const_cast<cScrollbar*>(this)->getWindow().mapPixelToCoords(point) };
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cScrollbar::handle_event(const sf::Event& event) {
|
bool cScrollbar::handle_event(const sf::Event& event) {
|
||||||
// Not visible -> not interested
|
// Not visible -> not interested
|
||||||
if(!this->isVisible())
|
if(!this->isVisible())
|
||||||
|
@@ -53,7 +53,6 @@ class cScrollbar : public cControl, public iEventListener, public iDrawable {
|
|||||||
// in the inventory area).
|
// in the inventory area).
|
||||||
rectangle wheel_event_rect {0, 0, 0, 0};
|
rectangle wheel_event_rect {0, 0, 0, 0};
|
||||||
void draw_vertical(), draw_horizontal();
|
void draw_vertical(), draw_horizontal();
|
||||||
location translated_location(const sf::Vector2i) const;
|
|
||||||
eScrollbarPart location_to_part(const location& location) const;
|
eScrollbarPart location_to_part(const location& location) const;
|
||||||
location mouse_pressed_at;
|
location mouse_pressed_at;
|
||||||
int drag_start_position;
|
int drag_start_position;
|
||||||
|
@@ -29,7 +29,7 @@ const char* oboeVersionString();
|
|||||||
// Window Resolutions
|
// Window Resolutions
|
||||||
const short boe_width = 605, boe_height = 430;
|
const short boe_width = 605, boe_height = 430;
|
||||||
const short pc_width = 590, pc_height = 440;
|
const short pc_width = 590, pc_height = 440;
|
||||||
const short scen_width = 584, scen_height = 420;
|
const short scen_width = 584, scen_height = 435;
|
||||||
|
|
||||||
// A convenient alias
|
// A convenient alias
|
||||||
namespace boost { namespace filesystem {} namespace process {}}
|
namespace boost { namespace filesystem {} namespace process {}}
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
#include "tools/cursors.hpp"
|
#include "tools/cursors.hpp"
|
||||||
#include "tools/winutil.hpp"
|
#include "tools/winutil.hpp"
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include "dialogxml/widgets/field.hpp"
|
||||||
|
|
||||||
#include "dialogxml/dialogs/dialog.hpp"
|
#include "dialogxml/dialogs/dialog.hpp"
|
||||||
|
|
||||||
@@ -54,6 +56,8 @@ extern sf::Texture bg_gworld;
|
|||||||
extern rectangle right_buttons[NRSONPAGE];
|
extern rectangle right_buttons[NRSONPAGE];
|
||||||
extern rectangle right_scrollbar_rect;
|
extern rectangle right_scrollbar_rect;
|
||||||
extern std::shared_ptr<cScrollbar> right_sbar, pal_sbar;
|
extern std::shared_ptr<cScrollbar> right_sbar, pal_sbar;
|
||||||
|
extern std::shared_ptr<cTextField> palette_search_field;
|
||||||
|
extern rectangle search_field_text_rect;
|
||||||
extern boost::variant<boost::none_t, std::pair<long,bool>, cTownperson, cTown::cItem, vector2d<ter_num_t>> clipboard;
|
extern boost::variant<boost::none_t, std::pair<long,bool>, cTownperson, cTown::cItem, vector2d<ter_num_t>> clipboard;
|
||||||
|
|
||||||
extern bool left_buttons_active,right_buttons_active;
|
extern bool left_buttons_active,right_buttons_active;
|
||||||
@@ -439,6 +443,11 @@ void draw_main_screen() {
|
|||||||
if((overall_mode < MODE_MAIN_SCREEN) || (overall_mode == MODE_EDIT_TYPES)) {
|
if((overall_mode < MODE_MAIN_SCREEN) || (overall_mode == MODE_EDIT_TYPES)) {
|
||||||
place_location();
|
place_location();
|
||||||
set_up_terrain_buttons(false);
|
set_up_terrain_buttons(false);
|
||||||
|
TextStyle style;
|
||||||
|
win_draw_string(mainPtr(), search_field_text_rect, "Search:", eTextMode::WRAP, style);
|
||||||
|
palette_search_field->show();
|
||||||
|
}else{
|
||||||
|
palette_search_field->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -541,30 +550,45 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
if(draw_mode == DRAW_MONST) first++, max++;
|
if(draw_mode == DRAW_MONST) first++, max++;
|
||||||
int end = min(first + 256, max);
|
int end = min(first + 256, max);
|
||||||
|
|
||||||
|
std::string search_query = palette_search_field->getText();
|
||||||
|
boost::algorithm::to_lower(search_query);
|
||||||
|
boost::algorithm::trim(search_query);
|
||||||
|
|
||||||
|
// How transparent to make non-matching elements in the palette
|
||||||
|
static const sf::Uint8 FILTER_ALPHA = 255 / 8;
|
||||||
|
|
||||||
// first make terrain buttons
|
// first make terrain buttons
|
||||||
sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons");
|
sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons");
|
||||||
for(short i = first; i < end; i++) {
|
for(short i = first; i < end; i++) {
|
||||||
|
sf::Color colour = Colours::WHITE;
|
||||||
|
sf::Color frame_colour = Colours::BLACK;
|
||||||
rectangle draw_rect = terrain_rects[i - first];
|
rectangle draw_rect = terrain_rects[i - first];
|
||||||
draw_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
draw_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||||||
switch(draw_mode){
|
switch(draw_mode){
|
||||||
case DRAW_TERRAIN:
|
case DRAW_TERRAIN:{
|
||||||
if(i == scenario.ter_types.size()) {
|
if(i == scenario.ter_types.size()) {
|
||||||
rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr(), draw_rect);
|
rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr(), draw_rect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const cTerrain& ter = scenario.ter_types[i];
|
||||||
|
|
||||||
|
std::string name = ter.name;
|
||||||
|
boost::algorithm::to_lower(name);
|
||||||
|
if(!search_query.empty() && name.find(search_query) == std::string::npos) colour.a = FILTER_ALPHA;
|
||||||
|
|
||||||
ter_from = ter_from_base;
|
ter_from = ter_from_base;
|
||||||
pic = scenario.ter_types[i].picture;
|
pic = ter.picture;
|
||||||
if(pic >= 1000) {
|
if(pic >= 1000) {
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), draw_rect);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||||||
}
|
}
|
||||||
else if(pic < 960) {
|
else if(pic < 960) {
|
||||||
pic = pic % 50;
|
pic = pic % 50;
|
||||||
ter_from.offset(28 * (pic % 10), 36 * (pic / 10));
|
ter_from.offset(28 * (pic % 10), 36 * (pic / 10));
|
||||||
int which_sheet = scenario.ter_types[i].picture / 50;
|
int which_sheet = ter.picture / 50;
|
||||||
rect_draw_some_item(*ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)),
|
rect_draw_some_item(*ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)),
|
||||||
ter_from, mainPtr(), draw_rect);
|
ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pic = (pic - 560) % 50;
|
pic = (pic - 560) % 50;
|
||||||
@@ -572,7 +596,7 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
ter_from.right = ter_from.left + 28;
|
ter_from.right = ter_from.left + 28;
|
||||||
ter_from.top = 36 * (pic % 5);
|
ter_from.top = 36 * (pic % 5);
|
||||||
ter_from.bottom = ter_from.top + 36;
|
ter_from.bottom = ter_from.top + 36;
|
||||||
rect_draw_some_item(*ResMgr::graphics.get("teranim"), ter_from, mainPtr(), draw_rect);
|
rect_draw_some_item(*ResMgr::graphics.get("teranim"), ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||||||
|
|
||||||
}
|
}
|
||||||
small_i = get_small_icon(i);
|
small_i = get_small_icon(i);
|
||||||
@@ -582,31 +606,39 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
tiny_to.top = tiny_to.bottom - 7;
|
tiny_to.top = tiny_to.bottom - 7;
|
||||||
tiny_to.left = tiny_to.right - 7;
|
tiny_to.left = tiny_to.right - 7;
|
||||||
if(small_i >= 0 && small_i < 255)
|
if(small_i >= 0 && small_i < 255)
|
||||||
rect_draw_some_item(editor_mixed, tiny_from, mainPtr(), tiny_to);
|
rect_draw_some_item(editor_mixed, tiny_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
break;
|
}break;
|
||||||
case DRAW_MONST:
|
case DRAW_MONST:{
|
||||||
pic = scenario.scen_monsters[i].picture_num;
|
const cMonster& monst = scenario.scen_monsters[i];
|
||||||
|
|
||||||
|
std::string name = monst.m_name;
|
||||||
|
boost::algorithm::to_lower(name);
|
||||||
|
if(!search_query.empty() && name.find(search_query) == std::string::npos){
|
||||||
|
colour.a = frame_colour.a = FILTER_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
pic = monst.picture_num;
|
||||||
tiny_to = draw_rect;
|
tiny_to = draw_rect;
|
||||||
frame_rect(mainPtr(), tiny_to, sf::Color::Black);
|
frame_rect(mainPtr(), tiny_to, frame_colour);
|
||||||
if(pic >= 4000) {
|
if(pic >= 4000) {
|
||||||
pic %= 1000;
|
pic %= 1000;
|
||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
tiny_to.height() = tiny_to.height() / 2;
|
tiny_to.height() = tiny_to.height() / 2;
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else if(pic >= 3000) {
|
} else if(pic >= 3000) {
|
||||||
pic %= 1000;
|
pic %= 1000;
|
||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
@@ -614,11 +646,11 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
tiny_to.offset(tiny_to.width() / 2, 0);
|
tiny_to.offset(tiny_to.width() / 2, 0);
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(0, tiny_to.height());
|
tiny_to.offset(0, tiny_to.height());
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else if(pic >= 2000) {
|
} else if(pic >= 2000) {
|
||||||
pic %= 1000;
|
pic %= 1000;
|
||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
@@ -626,16 +658,16 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
tiny_to.offset(0, tiny_to.height() / 2);
|
tiny_to.offset(0, tiny_to.height() / 2);
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else if(pic >= 1000) {
|
} else if(pic >= 1000) {
|
||||||
pic %= 1000;
|
pic %= 1000;
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else {
|
} else {
|
||||||
auto pic_info = m_pic_index[pic];
|
auto pic_info = m_pic_index[pic];
|
||||||
pic = pic_info.i;
|
pic = pic_info.i;
|
||||||
@@ -646,59 +678,71 @@ void set_up_terrain_buttons(bool reset) {
|
|||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
tiny_to.height() = tiny_to.height() / 2;
|
tiny_to.height() = tiny_to.height() / 2;
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else if(pic_info.y == 2) {
|
} else if(pic_info.y == 2) {
|
||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
tiny_to.height() = tiny_to.height() / 2;
|
tiny_to.height() = tiny_to.height() / 2;
|
||||||
tiny_to.offset(tiny_to.width() / 2, 0);
|
tiny_to.offset(tiny_to.width() / 2, 0);
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(0, tiny_to.height());
|
tiny_to.offset(0, tiny_to.height());
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else if(pic_info.x == 2) {
|
} else if(pic_info.x == 2) {
|
||||||
tiny_to.width() = tiny_to.width() / 2;
|
tiny_to.width() = tiny_to.width() / 2;
|
||||||
tiny_to.height() = tiny_to.height() / 2;
|
tiny_to.height() = tiny_to.height() / 2;
|
||||||
tiny_to.offset(0, tiny_to.height() / 2);
|
tiny_to.offset(0, tiny_to.height() / 2);
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
pic++;
|
pic++;
|
||||||
tiny_to.offset(tiny_to.width(), 0);
|
tiny_to.offset(tiny_to.width(), 0);
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else {
|
} else {
|
||||||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||||||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}break;
|
||||||
case DRAW_ITEM:
|
case DRAW_ITEM:{
|
||||||
pic = scenario.scen_items[i].graphic_num;
|
const cItem& item = scenario.scen_items[i];
|
||||||
|
pic = item.graphic_num;
|
||||||
|
|
||||||
|
std::string fname = item.full_name;
|
||||||
|
boost::algorithm::to_lower(fname);
|
||||||
|
// Maybe a designer will want to search for the unidentified name of a cursed item?
|
||||||
|
std::string name = item.name;
|
||||||
|
boost::algorithm::to_lower(name);
|
||||||
|
|
||||||
|
if(!search_query.empty() && fname.find(search_query) == std::string::npos && name.find(search_query) == std::string::npos){
|
||||||
|
colour.a = frame_colour.a = FILTER_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
tiny_to = draw_rect;
|
tiny_to = draw_rect;
|
||||||
frame_rect(mainPtr(), tiny_to, sf::Color::Black);
|
frame_rect(mainPtr(), tiny_to, frame_colour);
|
||||||
if(pic >= 1000) {
|
if(pic >= 1000) {
|
||||||
std::shared_ptr<const sf::Texture> source_gworld;
|
std::shared_ptr<const sf::Texture> source_gworld;
|
||||||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
||||||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
} else {
|
} else {
|
||||||
tiny_from = {0,0,18,18};
|
tiny_from = {0,0,18,18};
|
||||||
tiny_from.offset((pic % 10) * 18,(pic / 10) * 18);
|
tiny_from.offset((pic % 10) * 18,(pic / 10) * 18);
|
||||||
rect_draw_some_item(*ResMgr::graphics.get("tinyobj"), tiny_from, mainPtr(), tiny_to, sf::BlendAlpha);
|
rect_draw_some_item(*ResMgr::graphics.get("tinyobj"), tiny_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||||||
}
|
}
|
||||||
break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,6 +59,7 @@ short cur_viewing_mode = 0;
|
|||||||
short cen_x, cen_y;
|
short cen_x, cen_y;
|
||||||
eScenMode overall_mode = MODE_INTRO_SCREEN;
|
eScenMode overall_mode = MODE_INTRO_SCREEN;
|
||||||
std::shared_ptr<cScrollbar> right_sbar, pal_sbar;
|
std::shared_ptr<cScrollbar> right_sbar, pal_sbar;
|
||||||
|
std::shared_ptr<cTextField> palette_search_field;
|
||||||
short mode_count = 0;
|
short mode_count = 0;
|
||||||
short right_button_hovered = -1;
|
short right_button_hovered = -1;
|
||||||
|
|
||||||
@@ -91,6 +92,8 @@ void save_prefs();
|
|||||||
cScenario scenario;
|
cScenario scenario;
|
||||||
rectangle right_sbar_rect;
|
rectangle right_sbar_rect;
|
||||||
extern rectangle terrain_buttons_rect;
|
extern rectangle terrain_buttons_rect;
|
||||||
|
rectangle search_field_text_rect;
|
||||||
|
rectangle search_field_rect;
|
||||||
|
|
||||||
extern void set_up_apple_events();
|
extern void set_up_apple_events();
|
||||||
|
|
||||||
@@ -245,6 +248,24 @@ static void init_scrollbars() {
|
|||||||
init_sbar(pal_sbar, "pal_sbar", pal_sbar_rect, pal_sbar_event_rect, 16);
|
init_sbar(pal_sbar, "pal_sbar", pal_sbar_rect, pal_sbar_event_rect, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_search_field() {
|
||||||
|
search_field_text_rect.top = RIGHT_AREA_UL_Y + RIGHT_AREA_HEIGHT + 16;
|
||||||
|
search_field_text_rect.bottom = search_field_text_rect.top + 12;
|
||||||
|
search_field_text_rect.left = RIGHT_AREA_UL_X + 5;
|
||||||
|
TextStyle style;
|
||||||
|
search_field_text_rect.right = search_field_text_rect.left + string_length("Search: ", style);
|
||||||
|
search_field_rect = search_field_text_rect;
|
||||||
|
search_field_rect.offset({search_field_text_rect.width() + 5, -2});
|
||||||
|
search_field_rect.width() = RIGHT_AREA_WIDTH / 2;
|
||||||
|
|
||||||
|
static cParentless mainWin(mainPtr());
|
||||||
|
palette_search_field.reset(new cTextField(mainWin));
|
||||||
|
palette_search_field->setBounds(search_field_rect);
|
||||||
|
palette_search_field->show();
|
||||||
|
drawable_mgr.add_drawable(UI_LAYER_DEFAULT, "search_field", palette_search_field);
|
||||||
|
event_listeners["search_field"] = std::dynamic_pointer_cast<iEventListener>(palette_search_field);
|
||||||
|
}
|
||||||
|
|
||||||
sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, float ui_scale) {
|
sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, float ui_scale) {
|
||||||
|
|
||||||
// See compute_viewport() in boe.graphics.cpp
|
// See compute_viewport() in boe.graphics.cpp
|
||||||
@@ -340,6 +361,7 @@ void init_scened(int argc, char* argv[]) {
|
|||||||
cen_y = 18;
|
cen_y = 18;
|
||||||
|
|
||||||
init_scrollbars();
|
init_scrollbars();
|
||||||
|
init_search_field();
|
||||||
init_lb();
|
init_lb();
|
||||||
init_rb();
|
init_rb();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user