mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:50:04 +00:00 
			
		
		
		
	Allow icons to have a variable anchor
This commit is contained in:
		
							parent
							
								
									50e0036e0b
								
							
						
					
					
						commit
						f6ac027725
					
				
					 4 changed files with 67 additions and 36 deletions
				
			
		|  | @ -1,5 +1,4 @@ | |||
| #include <scwx/qt/gl/draw/icons.hpp> | ||||
| #include <scwx/qt/types/icon_types.hpp> | ||||
| #include <scwx/qt/util/maplibre.hpp> | ||||
| #include <scwx/qt/util/texture_atlas.hpp> | ||||
| #include <scwx/qt/util/tooltip.hpp> | ||||
|  | @ -80,9 +79,10 @@ public: | |||
| 
 | ||||
|    std::mutex iconMutex_; | ||||
| 
 | ||||
|    boost::unordered_flat_map<std::string, types::IconInfo> | ||||
|    boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>> | ||||
|       currentIconSheets_ {}; | ||||
|    boost::unordered_flat_map<std::string, types::IconInfo> newIconSheets_ {}; | ||||
|    boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>> | ||||
|       newIconSheets_ {}; | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<IconDrawItem>> currentIconList_ {}; | ||||
|    std::vector<std::shared_ptr<IconDrawItem>> newIconList_ {}; | ||||
|  | @ -243,17 +243,19 @@ void Icons::StartIconSheets() | |||
|    p->newIconSheets_.clear(); | ||||
| } | ||||
| 
 | ||||
| void Icons::AddIconSheet(const std::string& name, | ||||
| std::shared_ptr<types::IconInfo> Icons::AddIconSheet(const std::string& name, | ||||
|                                                      std::size_t  iconWidth, | ||||
|                                                      std::size_t  iconHeight, | ||||
|                                                      std::int32_t hotX, | ||||
|                                                      std::int32_t hotY) | ||||
| { | ||||
|    // Populate icon sheet map
 | ||||
|    p->newIconSheets_.emplace(std::piecewise_construct, | ||||
|    return p->newIconSheets_ | ||||
|       .emplace(std::piecewise_construct, | ||||
|                std::tuple {name}, | ||||
|                              std::forward_as_tuple(types::IconInfo { | ||||
|                                 name, iconWidth, iconHeight, hotX, hotY})); | ||||
|                std::forward_as_tuple(std::make_shared<types::IconInfo>( | ||||
|                   name, iconWidth, iconHeight, hotX, hotY))) | ||||
|       .first->second; | ||||
| } | ||||
| 
 | ||||
| void Icons::FinishIconSheets() | ||||
|  | @ -261,7 +263,7 @@ void Icons::FinishIconSheets() | |||
|    // Update icon sheets
 | ||||
|    for (auto& iconSheet : p->newIconSheets_) | ||||
|    { | ||||
|       iconSheet.second.UpdateTextureInfo(); | ||||
|       iconSheet.second->UpdateTextureInfo(); | ||||
|    } | ||||
| 
 | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
|  | @ -375,7 +377,7 @@ void Icons::Impl::UpdateBuffers() | |||
|       auto& icon = it->second; | ||||
| 
 | ||||
|       // Validate icon
 | ||||
|       if (di->iconIndex_ >= icon.numIcons_) | ||||
|       if (di->iconIndex_ >= icon->numIcons_) | ||||
|       { | ||||
|          // No icon found
 | ||||
|          logger_->warn("Invalid icon index: {}", di->iconIndex_); | ||||
|  | @ -390,12 +392,12 @@ void Icons::Impl::UpdateBuffers() | |||
|       const float y = static_cast<float>(di->y_); | ||||
| 
 | ||||
|       // Icon size
 | ||||
|       const float iw = static_cast<float>(icon.iconWidth_); | ||||
|       const float ih = static_cast<float>(icon.iconHeight_); | ||||
|       const float iw = static_cast<float>(icon->iconWidth_); | ||||
|       const float ih = static_cast<float>(icon->iconHeight_); | ||||
| 
 | ||||
|       // Hot X/Y (zero-based icon center)
 | ||||
|       const float hx = static_cast<float>(icon.hotX_); | ||||
|       const float hy = static_cast<float>(icon.hotY_); | ||||
|       const float hx = static_cast<float>(icon->hotX_); | ||||
|       const float hy = static_cast<float>(icon->hotY_); | ||||
| 
 | ||||
|       // Final X/Y offsets in pixels
 | ||||
|       const float lx = std::roundf(-hx); | ||||
|  | @ -477,7 +479,7 @@ void Icons::Impl::UpdateTextureBuffer() | |||
|       auto& icon = it->second; | ||||
| 
 | ||||
|       // Validate icon
 | ||||
|       if (di->iconIndex_ >= icon.numIcons_) | ||||
|       if (di->iconIndex_ >= icon->numIcons_) | ||||
|       { | ||||
|          // No icon found
 | ||||
|          logger_->error("Invalid icon index: {}", di->iconIndex_); | ||||
|  | @ -503,17 +505,17 @@ void Icons::Impl::UpdateTextureBuffer() | |||
|       } | ||||
| 
 | ||||
|       // Texture coordinates
 | ||||
|       const std::size_t iconRow    = (di->iconIndex_) / icon.columns_; | ||||
|       const std::size_t iconColumn = (di->iconIndex_) % icon.columns_; | ||||
|       const std::size_t iconRow    = (di->iconIndex_) / icon->columns_; | ||||
|       const std::size_t iconColumn = (di->iconIndex_) % icon->columns_; | ||||
| 
 | ||||
|       const float iconX = iconColumn * icon.scaledWidth_; | ||||
|       const float iconY = iconRow * icon.scaledHeight_; | ||||
|       const float iconX = iconColumn * icon->scaledWidth_; | ||||
|       const float iconY = iconRow * icon->scaledHeight_; | ||||
| 
 | ||||
|       const float ls = icon.texture_.sLeft_ + iconX; | ||||
|       const float rs = ls + icon.scaledWidth_; | ||||
|       const float tt = icon.texture_.tTop_ + iconY; | ||||
|       const float bt = tt + icon.scaledHeight_; | ||||
|       const float r  = static_cast<float>(icon.texture_.layerId_); | ||||
|       const float ls = icon->texture_.sLeft_ + iconX; | ||||
|       const float rs = ls + icon->scaledWidth_; | ||||
|       const float tt = icon->texture_.tTop_ + iconY; | ||||
|       const float bt = tt + icon->scaledHeight_; | ||||
|       const float r  = static_cast<float>(icon->texture_.layerId_); | ||||
| 
 | ||||
|       // clang-format off
 | ||||
|       textureBuffer_.insert( | ||||
|  | @ -541,7 +543,7 @@ void Icons::Impl::Update(bool textureAtlasChanged) | |||
|       // Update texture coordinates
 | ||||
|       for (auto& iconSheet : currentIconSheets_) | ||||
|       { | ||||
|          iconSheet.second.UpdateTextureInfo(); | ||||
|          iconSheet.second->UpdateTextureInfo(); | ||||
|       } | ||||
| 
 | ||||
|       // Update OpenGL texture buffer data
 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| 
 | ||||
| #include <scwx/qt/gl/gl_context.hpp> | ||||
| #include <scwx/qt/gl/draw/draw_item.hpp> | ||||
| #include <scwx/qt/types/icon_types.hpp> | ||||
| 
 | ||||
| #include <boost/gil.hpp> | ||||
| #include <units/angle.h> | ||||
|  | @ -69,8 +70,10 @@ public: | |||
|     * Default is -1 to center the icon. | ||||
|     * @param [in] hotY The zero-based center of the each icon in the icon sheet. | ||||
|     * Default is -1 to center the icon. | ||||
|     * | ||||
|     * @return Icon info | ||||
|     */ | ||||
|    void AddIconSheet(const std::string& name, | ||||
|    std::shared_ptr<types::IconInfo> AddIconSheet(const std::string& name, | ||||
|                                                  std::size_t  iconWidth  = 0, | ||||
|                                                  std::size_t  iconHeight = 0, | ||||
|                                                  std::int32_t hotX       = -1, | ||||
|  |  | |||
|  | @ -7,6 +7,11 @@ namespace qt | |||
| namespace types | ||||
| { | ||||
| 
 | ||||
| void IconInfo::SetAnchor(float anchorX, float anchorY) | ||||
| { | ||||
|    anchor_ = {anchorX, anchorY}; | ||||
| } | ||||
| 
 | ||||
| void IconInfo::UpdateTextureInfo() | ||||
| { | ||||
|    texture_ = util::TextureAtlas::Instance().GetTextureAttributes(iconSheet_); | ||||
|  | @ -26,10 +31,26 @@ void IconInfo::UpdateTextureInfo() | |||
|    } | ||||
| 
 | ||||
|    if (hotX_ == -1 || hotY_ == -1) | ||||
|    { | ||||
|       if (anchor_.has_value()) | ||||
|       { | ||||
|          hotX_ = | ||||
|             std::clamp<std::int32_t>(static_cast<std::int32_t>(std::lround( | ||||
|                                         iconWidth_ * anchor_.value().first)), | ||||
|                                      0, | ||||
|                                      static_cast<std::int32_t>(iconWidth_)); | ||||
|          hotY_ = | ||||
|             std::clamp<std::int32_t>(static_cast<std::int32_t>(std::lround( | ||||
|                                         iconHeight_ * anchor_.value().second)), | ||||
|                                      0, | ||||
|                                      static_cast<std::int32_t>(iconHeight_)); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          hotX_ = static_cast<std::int32_t>(iconWidth_ / 2); | ||||
|          hotY_ = static_cast<std::int32_t>(iconHeight_ / 2); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    numIcons_ = columns_ * rows_; | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,9 @@ | |||
| 
 | ||||
| #include <scwx/qt/util/texture_atlas.hpp> | ||||
| 
 | ||||
| #include <optional> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -26,6 +28,7 @@ struct IconInfo | |||
|    { | ||||
|    } | ||||
| 
 | ||||
|    void SetAnchor(float anchorX, float anchorY); | ||||
|    void UpdateTextureInfo(); | ||||
| 
 | ||||
|    std::string             iconSheet_; | ||||
|  | @ -39,6 +42,8 @@ struct IconInfo | |||
|    std::size_t             numIcons_ {}; | ||||
|    float                   scaledWidth_ {}; | ||||
|    float                   scaledHeight_ {}; | ||||
| 
 | ||||
|    std::optional<std::pair<float, float>> anchor_ {}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace types
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat