File | Lines added | Lines deleted |
---|---|---|
Mode.cpp | 3 | 0 |
Mode.hpp | 7 | 2 |
Modes.cpp | 24 | 6 |
Modes.hpp | 11 | 4 |
engine/mode.h | 9 | 0 |
File Mode.cpp changed (mode: 100644) (index 5cf602c..88d58b7) | |||
... | ... | Shortcut::Shortcut(std::wstring shortcut, std::function<void(int)> handler, | |
39 | 39 | descr(std::move(descr)) | descr(std::move(descr)) |
40 | 40 | { } | { } |
41 | 41 | ||
42 | Mode::Mode(std::string id) : id(std::move(id)) | ||
43 | { } | ||
44 | |||
42 | 45 | void | void |
43 | 46 | Mode::addShortcut(Shortcut shortcut) | Mode::addShortcut(Shortcut shortcut) |
44 | 47 | { | { |
File Mode.hpp changed (mode: 100644) (index 91970a8..21322f0) | |||
... | ... | struct Shortcut | |
48 | 48 | class Mode | class Mode |
49 | 49 | { | { |
50 | 50 | public: | public: |
51 | // Initializes empty mode. | ||
52 | Mode() = default; | ||
51 | // Initializes empty mode with the specified id. | ||
52 | explicit Mode(std::string id); | ||
53 | 53 | ||
54 | 54 | Mode(const Mode &rhs) = delete; | Mode(const Mode &rhs) = delete; |
55 | 55 | Mode(Mode &&rhs) = default; | Mode(Mode &&rhs) = default; |
... | ... | public: | |
57 | 57 | Mode & operator=(Mode &&rhs) = default; | Mode & operator=(Mode &&rhs) = default; |
58 | 58 | ||
59 | 59 | public: | public: |
60 | // Retrieves id of the mode. | ||
61 | const std::string & getId() const | ||
62 | { return id; } | ||
63 | |||
60 | 64 | // Sets whether count is used by shortcuts. | // Sets whether count is used by shortcuts. |
61 | 65 | void setUsesCount(bool uses) | void setUsesCount(bool uses) |
62 | 66 | { useCount = uses; } | { useCount = uses; } |
... | ... | public: | |
72 | 76 | { return shortcuts; } | { return shortcuts; } |
73 | 77 | ||
74 | 78 | private: | private: |
79 | std::string id; // Identifier of the mode. | ||
75 | 80 | std::deque<Shortcut> shortcuts; // Shortcuts of this mode. | std::deque<Shortcut> shortcuts; // Shortcuts of this mode. |
76 | 81 | bool useCount = false; // Whether count is used by shortcuts. | bool useCount = false; // Whether count is used by shortcuts. |
77 | 82 | }; | }; |
File Modes.cpp changed (mode: 100644) (index 34cfeff..253b647) | |||
20 | 20 | ||
21 | 21 | #include <cassert> | #include <cassert> |
22 | 22 | ||
23 | #include <iterator> | ||
23 | 24 | #include <stdexcept> | #include <stdexcept> |
24 | 25 | #include <utility> | #include <utility> |
25 | 26 | #include <vector> | #include <vector> |
26 | 27 | ||
27 | 28 | #include "engine/keys.h" | #include "engine/keys.h" |
29 | #include "engine/mode.h" | ||
28 | 30 | #include "Mode.hpp" | #include "Mode.hpp" |
29 | 31 | ||
30 | 32 | using namespace vle; | using namespace vle; |
... | ... | Modes::reset() | |
72 | 74 | void | void |
73 | 75 | Modes::init(std::vector<Mode> &&modesInfo) | Modes::init(std::vector<Mode> &&modesInfo) |
74 | 76 | { | { |
75 | modes = std::move(modesInfo); | ||
77 | for (Mode &mode : modesInfo) { | ||
78 | if (!modes.emplace(mode.getId(), std::move(mode)).second) { | ||
79 | throw std::invalid_argument("Duplicated mode id:" + mode.getId()); | ||
80 | } | ||
81 | } | ||
76 | 82 | ||
77 | 83 | modeKeyFlags.reserve(modes.size()); | modeKeyFlags.reserve(modes.size()); |
78 | for (const Mode &mode : modes) { | ||
79 | modeKeyFlags.push_back(mode.usesCount() ? MF_USES_COUNT : 0); | ||
84 | for (const auto &entry : modes) { | ||
85 | modeKeyFlags.push_back(entry.second.usesCount() ? MF_USES_COUNT : 0); | ||
80 | 86 | } | } |
81 | 87 | ||
82 | 88 | auto silence = [](int /*more*/) { }; | auto silence = [](int /*more*/) { }; |
83 | 89 | vle_keys_init(modes.size(), &modeKeyFlags[0], silence); | vle_keys_init(modes.size(), &modeKeyFlags[0], silence); |
84 | 90 | ||
85 | for (unsigned int i = 0U; i < modes.size(); ++i) { | ||
91 | int modeId = 0; | ||
92 | for (const auto &entry : modes) { | ||
86 | 93 | std::vector<keys_add_info_t> keys; | std::vector<keys_add_info_t> keys; |
87 | for (const Shortcut &sh : modes[i].getShortcuts()) { | ||
94 | for (const Shortcut &sh : entry.second.getShortcuts()) { | ||
88 | 95 | keys_add_info_t addInfo = {}; | keys_add_info_t addInfo = {}; |
89 | 96 | wcscpy(const_cast<wchar_t *>(addInfo.keys), sh.shortcut.c_str()); | wcscpy(const_cast<wchar_t *>(addInfo.keys), sh.shortcut.c_str()); |
90 | 97 | addInfo.info.data.handler = &keyHandler; | addInfo.info.data.handler = &keyHandler; |
... | ... | Modes::init(std::vector<Mode> &&modesInfo) | |
95 | 102 | keys.push_back(addInfo); | keys.push_back(addInfo); |
96 | 103 | } | } |
97 | 104 | ||
98 | int ret_code = vle_keys_add(&keys[0], keys.size(), i); | ||
105 | int ret_code = vle_keys_add(&keys[0], keys.size(), modeId++); | ||
99 | 106 | assert(ret_code == 0 && "Failed to add builtin keys"); | assert(ret_code == 0 && "Failed to add builtin keys"); |
100 | 107 | (void)ret_code; | (void)ret_code; |
101 | 108 | } | } |
102 | 109 | } | } |
110 | |||
111 | void | ||
112 | Modes::switchTo(const std::string &modeId) | ||
113 | { | ||
114 | auto it = modes.find(modeId); | ||
115 | if (it == modes.end()) { | ||
116 | throw std::invalid_argument("Unknown mode id:" + modeId); | ||
117 | } | ||
118 | |||
119 | vle_mode_set(std::distance(modes.begin(), it), VMT_PRIMARY); | ||
120 | } |
File Modes.hpp changed (mode: 100644) (index 4008b3b..ebabafc) | |||
19 | 19 | #ifndef LIBVLE__MODES_HPP__ | #ifndef LIBVLE__MODES_HPP__ |
20 | 20 | #define LIBVLE__MODES_HPP__ | #define LIBVLE__MODES_HPP__ |
21 | 21 | ||
22 | #include <string> | ||
23 | #include <unordered_map> | ||
22 | 24 | #include <vector> | #include <vector> |
23 | 25 | ||
24 | namespace vle { | ||
26 | #include "Mode.hpp" | ||
25 | 27 | ||
26 | class Mode; | ||
28 | namespace vle { | ||
27 | 29 | ||
28 | 30 | // Handles initialization and deinitialization of modes. | // Handles initialization and deinitialization of modes. |
29 | 31 | class Modes | class Modes |
... | ... | public: | |
43 | 45 | // Initializes modes. Throws `std::invalid_argument` on duplicated mode ids | // Initializes modes. Throws `std::invalid_argument` on duplicated mode ids |
44 | 46 | // or empty list of modes. | // or empty list of modes. |
45 | 47 | void setModes(std::vector<Mode> modesInfo); | void setModes(std::vector<Mode> modesInfo); |
48 | // Switches to the mode specified by its id. Throws `std::invalid_argument` | ||
49 | // on unknown mode id. | ||
50 | void switchTo(const std::string &modeId); | ||
46 | 51 | ||
47 | 52 | private: | private: |
48 | 53 | // Deinitializes all modes. | // Deinitializes all modes. |
... | ... | private: | |
52 | 57 | void init(std::vector<Mode> &&modesInfo); | void init(std::vector<Mode> &&modesInfo); |
53 | 58 | ||
54 | 59 | private: | private: |
55 | std::vector<Mode> modes; // Data that describes modes. | ||
56 | std::vector<int> modeKeyFlags; // Key processing flags of each mode. | ||
60 | // Data that describes modes. | ||
61 | std::unordered_map<std::string, Mode> modes; | ||
62 | // Key processing flags of each mode. | ||
63 | std::vector<int> modeKeyFlags; | ||
57 | 64 | }; | }; |
58 | 65 | ||
59 | 66 | } | } |
File engine/mode.h changed (mode: 100644) (index 9c88245..e18cf20) | |||
34 | 34 | * - secondary mode present, which makes "current" and "primary" modes be | * - secondary mode present, which makes "current" and "primary" modes be |
35 | 35 | * different. */ | * different. */ |
36 | 36 | ||
37 | #ifdef __cplusplus | ||
38 | extern "C" | ||
39 | { | ||
40 | #endif | ||
41 | |||
37 | 42 | /* Type of mode. */ | /* Type of mode. */ |
38 | 43 | typedef enum | typedef enum |
39 | 44 | { | { |
... | ... | int vle_primary_mode_is(vle_mode_t mode); | |
62 | 67 | /* Sets current mode of the specified type. */ | /* Sets current mode of the specified type. */ |
63 | 68 | void vle_mode_set(vle_mode_t mode, VleModeType type); | void vle_mode_set(vle_mode_t mode, VleModeType type); |
64 | 69 | ||
70 | #ifdef __cplusplus | ||
71 | } | ||
72 | #endif | ||
73 | |||
65 | 74 | #endif /* VIFM__ENGINE__MODE_H__ */ | #endif /* VIFM__ENGINE__MODE_H__ */ |
66 | 75 | ||
67 | 76 | /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ | /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |