|
1 | 1 | /* |
2 | | - * BackgroundImage.cpp |
| 2 | + * BackgroundImages.cpp |
3 | 3 | * Maintains the background image data |
4 | 4 | */ |
5 | 5 |
|
|
20 | 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | 21 | */ |
22 | 22 |
|
23 | | -#include "BackgroundImage.h" |
| 23 | +#include "BackgroundImages.h" |
| 24 | +#include "cc_image.h" |
24 | 25 | #include <algorithm> |
25 | 26 |
|
| 27 | +class BackgroundImage { |
| 28 | +public: |
| 29 | + BackgroundImage(wxImage const& image, int x, int y, int scaled_width, int scaled_height); |
| 30 | + |
| 31 | + bool MouseClickIsHit(wxMouseEvent const& event, wxDC const& dc) const; |
| 32 | + void OnMouseLeftDown(wxMouseEvent const& event, wxDC const& dc); |
| 33 | + // returns left, top, width, height |
| 34 | + std::array<int, 4> OnMouseLeftUp(wxMouseEvent const& event, wxDC const& dc); |
| 35 | + |
| 36 | + void OnMouseMove(wxMouseEvent const& event, wxDC const& dc); |
| 37 | + void OnPaint(wxDC& dc, bool drawPicAdjustDots, bool selected) const; |
| 38 | + |
| 39 | +private: |
| 40 | + static constexpr auto kCircleSize = 6; |
| 41 | + |
| 42 | + wxImage mImage; |
| 43 | + wxBitmap mBitmap; |
| 44 | + wxPoint mBitmapPoint; |
| 45 | + |
| 46 | + // what type of background adjustments could we do |
| 47 | + enum class BackgroundAdjustType { |
| 48 | + kUpperLeft = 0, |
| 49 | + kUpper, |
| 50 | + kUpperRight, |
| 51 | + kLeft, |
| 52 | + kMove, |
| 53 | + kRight, |
| 54 | + kLowerLeft, |
| 55 | + kLower, |
| 56 | + kLowerRight, |
| 57 | + kLast, |
| 58 | + }; |
| 59 | + BackgroundAdjustType mBackgroundAdjustType; |
| 60 | + |
| 61 | + struct CalculateScaleAndMove { |
| 62 | + public: |
| 63 | + CalculateScaleAndMove(wxPoint startClick, wxRect rect, BackgroundAdjustType adjustType); |
| 64 | + |
| 65 | + wxRect operator()(wxCoord x, wxCoord y, wxRect wxRect); |
| 66 | + wxPoint mStartClick; |
| 67 | + wxRect mRect; |
| 68 | + float mAspectRatio; |
| 69 | + BackgroundAdjustType mAdjustType; |
| 70 | + }; |
| 71 | + std::unique_ptr<CalculateScaleAndMove> mScaleAndMove; |
| 72 | +}; |
| 73 | + |
26 | 74 | BackgroundImage::BackgroundImage(const wxImage& image, int x, int y, int scaled_width, int scaled_height) |
27 | 75 | : mImage(image) |
28 | 76 | , mBitmapPoint(x, y) |
@@ -253,3 +301,72 @@ wxRect BackgroundImage::CalculateScaleAndMove::operator()(wxCoord x, wxCoord y, |
253 | 301 | return rect; |
254 | 302 | } |
255 | 303 | } |
| 304 | + |
| 305 | +BackgroundImages::BackgroundImages() = default; |
| 306 | +BackgroundImages::~BackgroundImages() = default; |
| 307 | + |
| 308 | +void BackgroundImages::SetBackgroundImages(std::vector<CalChart::ImageData> const& images) |
| 309 | +{ |
| 310 | + mBackgroundImages.clear(); |
| 311 | + mWhichBackgroundIndex = -1; |
| 312 | + for (auto&& image : images) { |
| 313 | + // ugh... not sure if there's a better way to pass data to image. |
| 314 | + auto d = static_cast<unsigned char*>(malloc(sizeof(unsigned char) * image.image_width * image.image_height * 3)); |
| 315 | + std::copy(image.data.begin(), image.data.end(), d); |
| 316 | + auto a = static_cast<unsigned char*>(nullptr); |
| 317 | + if (image.alpha.size()) { |
| 318 | + a = static_cast<unsigned char*>(malloc(sizeof(unsigned char) * image.image_width * image.image_height)); |
| 319 | + std::copy(image.alpha.begin(), image.alpha.end(), a); |
| 320 | + wxImage img(image.image_width, image.image_height, d, a); |
| 321 | + mBackgroundImages.emplace_back(img, image.left, image.top, image.scaled_width, image.scaled_height); |
| 322 | + } else { |
| 323 | + wxImage img(image.image_width, image.image_height, d); |
| 324 | + mBackgroundImages.emplace_back(img, image.left, image.top, image.scaled_width, image.scaled_height); |
| 325 | + } |
| 326 | + } |
| 327 | +} |
| 328 | + |
| 329 | +void BackgroundImages::OnPaint(wxDC& dc) const |
| 330 | +{ |
| 331 | + for (auto i = 0; i < static_cast<int>(mBackgroundImages.size()); ++i) { |
| 332 | + mBackgroundImages[i].OnPaint(dc, mAdjustBackgroundMode, mWhichBackgroundIndex == i); |
| 333 | + } |
| 334 | +} |
| 335 | + |
| 336 | +void BackgroundImages::OnMouseLeftDown(wxMouseEvent const& event, wxDC const& dc) |
| 337 | +{ |
| 338 | + if (!mAdjustBackgroundMode) { |
| 339 | + return; |
| 340 | + } |
| 341 | + mWhichBackgroundIndex = -1; |
| 342 | + for (auto i = 0; i < static_cast<int>(mBackgroundImages.size()); ++i) { |
| 343 | + if (mBackgroundImages[i].MouseClickIsHit(event, dc)) { |
| 344 | + mWhichBackgroundIndex = i; |
| 345 | + } |
| 346 | + } |
| 347 | + if (mWhichBackgroundIndex != -1) { |
| 348 | + mBackgroundImages[mWhichBackgroundIndex].OnMouseLeftDown(event, dc); |
| 349 | + } |
| 350 | +} |
| 351 | + |
| 352 | +std::optional<std::tuple<int, std::array<int, 4>>> BackgroundImages::OnMouseLeftUp(wxMouseEvent const& event, wxDC const& dc) |
| 353 | +{ |
| 354 | + if (!mAdjustBackgroundMode) { |
| 355 | + return {}; |
| 356 | + } |
| 357 | + if (mWhichBackgroundIndex >= 0 && mWhichBackgroundIndex < static_cast<int>(mBackgroundImages.size())) { |
| 358 | + return { { mWhichBackgroundIndex, mBackgroundImages[mWhichBackgroundIndex].OnMouseLeftUp(event, dc) } }; |
| 359 | + } |
| 360 | + return {}; |
| 361 | +} |
| 362 | + |
| 363 | +void BackgroundImages::OnMouseMove(wxMouseEvent const& event, wxDC const& dc) |
| 364 | +{ |
| 365 | + if (!mAdjustBackgroundMode) { |
| 366 | + return; |
| 367 | + } |
| 368 | + if (mWhichBackgroundIndex >= 0 && mWhichBackgroundIndex < static_cast<int>(mBackgroundImages.size())) { |
| 369 | + mBackgroundImages[mWhichBackgroundIndex].OnMouseMove(event, dc); |
| 370 | + } |
| 371 | +} |
| 372 | + |
0 commit comments