#pragma once #include //#include "KUIControl.h" #include "KUIControlScroll.h" #include "KUIControlGauge.h" #include //#include #include "enc.h" #include "ItemBase.h" #include class SUIDisplayInfo; class SUIWnd; // sonador #2.1.2.4.3 팻 조작 UI 연동 // 2010.05.11 - prodongi class SCreatureInfo; // 2010.06.09 - prodongi class SInventorySlot; // 2010.07.20 - prodongi class KUIControlMultiIcon; class SGameAvatarEx; class SUIDisplayInfo; class SSkillSlotMgr; class SCreatureSlotMgr; class SGameManager; namespace sui { namespace helper { /// convert numeric to comma numeric... std::string int_to_comma_numeric( __int64 number ); /// convert comma numeric to numeric... __int64 comma_numeric_to_int( const char* number ); /// convert string to indexed string( 'abc_%d' -> 'abc_01' ) std::string indexed_id( const char* format, int index ); } ///< sequence container wiper template< class _Ct > inline void wipe_seq( _Ct& container ) { typedef typename _Ct::iterator iterator; iterator end = container.end(); for( iterator itor = container.begin(); itor != end; ++itor ) if( *itor ) delete *itor; container.clear(); } template< class _Ct, class _Ty > inline void remove_seq( _Ct& container, const _Ty& value ) { container.erase( std::remove( container.begin(), container.end(), value ), container.end() ); } template< typename T > struct type2type { typedef T type_value; }; // sonador 7.0.25 proxy_list 정렬 타입 불일치 문제 수정 template< int T > struct int2type { enum { value = T }; }; /// tree control proxy template< class _Elem > class proxy_tree { public: typedef _Elem element_t; struct node { typedef std::vector< node* > nodes_t; node() : m_parent( 0 ), m_right( 0 ), m_depth( 0 ), m_folded_state( true ) { } node( const element_t& _element ) : m_element( _element ), m_parent( 0 ), m_right( 0 ), m_depth( 0 ), m_folded_state( true ) { } ~node() { wipe_seq( m_children ); } node* add( node* item ) { if( item ) { // setup right hand side... if( !m_children.empty() ) { nodes_t::reverse_iterator ri = m_children.rbegin(); assert( (*ri)->m_right == 0 ); (*ri)->m_right = item; } m_children.push_back( item ); item->m_parent = this; item->on_add(); //item->m_depth = m_depth + 1; } return this; } int depth() const { return m_depth; } int size_children() const { return m_children.size(); } bool empty() const { return m_children.empty(); } int size() const { struct nodeCounter { nodeCounter() : result( 1 ) {} // it's me =) void operator()( const node* item ) { result += item->size(); } int result; }; return std::for_each( m_children.begin(), m_children.end(), nodeCounter() ).result; } int size_visible() const { struct VisibleNodeCounter { VisibleNodeCounter() : result( 1 ) {} // it's me =) void operator()( const node* item ) { result += ( item->folded() ) ? 1 : item->size_visible(); } int result; }; return std::for_each( m_children.begin(), m_children.end(), VisibleNodeCounter() ).result; } void fold() { m_folded_state = true; } void unfold() { m_folded_state = false; } void toggle() { m_folded_state = !m_folded_state; } bool folded() const { return m_folded_state; } node* find( const element_t& element ) { if( m_element == element ) return this; if( !m_children.empty() ) { nodes_t::iterator _i = m_children.begin(), _e = m_children.end(); for( ; _i != _e; ++_i ) { node* _node = (*_i)->find( element ); if( _node ) return _node; } } return 0; } const element_t& get_element() const { return m_element; } element_t& get_element() { return m_element; } typename nodes_t::iterator begin() { return m_children.begin(); } typename nodes_t::iterator end() { return m_children.end(); } node* next() { if( !m_children.empty() ) return *m_children.begin(); return next_without_children(); } node* next_visible() { node* it = next(); while( it ) { if( it->is_visible() ) return it; it = it->next(); } return 0; } node* next_visible_index( int index ) { int loop = 0; node* it = next_visible(); while( it ) { if( index <= loop++ ) break; it = it->next_visible(); } return it; } private: void on_add() { m_depth = m_parent->depth() + 1; nodes_t::iterator i = m_children.begin(), e = m_children.end(); for( ; i != e; ++i ) { (*i)->on_add(); } } bool is_visible() const { return m_parent ? !m_parent->folded() : false; } node* next_without_children() { if( m_right ) return m_right; if( m_parent ) return m_parent->next_without_children(); return 0; } element_t m_element; int m_depth; node* m_parent; node* m_right; nodes_t m_children; bool m_folded_state; }; proxy_tree() : m_root( 0 ), m_selected( 0 ) { m_root = new node(); m_root->unfold(); } ~proxy_tree() { SAFE_DELETE( m_root ); } node* root() { return m_root; } const node* root() const { return m_root; } node* operator->() { return m_root; } const node* operator->() const { return m_root; } node& operator*() { return *m_root; } const node& operator*() const { return *m_root; } private: node* m_root; node* m_selected; }; class property { public: enum CLASSID { CID_NONE, CID_BOOLEAN, CID_CHAR, CID_UCHAR, CID_WORD, CID_DWORD, CID_INT, CID_UINT, CID_INT64, CID_FLOAT, CID_POINTER, CID_RESOURCE, CID_STRING, }; struct finder { finder( const char* name ) : name_for_search( name ) {} bool operator () ( const property* arg ) { return ( ::stricmp( name_for_search, arg->get_name() ) == 0 ) ? true : false; } const char* name_for_search; }; struct AbstractResource { virtual ~AbstractResource() {} virtual void* get_resource() = 0; virtual AbstractResource* clone() = 0; }; /** 프로퍼티에 리소스를 등록하기 위한 클래스( 리소스는 값으로 취급할 수 없다... ) 리소스로 등록되는 클래스는 반드시 복사 생성자를 정의하고 있어야 합니다. */ template< typename T > struct Resource : public AbstractResource { Resource( T* resource ) : AbstractResource(), m_resource( new T( *resource ) ) { } virtual ~Resource() { SAFE_DELETE( m_resource ); } virtual AbstractResource* clone() { return new Resource< T >( m_resource ); } virtual void* get_resource() { return reinterpret_cast< void* >( m_resource ); } T* m_resource; }; property() : m_name( 0 ), m_class( CID_NONE ) { m_value.int_value = 0; } property( const char* name ) : m_name( name ), m_class( CID_NONE ) { m_value.int_value = 0; } property( const property& rhs ) : m_name( rhs.m_name ), m_class( CID_NONE ) { m_value.int_value = 0; copy( rhs ); } virtual ~property() { wipe(); } property& operator = ( const property& rhs ) { copy( rhs ); return *this; } bool operator == ( const property& rhs ) const { return !::strcmp( m_name, rhs.get_name() ); } bool is_valid() const { return ( m_name == 0 || m_class == CID_NONE ) ? false : true; } virtual void copy( const property& other ) { wipe(); m_name = other.m_name; if( other.m_class == CID_STRING ) { char* buffer; other.get_value( buffer ); set_value( buffer ); } else if( other.m_class == CID_RESOURCE ) { m_class = other.m_class; AbstractResource* otherAbsResource = reinterpret_cast< AbstractResource* >( other.m_value.pointer_value ); if( otherAbsResource ) { AbstractResource* myAbsResource = otherAbsResource->clone(); m_value.pointer_value = reinterpret_cast< void* >( myAbsResource ); } } else { m_class = other.m_class; m_value = other.m_value; } } void wipe() { if( m_class == CID_STRING ) { char* buffer = reinterpret_cast< char* >( m_value.pointer_value ); SAFE_DELETE_ARRAY( buffer ); m_value.pointer_value = 0; } else if( m_class == CID_RESOURCE ) { AbstractResource* resource = reinterpret_cast< AbstractResource* >( m_value.pointer_value ); SAFE_DELETE( resource ); m_value.pointer_value = 0; } m_class = CID_NONE; m_value.int_value = 0; } const char* get_name() const { return m_name; } void set_name( const char* name ) { m_name = name; } CLASSID get_class() const { return m_class; } /// setter template< typename T > property& set_resource( T* resource ) { wipe(); m_class = CID_RESOURCE; if( resource ) { Resource< T >* res = new Resource< T >( resource ); m_value.pointer_value = reinterpret_cast< void* >( res ); } return *this; } template< typename T > property& set_value( T value ) { wipe(); m_class = CID_POINTER; m_value.pointer_value = reinterpret_cast< void* >( value ); return *this; } template< > property& set_value< bool >( bool value ) { wipe(); m_class = CID_BOOLEAN; m_value.bool_value = value; return *this; } template< > property& set_value< char >( char value ) { wipe(); m_class = CID_CHAR; m_value.char_value = value; return *this; } template< > property& set_value< unsigned char >( unsigned char value ) { wipe(); m_class = CID_UCHAR; m_value.uchar_value = value; return *this; } template< > property& set_value< WORD >( WORD value ) { wipe(); m_class = CID_WORD; m_value.word_value = value; return *this; } template< > property& set_value< DWORD >( DWORD value ) { wipe(); m_class = CID_DWORD; m_value.dword_value = value; return *this; } template< > property& set_value< float >( float value ) { wipe(); m_class = CID_FLOAT; m_value.float_value = value; return *this; } template< > property& set_value< int >( int value ) { wipe(); m_class = CID_INT; m_value.int_value = value; return *this; } template< > property& set_value< unsigned int >( unsigned int value ) { wipe(); m_class = CID_UINT; m_value.uint_value = value; return *this; } template< > property& set_value< __int64 >( __int64 value ) { wipe(); m_class = CID_INT64; m_value.int64_value = value; return *this; } template< > property& set_value< const char* >( const char* value ) { wipe(); m_class = CID_STRING; int len = ::strlen( value ); char* buffer = new char[ len + 1 ]; ::strcpy( buffer, value ); m_value.pointer_value = reinterpret_cast< void* >( buffer ); return *this; } template< > property& set_value< char* >( char* value ) { wipe(); m_class = CID_STRING; int len = ::strlen( value ); char* buffer = new char[ len + 1 ]; ::strcpy( buffer, value ); m_value.pointer_value = reinterpret_cast< void* >( buffer ); return *this; } /// getter template< typename T > void get_resource( T*& resource ) const { assert( m_class == CID_RESOURCE ); AbstractResource* absResource = reinterpret_cast< AbstractResource* >( m_value.pointer_value ); if( absResource ) { resource = reinterpret_cast< T* >( absResource->get_resource() ); } } template< typename T > void get_value( T& value ) const { assert( m_class == CID_POINTER ); value = reinterpret_cast< T >( m_value.pointer_value ); } template< > void get_value< bool >( bool& value ) const { assert( m_class == CID_BOOLEAN ); value = m_value.bool_value; } template< > void get_value< char >( char& value ) const { assert( m_class == CID_CHAR ); value = m_value.char_value; } template< > void get_value< unsigned char >( unsigned char& value ) const { assert( m_class == CID_UCHAR ); value = m_value.uchar_value; } template< > void get_value< WORD >( WORD& value ) const { assert( m_class == CID_WORD ); value = m_value.word_value; } template< > void get_value< DWORD >( DWORD& value ) const { assert( m_class == CID_DWORD ); value = m_value.dword_value; } template< > void get_value< float >( float& value ) const { assert( m_class == CID_FLOAT ); value = m_value.float_value; } template< > void get_value< int >( int& value ) const { assert( m_class == CID_INT ); value = m_value.int_value; } template< > void get_value< unsigned int >( unsigned int& value ) const { assert( m_class == CID_UINT ); value = m_value.uint_value; } template< > void get_value< __int64 >( __int64& value ) const { assert( m_class == CID_INT64 ); value = m_value.int64_value; } template< > void get_value< char* >( char*& value ) const { assert( m_class == CID_STRING ); value = reinterpret_cast< char* >( m_value.pointer_value ); } template< > void get_value< std::string >( std::string& value ) const { assert( m_class == CID_STRING ); value = reinterpret_cast< char* >( m_value.pointer_value ); } void* get_resource() const { assert( m_class == CID_RESOURCE ); AbstractResource* absResource = reinterpret_cast< AbstractResource* >( m_value.pointer_value ); if( absResource ) return absResource->get_resource(); return 0; } void* get_pointer_value() const { assert( m_class == CID_POINTER ); return m_value.pointer_value; } bool get_boolean_value() const { assert( m_class == CID_BOOLEAN ); return m_value.bool_value; } char get_char_value() const { assert( m_class == CID_CHAR ); return m_value.char_value; } unsigned char get_uchar_value() const { assert( m_class == CID_UCHAR ); return m_value.uchar_value; } WORD get_word_value() const { assert( m_class == CID_WORD ); return m_value.word_value; } DWORD get_dword_value() const { assert( m_class == CID_DWORD ); return m_value.dword_value; } float get_float_value() const { assert( m_class == CID_FLOAT ); return m_value.float_value; } int get_int_value() const { assert( m_class == CID_INT ); return m_value.int_value; } unsigned int get_uint_value() const { assert( m_class == CID_UINT ); return m_value.uint_value; } __int64 get_int64_value() const { assert( m_class == CID_INT64 ); return m_value.int64_value; } const char* get_string_value() const { assert( m_class == CID_STRING ); return reinterpret_cast< const char* >( m_value.pointer_value ); } protected: union value_type { bool bool_value; char char_value; unsigned char uchar_value; WORD word_value; DWORD dword_value; int int_value; unsigned int uint_value; __int64 int64_value; float float_value; void* pointer_value; }; CLASSID m_class; const char* m_name; value_type m_value; }; static property null_property; /// property array class property_array { public: typedef std::vector< property* > properties_t; typedef properties_t::iterator iterator; typedef properties_t::const_iterator const_iterator; property_array(); property_array( const property_array& other ); property_array& operator = ( const property_array& rhs ); virtual ~property_array(); property_array& add( property* prop ); property& get( const char* name ); property& at( int index ); property& operator[]( int index ); property& operator[]( const char* name ); int size() const; bool empty() const; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; protected: void _copy( const property_array& other ); properties_t m_properties; }; /// property for updatable window class kui_window_property : public property { public: kui_window_property( const char* name ) : property( name ) {} kui_window_property( const kui_window_property& rhs ) : property( rhs ) {} virtual ~kui_window_property() {} virtual void on_update( property& data ) = 0; KUIWnd* get_window() { return reinterpret_cast< KUIWnd* >( get_pointer_value() ); } virtual kui_window_property& set_value( KUIWnd* value ) { property::set_value< KUIWnd* >( value ); return *this; } }; // soandor #2.1.2.4.3 팻 조작 UI 연동 /// updatable widow class kui_updatable_window { public: struct finder { finder( const char* name ) : name_for_search( name ) {} bool operator () ( const kui_updatable_window* arg ) { return ( ::stricmp( name_for_search, arg->get_name() ) == 0 ) ? true : false; } const char* name_for_search; }; kui_updatable_window() : m_window( 0 ), m_data( "" ) {} kui_updatable_window( kui_window_property* window ) : m_window( window ), m_data( window->get_name() ) {} virtual ~kui_updatable_window() { SAFE_DELETE( m_window ); } virtual void update() { if( !m_window ) return; m_window->on_update( m_data ); } const char* get_name() const { if( !m_window ) return 0; return m_window->get_name(); } void set_window( kui_window_property* window ) { SAFE_DELETE( m_window ); m_window = window; m_data.set_name( window->get_name() ); } KUIWnd* get_window() { if( !m_window ) return 0; return m_window->get_window(); } template< typename T > void set_data( T data ) { m_data.set_value( data ); } template< typename T > void get_data( T& data ) const { m_data.get_value( data ); } template< typename T > void set_resource( T* resource ) { m_data.set_resource( resource ); } template< typename T > void get_resource( T* resource ) const { m_data.get_resource( T* resource ); } protected: kui_window_property* m_window; property m_data; }; static kui_updatable_window null_updatable_window; /// updatable window array class kui_updatable_window_array { public: typedef std::vector< kui_updatable_window* > window_container_t; typedef window_container_t::iterator iterator; typedef window_container_t::const_iterator const_iterator; kui_updatable_window_array(); ~kui_updatable_window_array(); kui_updatable_window_array& add( kui_updatable_window* window ); kui_updatable_window& get( const char* name ); kui_updatable_window& at( int index ); kui_updatable_window& operator[]( int index ); kui_updatable_window& operator[]( const char* name ); int size() const; bool empty() const; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; void clear(); virtual void update(); protected: window_container_t m_windows; /// disabled... kui_updatable_window_array( const kui_updatable_window_array& other ); kui_updatable_window_array& operator = ( const kui_updatable_window_array& rhs ); }; /// list control proxy class proxy_list { public: enum { INVALID_VALUE = -1 }; typedef property_array item_t; typedef proxy_list this_t; typedef std::vector< item_t* > item_container_t; typedef std::vector< kui_window_property* > control_row_t; typedef std::vector< control_row_t* > control_matrix_t; typedef std::vector< KUIWnd* > selectables_t; typedef item_container_t::iterator iterator; // ctor and dtor proxy_list( SUIWnd* window, const char* id, int limit, int item_offset = 0 ); ~proxy_list(); // public interface void initialize( const char* selectable_id = 0, const char* selection_mask_id = 0, const char* scroll_id = 0 ); void clear(); void update_data(); // kui method void proc_pumpup( LPCSTR id, DWORD message, DWORD lparam, DWORD wparam ); void proc_mouse( DWORD msg, int x, int y ); void activate_mouse_proc( bool activity ); // list method void save_state(); void load_state(); this_t& add( item_t* item ); void remove( item_t* item ); template< class _Pred > void remove_if( _Pred pred ) { m_items.erase( std::remove_if( begin(), end(), pred ), m_items.end() ); _update_scroll_range(); } bool empty() const; int size() const; iterator begin(); iterator end(); iterator visible_begin(); iterator visible_end(); item_t* at( int item_index ); item_t* operator[ ]( int item_index ); int get_offset() const { return m_offset; } // #2.1.2.4.3 void next_page(); void prev_page(); int page_begin() const; int page_end() const; int page() const; // { sonador 7.0.25 proxy_list 정렬 타입 불일치 문제 수정 template< typename _Ty, typename _Pr > void sort( const char* column_name, _Pr pred ) { std::sort( begin(), end(), sort_column< _Ty, _Pr, false >( column_name, pred ) ); } template< typename _Ty, typename _Pr > void sort_resource( const char* column_name, _Pr pred ) { std::sort( begin(), end(), sort_column< _Ty, _Pr, true >( column_name, pred ) ); } template< typename _Ty, typename _Pr > void stable_sort( const char* column_name, _Pr pred ) { std::stable_sort( begin(), end(), sort_column< _Ty, _Pr, false >( column_name, pred ) ); } template< typename _Ty, typename _Pr > void stable_sort_resource( const char* column_name, _Pr pred ) { std::stable_sort( begin(), end(), sort_column< _Ty, _Pr, true >( column_name, pred ) ); } // } // control method template< typename property_t > bool add_column( const char* window_id, property_t* origin_property ) { std::string indexed_id_orig = helper::indexed_id( window_id , 0 ); KUIWnd* wnd = m_window->GetChild( indexed_id_orig.c_str() ); if( wnd == 0 ) return false; m_window->SetChildAsTop( indexed_id_orig.c_str() ); m_control_matrix.at( 0 )->push_back( &( origin_property->set_value( wnd ) ) ); RECT region_offset; region_offset.left = 0; region_offset.right = 0; // n = 1 : our original control index ... for( int n = 1; n < m_limit; ++n ) { int offset = n * m_item_offset; region_offset.top = offset; region_offset.bottom = offset; m_control_matrix.at( n )->push_back( &( new property_t( *origin_property ) )->set_value( m_window->CopyControl( indexed_id_orig.c_str(), helper::indexed_id( window_id, n ).c_str(), region_offset ) ) ); } return true; } property* get_window_property( int row, const char* column_id ); private: // sonador 7.0.25 proxy_list 정렬 타입 불일치 문제 수정 template< typename _Ty, typename _Pr, bool _IsRes = false > struct sort_column { sort_column( const char* column_name, const _Pr& pred ) : m_column_name( column_name ), m_pred( pred ) {} bool operator () ( item_t* lhs, item_t* rhs ) const { property& lhs_column = lhs->get( m_column_name ); property& rhs_column = rhs->get( m_column_name ); if( !rhs_column.is_valid() ) return false; if( !lhs_column.is_valid() ) return true; return compare_property( lhs_column, rhs_column, int2type< _IsRes >() ); } bool compare_property( const property& lhs, const property& rhs, int2type< false > ) const { _Ty lhs_value, rhs_value; lhs.get_value< _Ty >( lhs_value ); rhs.get_value< _Ty >( rhs_value ); return m_pred( lhs_value, rhs_value ); } bool compare_property( const property& lhs, const property& rhs, int2type< true > ) const { _Ty *lhs_value, *rhs_value; lhs.get_resource< _Ty >( lhs_value ); rhs.get_resource< _Ty >( rhs_value ); return m_pred( *lhs_value, *rhs_value ); } const char* m_column_name; const _Pr& m_pred; }; void _init_scroll( const char* window_id ); void _init_selectables( const char* window_id ); void _init_selection_mask( const char* selection_mask_id ); int _normalize_offset( int offset ); bool _is_valid_index( int control_index ) const; bool _is_visible_index( int control_index ) const; int _get_visible_end_index() const; int _to_item_index( int control_index ) const; int _to_control_index( int item_index ) const; int _mouse_to_index( int x, int y ) const; int _change_current_index( int new_item_index ); int _get_page_from( int item_index ) const; bool _is_valid_page( int page ) const; void _set_offset_by( int page ); int _select_item_by( int control_index = INVALID_VALUE ); void _locate_selection_mask_at( int control_index = INVALID_VALUE ); void _update_scroll_range(); const char* m_id; const unsigned int m_limit; const unsigned int m_item_offset; int m_offset; int m_current_index; int m_saved_offset; int m_saved_index; SUIWnd* m_window; KUIControlScrollBase* m_scroll; KUIWnd* m_selection_mask; int m_selection_mask_origin_offset; selectables_t m_selectables; item_container_t m_items; control_matrix_t m_control_matrix; bool m_proc_mouse; }; template< typename _Ty > class spin_cache { public: enum { INITIAL_INDEX = -1 }; typedef std::vector< _Ty > cache_t; typedef typename cache_t::iterator iterator; spin_cache( int maxCache ) : m_maxCache( maxCache ), m_index( INITIAL_INDEX ) { } void push( const _Ty& value ) { m_cache.insert( m_cache.begin(), value ); normalizeCache(); while( overflow() ) { m_cache.pop_back(); } resetIndex(); } void clear() { resetIndex(); m_cache.clear(); } bool empty() const { return m_cache.empty(); } iterator next() { normalizeIndex( ++m_index ); return isValid( m_index ) ? m_cache.begin() + m_index : m_cache.end(); } iterator prev() { normalizeIndex( --m_index ); return isValid( m_index ) ? m_cache.begin() + m_index : m_cache.end(); } iterator begin() { return m_cache.begin(); } iterator end() { return m_cache.end(); } void pop_front() { if( !m_cache.empty() ) { m_cache.erase( m_cache.begin() ); } } void pop_back() { if( !m_cache.empty() ) { m_cache.pop_back(); } } protected: bool overflow() const { return ( m_cache.size() > m_maxCache ) ? true : false; } void normalizeCache() { typedef std::vector< std::string > cache_t; cache_t new_cache; new_cache.reserve( m_maxCache ); cache_t::iterator i = m_cache.begin(), e = m_cache.end(); for( ; i != e; ++i ) { cache_t::iterator i_found = std::find( new_cache.begin(), new_cache.end(), *i ); if( i_found != new_cache.end() ) continue; new_cache.push_back( *i ); } m_cache.clear(); m_cache.assign( new_cache.begin(), new_cache.end() ); } void normalizeIndex( int& index ) { if( index < 0 ) index = m_cache.size() - 1; else if( index >= m_cache.size() ) index = 0; } void resetIndex() { m_index = INITIAL_INDEX; } bool isValid( int index ) { return ( index < 0 || index >= m_cache.size() ) ? false : true; } std::vector< std::string > m_cache; const int m_maxCache; int m_index; }; class ticker; class tickable { public: tickable() : m_ticker( 0 ) {} virtual ~tickable() {} // transitive methods virtual void on_tick() = 0; virtual void on_enter() = 0; virtual void on_leave() = 0; ticker* get_ticker() { return m_ticker; } protected: friend class ticker; void set_ticker( ticker* _ticker ); ticker* m_ticker; }; class ticker : public tickable { public: ticker() : tickable(), m_time( 0 ), m_is_on_tick( false ), m_lock( false ) {} virtual ~ticker() {} virtual void on_tick() { tick( m_ticker->time() ); } virtual void on_enter(); virtual void on_leave(); virtual void tick( DWORD time ); virtual void enter(); virtual void leave(); bool append_tickable( tickable* _tickable ); bool remove_tickable( tickable* _tickable ); DWORD time() const { return m_time; } bool is_on_tick() const { return m_is_on_tick; } protected: typedef std::vector< tickable* > tickable_vector_t; typedef std::queue< tickable* > tickable_queue_t; tickable_vector_t m_tickables; tickable_queue_t m_candidates; tickable_queue_t m_garbages; DWORD m_time; bool m_is_on_tick; bool m_lock; }; class fixed_rate_ticker : public ticker { public: fixed_rate_ticker( DWORD frequency ) : ticker(), m_frequency( frequency ) { } virtual ~fixed_rate_ticker() {} virtual void on_tick(); virtual void on_enter(); virtual void on_leave(); DWORD frequency() const { return m_frequency; } protected: DWORD m_frequency; }; class fixed_rate_one_time_ticker : public fixed_rate_ticker { public: fixed_rate_one_time_ticker( DWORD frequency ) : fixed_rate_ticker( frequency ) { } virtual ~fixed_rate_one_time_ticker() {} virtual void on_tick(); }; class conditional_fixed_rate_one_time_ticker : public fixed_rate_ticker { public: conditional_fixed_rate_one_time_ticker( DWORD frequency ) : fixed_rate_ticker( frequency ), m_satisfaction( false ) { } virtual ~conditional_fixed_rate_one_time_ticker() {} virtual void on_tick(); virtual void on_enter(); void satisfy(); bool m_satisfaction; }; struct Action { virtual ~Action() {} virtual void operator()() = 0; }; struct ActionEnableControl : public Action { ActionEnableControl( KUIControl* pControl ) : Action(), m_pControl( pControl ) {} virtual void operator()() { if( m_pControl ) m_pControl->Enable(); } KUIControl* m_pControl; }; struct ActionDisableControl : public Action { ActionDisableControl( KUIControl* pControl ) : Action(), m_pControl( pControl ) {} void operator()() { if( m_pControl ) m_pControl->Disable(); } KUIControl* m_pControl; }; struct ActionShowControl : public Action { ActionShowControl( KUIControl* pControl ) : Action(), m_pControl( pControl ) {} void operator()() { if( m_pControl ) m_pControl->SetShow( true ); } KUIControl* m_pControl; }; struct ActionHideControl : public Action { ActionHideControl( KUIControl* pControl ) : Action(), m_pControl( pControl ) {} void operator()() { if( m_pControl ) m_pControl->SetShow( false ); } KUIControl* m_pControl; }; class ActionBinder : public tickable { public: ActionBinder( Action* pOnEnter, Action* pOnTick, Action* pOnLeave ) : tickable() , m_pOnEnterAction( pOnEnter ) , m_pOnTickAction( pOnTick ) , m_pOnLeaveAction( pOnLeave ) { } virtual ~ActionBinder() { SAFE_DELETE( m_pOnTickAction ); SAFE_DELETE( m_pOnEnterAction ); SAFE_DELETE( m_pOnLeaveAction ); } virtual void on_tick() { if( m_pOnTickAction ) (*m_pOnTickAction)(); } virtual void on_enter() { if( m_pOnEnterAction ) (*m_pOnEnterAction)(); } virtual void on_leave() { if( m_pOnLeaveAction ) (*m_pOnLeaveAction)(); } private: Action* m_pOnEnterAction; Action* m_pOnTickAction; Action* m_pOnLeaveAction; }; class Page { public: Page() : m_nCurrentPage( 1 ), m_nEndPage( 1 ), m_pPrevButton( 0 ), m_pNextButton( 0 ) { } void SetButton( class KUIControl* pPrevButton, class KUIControl* pNextButton ); void Update( int nCurrentPage ); void Update( int nCurrentPage, int nEndPage ); int Current() const; int End() const; int Next() const; int Prev() const; private: int _GetNormalizedPage( int nPage ) const; bool _IsEnd() const; bool _IsBegin() const; int m_nCurrentPage; int m_nEndPage; class KUIControl* m_pPrevButton; class KUIControl* m_pNextButton; }; /// 2011.01.20 - prodongi /// 2010.01.20 메인 프레임과 타겟 창에 쓰이는 마크 아이콘 구조체 - prodongi struct sMarkState { enum eState { PC = 0, FREEPASS, PK, PVP, MAX }; struct sInfo { bool m_show; // 프리패스/pc방에서만 쓰인다 int m_stateCode; AR_TIME m_endTime; int m_stateLevel; bool m_toggleSkill; int m_stateValue; ///< 지속효과 관련 추가값 // pk status에만 쓰인다 int m_status; std::string m_strMarkControlName; // 매칭 되어있는 컨트롤 마크 이름 ( 이름은 sortMarkState() 할때마다 바뀜 ) sInfo() : m_show( false ) , m_stateCode( NULL ) , m_endTime( NULL ) , m_stateLevel( NULL ) , m_toggleSkill( NULL ) , m_stateValue( NULL ) , m_strMarkControlName( "" ) { } void setStateSlot( class SStateSlot const* slot ); }; void updateMarkStateList(KUIWnd* wnd, SUIDisplayInfo* displayInfo, SGameAvatarEx* avatar); void updateMarkStatusList(KUIWnd* wnd, SUIDisplayInfo* displayInfo, int status); void sortMarkState(KUIWnd* wnd, SUIDisplayInfo* displayInfo); void hideAllControl(KUIWnd* wnd); void hideAll( void ); bool IsInRectFreePass( KUIWnd* pDestWnd, const KPoint ptMouse ); void UpdateFreePassEndTimeTooltip( KUIWnd* pDestWnd, SUIDisplayInfo* pDisplayInfo ); sInfo m_info[ eState::MAX ]; }; /// 2011.12.12 마우스 영역 체크로 투명/불투명 효과를 주는 구조체 - prodongi struct sOpacityMouseChecker { sOpacityMouseChecker() : m_alphaV(3.0f), m_alpha(0.0f) {} ~sOpacityMouseChecker(); void open(); void update(DWORD dwTime, int x, int y, SUIWnd* wnd); void setAlpha(float alpha); void addChild(SUIWnd* parent, char const* id); void setShow(bool show); void changeAlpha(); float m_alphaV; float m_alpha; std::vector m_childList; }; } // namespace util /// 2012.05.02 클래스의 함수포인터를 등록해서 함수를 호출해주는 템플릿 - prodongi template struct cClassFuncP { typedef void (T::*fp)(); typedef std::map map_fp; ~cClassFuncP() { m_funcList.clear(); } void add(KEY const& id, fp _fp) { map_fp::iterator it = m_funcList.find(id); if (it != m_funcList.end()) return ; m_funcList[id] = _fp; } void del(KEY const& id) { map_fp::iterator it = m_funcList.find(id); if (it == m_funcList.end()) return ; m_funcList.erase(id); } void call(KEY const& id, T* owner) { map_fp::iterator it = m_funcList.find(id); if (it == m_funcList.end()) return ; fp fn = it->second; (owner->*fn)(); } map_fp m_funcList; }; template struct cClassParamFuncP { typedef void (T::*fp)(P); typedef std::map map_fp; ~cClassParamFuncP() { m_funcList.clear(); } void add(KEY const& id, fp _fp) { map_fp::iterator it = m_funcList.find(id); if (it != m_funcList.end()) return ; m_funcList[id] = _fp; } void del(KEY const& id) { map_fp::iterator it = m_funcList.find(id); if (it == m_funcList.end()) return ; m_funcList.erase(id); } void call(KEY const& id, T* owner, P param) { map_fp::iterator it = m_funcList.find(id); if (it == m_funcList.end()) return ; fp fn = it->second; (owner->*fn)(param); } map_fp m_funcList; }; /// 2012.05.09 x, y가 m_emptyRegionControl영역에 있는지 체크하는 구조체 - prodongi struct sEmptyControlRegionChecker { ~sEmptyControlRegionChecker(); bool isIn(int x, int y) const; void add(KUIWnd* control); private: std::list m_controlList; }; class EquipItemAddtionalIconSetter { public: EquipItemAddtionalIconSetter( KUIControlMultiIcon* pIcon, ItemBase::ItemCode nItemCode, int nEnhance, int nEtherealDurability, XFlag xFlag ); EquipItemAddtionalIconSetter( KUIControlMultiIcon* pIcon, SInventorySlot* pSlot ); private: void SetIcon( KUIControlMultiIcon* pIcon, ItemBase::ItemCode nItemCode, int nEnhance, int nEtherealDurability, XFlag xFlag ); }; // 2010.05.11 강화 크리쳐의 아이콘 이름을 구한다 - prodongi void getEnhanceIconName(char* enhanceIconName, SCreatureInfo const* info, int enhance); // 2010.08.31 - prodongi void getEnhanceIconName(char* enhanceIconName, ENC_INT creatureId, int enhance); // 2010.05.13 순수하게 아이템 이름만 뽑는다 - prodongi std::string getItemName(int itemId); // 2010.06.09 내구도에 따른 아이콘 이름 뽑는다 - prodongi void getIconNameAtDurability(SInventorySlot const* slot, std::string& iconName); // 2010.07.06 - prodongi void getIconNameAtDurability(ItemBase::ItemCode itemCode, int enhance, int etherealDurability, std::string& iconName, int nFlag = 0, int nSummonID = 0 ); void getIconNameAtDurability(ItemBase::ItemCode itemCode, int enhance, int etherealDurability, std::string& iconName, XFlag tFlag, int nSummonID = 0 ); // 2013.03.18 - gmpbigsun void getIconNameAtDurability(SInventorySlot const* slot, int nTmep, std::string& iconName); bool setIconNameEquipment_ENHANCE( KUIControlMultiIcon* icon, ENC_INT itemCode, const int nEnhance ); // 봉인카드 테두리아이콘 이름얻기 bool getIconNameSummonCard_BORDER( std::string& strTemp, const int nSummonID, int nEnhance = 0, int nDurability = 0 ); bool getIconNameSummonCard_BELT( std::string& strTemp, AR_HANDLE nHandle ); bool getIconNameSummonCard_FORMATION( std::string& strTemp, AR_HANDLE nHandle ); bool getIconNameSummonCard_STAGE( std::string& strTemp, const int nSummonID, const int nEnhance ); // 2010.07.14 파괴된 크리쳐 카드인지 아닌지- prodongi bool isExhaustedSummonCard(ItemBase::ItemCode itemCode, int enhance, int etherealDurability); // 착용 불가능한 꾸미기 아이템 인가? bool isWearableDecoItem( const ItemBaseEx_info* pItem ); // 착용 불가능한 아이템 아이콘 설정 void setCantWearIcon(KUIControlMultiIcon* icon, ENC_INT itemCode, int nJobID, int nRace, int nLevel, XFlag xFlag, SSkillSlotMgr& SkillSlotMgr ); // 2010.07.20 깨진 아이템 아이콘 설정- prodongi void setDurabilityIcon(KUIControlMultiIcon* icon, ENC_INT itemCode, int etherealDurability); // 강화 실패 아이템 아이콘 설정 void setEnhanceFailedIcon(KUIControlMultiIcon* icon, XFlag xFlag); // 2010.06.11 사용할려는 아이템이 동일한 타입인지 체크 - prodongi bool checkUseEqualHairTypeItem(ItemBase const* item); // 2010.07.27 아이템의 사용 가능 조건을 체크 - prodongi bool checkEnableUseItem(ItemBase const* item, int itemCode, SUIDisplayInfo* displayInfo, int& msgId); // 2010.08.20 set control gage - prodongi void setStaticWndGage(KUIWnd* wnd, int maxSize, float percent); // 2010.09.17 장착 카드 내구도 퍼센트 - prodongi float getEquipCardDurPercent(SInventorySlot const* slot); // 2010.09.17 장착 카드 내구도 퍼센트 단계- prodongi int getEquipCardDurPercentLevel(SInventorySlot const* slot); float getCreatureCardDurPercent(SInventorySlot const* slot, int enhance); // 2010.09.17 카드 내구도 퍼센트 - prodongi float getCreatureCardDurPercent(int etherealDurability, int enhance); /// 2011.03.29 - prodongi int getCreatureCardDurPercentLevel(SInventorySlot const* slot, int enhance);// 2010.09.17 장착 아이템 내구도 퍼센트 단계- prodongi int getCreatureCardDurPercentLevel(int etherealDurability, int enhance); /// 2011.03.29 - prodongi /// 2010.12.17 - prodongi void setChildControlEnable(KUIWnd* parent, char const* childId, bool enable); std::string expToString(__int64 exp); /// 2011.02.09 - prodongi void jpToString(__int64 jp, std::string& str); void convertMagicTypeToString(int type, std::string& str); /// 2011.03.07 왜 속성을 magic으로 쓰고들 있나?? - prodongi void getNpcIconAniName(std::string& str, unsigned int type = 0, unsigned int status = 0); /// 2011.03.18 npc의 아이콘 ani name을 얻어온다 - prodongi void getDungeonGateIconAniName(std::string& str, int type); /// 2011.07.21 - prodongi // 2012.02.03 - servantes : 백분율에 따라 게이지의 텍스처를 바꿔 준다 // int nPixelHeight : 텍스처가 4,5 .. 펙셀짜리로 여러가지가 있다. 이 중 선택한다, UI 툴 또는 UI 담당자에게 확인 bool setHPGaugeTexture(int percent, KUIControlGauge* pGauge, int nPixelHeight = 4); bool isLastBR(char const* str); /// 2011.04.22
이 str 맨 마지막 태그 안에 들어 있는지 체크 bool isFirstBR(char const* str);/// 2011.04.27
이 str 맨 처음 태그 안에 들어 있는지 체크 bool setSkillCardIcon(KUIControlMultiIcon* icon, int itemCode, bool isEquip = false); /// 2011.08.03 - prodongi // 2013. 03. 22 - gmpbigsun : 봉인카드에 대한 아이콘처리 bool setSummonCardIcon( KUIControlMultiIcon* pIcon, SInventorySlot const* pslot ); bool setSummonCardIcon( KUIControlMultiIcon* pIcon, int nItemCode, int nSummonID, int nEnhance, int nFlag, int nDurability = 0 ); bool setSummonCardIcon( KUIControlMultiIcon* pIcon, int nItemCode, int nSummonID, int nEnhance, XFlag tFlag, int nDurability = 0 ); bool setSummonCardIconForPortrait( KUIControlMultiIcon* pIcon, SInventorySlot const* pSlot ); //20130409 편성창 오른쪽 초상화 void ResetMultiIcon( KUIControlMultiIcon* pIcon, const int nBegin, const int nEnd ); bool isEmptyCreatureCard(int itemCode, XFlag const& xFlag); /// 2011.10.21 빈카드인지 - prodongi // Azia Mafia ++ bool isWearableSkillCardItem(const ItemBaseEx_info* pItem, SSkillSlotMgr& SkillSlotMgr); // // return cost // 0 : error // 1 : 내구도 있음 // 2 : 내구도 없음 int refreshItemDurability(SInventorySlot* pSlot, KUIWnd* pGauge, float fGaugeWidth); void UISendStringMessage(SGameManager* pGameManager, int nToUI, const char* pSendStr, bool bForceSend = false);