void Window::ShowDecorations() { Hide(); Rect clr = GetClientRect(); SetWindowLong( _window_handle, GWL_STYLE, WS_TILEDWINDOW); Rect dr = GetWindowRect() - GetClientRect(); Resize( clr.GetW() + dr.GetW(), clr.GetH() + dr.GetH() ); Show(); }
/** * Returns true if the given box is directly above the ground */ bool MovementMap::IsOnGround(const Rect box) { // Checks the lower limit if (!IsZero(box.Center().GetX(), box.GetY()+box.GetH()+1)) return true; // Checks the lower-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()+1)) return true; // Checks the lower-left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH()+1)) return true; return false; }
void WidgetTableWidget::RepaintImpl( const WidgetPainter &painter ) { //HubWidget::Repaint(painter); -- nonsense Rect client_area = GetParent()->GetClientRect(this)-GetPosition(); Rect influenced = GetCrossing( client_area ); Pos p( influenced.GetX1(), influenced.GetY1() ); for ( int j=0; j!=influenced.GetW(); ++j, ++p.x ) { SettlerMap::Iterator iter; _settlers.Find( p, (SettlerMap::ConstIterator*)&iter); for ( int i=0; i!=influenced.GetH(); ++i, ++iter ) { if (!iter) { break; }//< W/A GetCrossing() does not work corectly Widget &child = *iter->_settler; if ( child.IsVisible() ) { WidgetPainter child_painter( painter, child ); if ( child_painter.Intersect() ) { child.Repaint(child_painter); child_painter.RestoreClipper(); } } } } }
void TableListedItems::PaintClients( const WidgetPainter &painter ) { Pos p; Dim2i d( GetWidth(), 0); Rect client_area = GetParent()->GetClientRect(this)-GetPosition(); Rect visibile = TableWidget::GetCrossing( client_area ); p.y = RowRect( visibile.GetY1() ).GetY(); for ( int i=visibile.GetY1(); i<visibile.GetY2(); ++i ) { d.y = GetRowHeight(i); int last_col = GetNumColumns() -1; Rect fa = RowRect( i ); if ( _skins.Select( GetState(i) ) ) { _skins.SetSize( Dim2i(fa.GetW(),fa.GetH()) ); } _skins.Paint( painter, fa.GetPos(), fa ); p.y += d.y; } }
void MainState::Update() { // Moves the player in the specified direction if (m_PlayerDirState[kPlayerDirLeft]) { m_Player->TranslateBy(Vec2(-5.0, 0.0)); } else if (m_PlayerDirState[kPlayerDirRight]) { m_Player->TranslateBy(Vec2(5.0, 0.0)); } else if (m_PlayerDirState[kPlayerDirUp]) { m_Player->TranslateBy(Vec2(0.0, -5.0)); } else if (m_PlayerDirState[kPlayerDirDown]) { m_Player->TranslateBy(Vec2(0.0, 5.0)); } for (int i = 0; i < m_ProjectileArray.GetSize(); ++i) { Rect screenRect = m_EnginePtr->GetScene()->GetScreenRect(); Projectile* projectile = m_ProjectileArray[i]; Vec2 pos = projectile->GetWorldPosition(); if (pos.GetX() < screenRect.GetX() || pos.GetX() > (screenRect.GetX() + screenRect.GetW()) || pos.GetY() < screenRect.GetY() || pos.GetY() > (screenRect.GetY() + screenRect.GetH())) { LOG_PRINT("removed"); } } }
/** * Corrects the box position relative to a given tileBox * and the previous position of the box. */ void MovementMap::CorrectCollision(Rect& box, Rect tileBox) { if (!Collision::IsColliding(box, tileBox, 0, 0)) return; // If the previous position was to the left of the tile if (previousPos.GetX()+previousPos.GetW() <= tileBox.GetX()) box.MoveRect(tileBox.GetX() - (box.GetX()+box.GetW()), 0); // If the previous position was to the right of the tile else if (previousPos.GetX() >= tileBox.GetX()+tileBox.GetW()) box.MoveRect((tileBox.GetX()+tileBox.GetW()) - box.GetX(), 0); // If the previous position was below the tile else if (previousPos.GetY() > tileBox.GetY()) box.MoveRect(0, tileBox.GetY()+tileBox.GetH() - box.GetY()); // If the previous position was above the tile else box.MoveRect(0, tileBox.GetY()-(box.GetY()+box.GetH())); }
void Window::HideDecorations() { Hide(); Rect clr = GetClientRect(); SetWindowLong( _window_handle, GWL_STYLE, WS_POPUP); Resize( clr.GetW(), clr.GetH()); Show(); }
Rect TableWidget::RowRect( int row ) const { int last_col = GetNumColumns() -1; Rect R = CellRect( 0, row) | CellRect( last_col, row); Rect r = ClientRect( 0, row) | ClientRect( last_col, row); return Rect( R.GetX1(), r.GetY1(), R.GetW(), r.GetH() ); }
Rect TableWidget::ColumnRect( int column ) const { int last_row = GetNumRows() -1; Rect R = CellRect( column, 0) | CellRect( column, last_row); Rect r = ClientRect( column, 0) | ClientRect( column, last_row); return Rect( r.GetX1(), R.GetY1(), r.GetW(), R.GetH() ); }
Point<double> DDScreen::GetZoomFactors() const { DDSurface *p_back = DDrawWindow::GetDisplay().GetBackBuffer(); Rect client = Window::GetClientRect(); assert( p_back ); double factor_x = client.GetW()/ (double)p_back->GetWidth(); double factor_y = client.GetH()/ (double)p_back->GetHeight(); return Point<double>( factor_x, factor_y ); }
Vec2 CollisionDetector::AABBToAABB(const Rect& rect1, const Rect& rect2) { // Prevents false collision if either rects has no width and height if ((rect1.GetW() == 0 && rect1.GetH() == 0) || (rect2.GetW() == 0 && rect2.GetH() == 0)) { return Vec2(0.0, 0.0); } Vec2 min1(rect1.GetX(), rect1.GetY()); Vec2 max1(rect1.GetX() + rect1.GetW(), rect1.GetY() + rect1.GetH()); Vec2 min2(rect2.GetX(), rect2.GetY()); Vec2 max2(rect2.GetX() + rect2.GetW(), rect2.GetY() + rect2.GetH()); if ((max1.GetX() < min2.GetX()) || (max1.GetY() < min2.GetY())) { return Vec2(0.0, 0.0); } if ((max2.GetX() < min1.GetX()) || (max2.GetY() < min1.GetY())) { return Vec2(0.0, 0.0); } // Potential resolution offsets double negX = max1.GetX() - min2.GetX(); double posX = max2.GetX() - min1.GetX(); double negY = max1.GetY() - min2.GetY(); double posY = max2.GetY() - min1.GetY(); // Returns the component vector that needs the least offset to resolve the collision if (negX <= posX && negX <= negY && negX <= posY) { return Vec2(-negX, 0.0); } else if (posX <= negY && posX <= posY) { return Vec2(posX, 0.0); } else if (negY <= posY) { return Vec2(0.0, -negY); } else { return Vec2(0.0, posY); } return Vec2(0.0, 0.0); }
void ListedTextItems::PaintArea( const Painter &painter, const Rect &area, int stateID) { if ( _skins.Select(stateID) ) { int cur_w = _skins.GetWidth(); int cur_h = _skins.GetHeight(); _skins.SetSize( Dim2i( area.GetW(), area.GetH())); _skins.Paint( painter, area.GetPos()); _skins.SetSize( Dim2i( cur_w, cur_h)); } }
/** * Returns a vector of Rects corresponding to the tiles * that are colliding with the given box */ std::vector<Rect> MovementMap::GetCollidingTiles(const Rect& box) { std::vector<Rect> collidingTiles; // Check the upper point if (!IsZero(box.GetX()+box.GetW()/2, box.GetY())) collidingTiles.push_back(TileToRect(box.GetX(), box.GetY())); // Check the right point if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH()/2)) collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY())); // Check the left point if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2)) collidingTiles.push_back(TileToRect(box.GetX(), box.GetY()+box.GetH())); // Check the lower point if (!IsZero(box.GetX()+box.GetW()/2, box.GetY()+box.GetH())) collidingTiles.push_back(TileToRect(box.GetX()+box.GetW(), box.GetY()+box.GetH())); // for (int i = 0; i < collidingTiles.size(); i++) // { // std::cout << std::endl; // std::cout << "(" << collidingTiles[i].GetX() << "," << collidingTiles[i].GetY() << ")" << std::endl; // std::cout << "Width: " << collidingTiles[i].GetW() << " Height: " << collidingTiles[i].GetH() << std::endl; // } return collidingTiles; }
/** * This method uses the new position of the given object, * its previous position and the map to determine whether * the object is colliding with the walls */ bool MovementMap::IsColliding(const Rect box) { // // Checks the center // if (!IsZero(box.Center().GetX(), box.Center().GetY())) return true; // Checks the above limit if (!IsZero(box.GetX()+box.GetW()/2, box.GetY())) return true; // Checks the right limit if (!IsZero(box.GetX() + box.GetW(), box.GetY() + box.GetH()/2)) return true; // Checks the left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH()/2)) return true; // Checks the upper-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY())) return true; // Checks the upper-left limit if (!IsZero(box.GetX(), box.GetY())) return true; // Checks the lower limit if (!IsZero(box.Center().GetX(), box.Center().GetY() + box.GetH()/2)) return true; // Checks the lower-right limit if (!IsZero(box.GetX()+box.GetW(), box.GetY()+box.GetH())) return true; // Checks the lower-left limit if (!IsZero(box.GetX(), box.GetY()+box.GetH())) return true; return false; // return IsCollidingWithGround(box); }
void TableSkin::TableDice( const Rect &bound, int x1, int x2, int x3, int y1, int y2, int y3, bool no_interrior) { AssocVector<int ,Rect> assoc_rects; Pos p0;// = bound.GetPos(); int x[5] = { 0, x1, x2, x3, bound.GetW() }; int y[5] = { 0, y1, y2, y3, bound.GetH() }; assoc_rects.Insert( TOP+HEAD, CheckedRect( x[0], y[0], x[1]-x[0], y[1]-y[0]) +p0); assoc_rects.Insert( TOP+BODY, CheckedRect( x[1], y[0], x[2]-x[1], y[1]-y[0]) +p0); assoc_rects.Insert( TOP+TAIL, CheckedRect( x[3], y[0], x[4]-x[3], y[1]-y[0]) +p0); assoc_rects.Insert( MIDDLE+HEAD, CheckedRect( x[0], y[1], x[1]-x[0], y[2]-y[1]) +p0); if ( !no_interrior ) assoc_rects.Insert( MIDDLE+BODY, CheckedRect( x[1], y[1], x[2]-x[1], y[2]-y[1]) +p0); assoc_rects.Insert( MIDDLE+TAIL, CheckedRect( x[3], y[1], x[4]-x[3], y[2]-y[1]) +p0); assoc_rects.Insert( BOTTOM+HEAD, CheckedRect(x[0], y[3], x[1]-x[0], y[4]-y[3]) +p0); assoc_rects.Insert( BOTTOM+BODY, CheckedRect(x[1], y[3], x[2]-x[1], y[4]-y[3]) +p0); assoc_rects.Insert( BOTTOM+TAIL, CheckedRect(x[3], y[3], x[4]-x[3], y[4]-y[3]) +p0); assoc_rects.Insert( HEAD+HDIV , CheckedRect( x[0], y[2], x[1]-x[0], y[3]-y[2]) +p0); assoc_rects.Insert( BODY+HDIV , CheckedRect( x[1], y[2], x[2]-x[1], y[3]-y[2]) +p0); assoc_rects.Insert( TAIL+HDIV , CheckedRect( x[3], y[2], x[4]-x[3], y[3]-y[2]) +p0); assoc_rects.Insert( HEAD+VDIV , CheckedRect( x[2], y[0], x[3]-x[2], y[1]-y[0]) +p0); assoc_rects.Insert( BODY+VDIV , CheckedRect( x[2], y[1], x[3]-x[2], y[2]-y[1]) +p0); assoc_rects.Insert( TAIL+VDIV , CheckedRect( x[2], y[3], x[3]-x[2], y[4]-y[3]) +p0); assoc_rects.Insert( CROSSING , CheckedRect( x[2], y[2], x[3]-x[2], y[3]-y[2]) +p0); ImageDicer::Dice(assoc_rects); SetSize( Dim2i(bound.GetW(), bound.GetH()) ); }
/*! Place self inside parents-client area. * Proportions are rect.{x|y|w|h} / base.{x|y|x|y}. * If base.{x|y}==0 then position and size in {X|Y} direction will be preserved. */ void Widget::Place ( const Rect &rect, const Pos &base) { Rect client_area = GetParent()->GetClientRect( this); Rect my_rect = GetBoundingRect() + GetPosition(); double x = my_rect.GetX(); double y = my_rect.GetY(); double w = my_rect.GetW(); double h = my_rect.GetH(); if ( base.x > 0) { x = as_double( client_area.GetW() * rect.GetX() ) / as_double( base.x ); } if ( base.y > 0) { y = as_double( client_area.GetH() * rect.GetY() ) / as_double( base.y ); } if ( base.x > 0) { w = as_double( client_area.GetW() * rect.GetW() ) / as_double( base.x ); } if ( base.y > 0) { h = as_double( client_area.GetH() * rect.GetH() ) / as_double( base.y ); } SetPosition( client_area.GetPos() + Pos( std::floor(x), std::floor(y) )); Resize( std::ceil(w), std::ceil(h) ); }
// Fills parent client-area with self void Widget::Fill( const Rect& area, const Rect &padding ) { Rect cr = area; if (!cr) { assert( _parent && "Widget::Fill(): Impossibile due no parent"); cr = _parent->GetClientRect(this); } cr.x += padding.x; cr.y += padding.y; cr.w -= padding.w + padding.x; cr.h -= padding.h + padding.y; SetPosition( cr.GetPos() ); Resize( cr.GetW(), cr.GetH() ); }
// Methos allocates space for widget void Widget::SetBoundingRect( const Rect &r ) { Rect previous = _bound; _bound = r; bool anything_changed=false; if ( GetEnvironment() ) { _parent->SetDirty( previous | _bound ); } if ( _bound.GetX() != previous.GetX() || _bound.GetY() != previous.GetY() ) { OnReposition.Send_1( Pos( _bound.GetX(), _bound.GetY() )); anything_changed=true; } if ( _bound.GetW() != previous.GetW() || _bound.GetH() != previous.GetH() ) { OnResize.Send_2( _bound.GetW(), _bound.GetH() ); anything_changed=true; } if ( anything_changed ) NotifyAncestors(true); }
void TableSystemWidget::Fit() { int w = GetWidth(), h=GetHeight(); int sb_width = _sb_width; int sb_height = _sb_height; if (_p_verti_scrollbar && _p_verti_scrollbar->Atom().IsVisible() ) { _ResizePositive( _p_verti_scrollbar->AtomPtr(), sb_width, h-(_cs_height+sb_height) ); _p_verti_scrollbar->Atom().SetPosition ( Pos( w-sb_width, _cs_height) ); } if (_p_horiz_scrollbar && _p_horiz_scrollbar->Atom().IsVisible() ) { _ResizePositive( _p_horiz_scrollbar->AtomPtr(), w-sb_width, sb_height ); _p_horiz_scrollbar->Atom().SetPosition ( Pos( 0, h-sb_height ) ); } if (_p_table_frame) { int frame_w = w-sb_width; int frame_h = h-sb_height; _p_table_frame->Fill( Rect( 0, 0, frame_w, frame_h )); Rect c = _p_table_frame->GetClientRect( _p_caption_scroller ); _p_caption_scroller->Resize( c.GetW(), _cs_height ); _p_caption_scroller->SetPosition( c.GetPos() ); _ResizePositive( _p_table_scroller, c.GetW(), c.GetH()-_cs_height ); _p_table_scroller->SetPosition( c.GetPos() + Pos( 0, _cs_height) ); } else { if (_p_caption_scroller) { _p_caption_scroller->Resize( w-sb_width, _cs_height ); _p_caption_scroller->SetPosition( Pos(0,0) ); } if (_p_table_scroller) { _ResizePositive( _p_table_scroller, w-sb_width, h-(_cs_height+sb_height) ); _p_table_scroller->SetPosition ( Pos(0,_cs_height) ); } } if ( _p_top_gadget ) { _p_top_gadget->SetPosition( Pos( w-_p_top_gadget->GetWidth(), 0) ); HubWidget::BringOnTop( _p_top_gadget ); } if ( _p_bottom_gadget ) { if ( sb_width && sb_height ) { _p_bottom_gadget->SetPosition( Pos( w-sb_width, h-sb_height) ); if ( !_p_bottom_gadget->Atom().IsVisible() ) { _p_bottom_gadget->Atom().Show(); } } else if ( _p_bottom_gadget->Atom().IsVisible() ) { _p_bottom_gadget->Atom().Hide(); } } if ( _auto_cover ) { int pri_tbl_width = _pri_tbl_width; int pri_tbl_height= _pri_tbl_height; int table_w = pri_tbl_width; int table_h = pri_tbl_height; int client_w = _p_table_scroller->GetWidth(); int client_h = _p_table_scroller->GetHeight(); // try to cover all client area by table (if table is smaller than area) if ( client_w > table_w ) { _p_main_table->Atom().Resize( client_w, table_h ); } else if ( client_w < pri_tbl_width ) { _p_main_table->Atom().Resize( pri_tbl_width, table_h ); } table_w = _p_main_table->Atom().GetWidth(); if ( client_h > table_h ) { _p_main_table->Atom().Resize( table_w, client_h ); } else if ( client_h < pri_tbl_height ) { _p_main_table->Atom().Resize( table_w, pri_tbl_height ); } table_h = _p_main_table->Atom().GetHeight(); // right scrollbar dissappears only if top-gadget does not exist if ( !_p_top_gadget ) { // Check if full table would be visible if we hide both scrollbars bool would_fit_width = client_w + sb_width >= table_w; bool would_fit_height= client_h + sb_height >= table_h; if ( would_fit_width && would_fit_height ) { _p_main_table->Atom().Resize( client_w + sb_width, client_h + sb_height); _sb_width = _sb_height = 0; } } _pri_tbl_width = pri_tbl_width; _pri_tbl_height= pri_tbl_height; } // Make sure that scrollbar sizes have not been changed, and if so try again if ( _sb_width!=sb_width || _sb_height!=sb_height ) { Fit(); } }
Vec2 CollisionDetector::LineToAABB(const Vec2& linePt, const Vec2& lineDir, const Rect& rect) { // Prevents false collision if either rects has no width and height if (rect.GetW() == 0 && rect.GetH() == 0) { return Vec2(0.0, 0.0); } Vec2 linePt1 = linePt; Vec2 linePt2 = linePt + lineDir; Vec2 rectPtArray[] = { Vec2(rect.GetX(), rect.GetY()), Vec2(rect.GetX() + rect.GetW(), rect.GetY()), Vec2(rect.GetX() + rect.GetW(), rect.GetY() + rect.GetH()), Vec2(rect.GetX(), rect.GetY() + rect.GetH()) }; double currentDirMag = 1.0f; // Current direction vector magnitude // Test intersection for all four line segments of the rectangle for (int i = 0; i < 4; ++i) { // i is the index of the first point, j the second // set j to 0 if i equals 3 int j = (i < 3) ? (i + 1) : 0; Vec2 rectPt1 = rectPtArray[i]; Vec2 rectPt2 = rectPtArray[j]; double sNumer = ( (linePt1.GetY() - rectPt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ) - ( (linePt1.GetX() - rectPt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ); double sDenom = ( (linePt2.GetX() - linePt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ) - ( (linePt2.GetY() - linePt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ); double tNumer = ( (linePt1.GetY() - rectPt1.GetY()) * (linePt2.GetX() - linePt1.GetX()) ) - ( (linePt1.GetX() - rectPt1.GetX()) * (linePt2.GetY() - linePt1.GetY()) ); double tDenom = ( (linePt2.GetX() - linePt1.GetX()) * (rectPt2.GetY() - rectPt1.GetY()) ) - ( (linePt2.GetY() - linePt1.GetY()) * (rectPt2.GetX() - rectPt1.GetX()) ); double s = sNumer / sDenom; double t = tNumer / tDenom; // Lines intersect if s and t are in range [0,1] if ((s >= 0.0 && s <= 1.0) && (t >= 0.0 && t <= 1.0)) { currentDirMag = t < currentDirMag ? s : currentDirMag; } } if (currentDirMag == 1.0) { return Vec2(0.0, 0.0); } else { return Vec2(linePt + (lineDir * currentDirMag)); } }
void Font::ConvertToBitmapFont(Display* display, int numchar) { int textureW = size * sqrt(numchar); int textureH = size * sqrt(numchar); bitmapFont = SDL_CreateTexture(display->GetRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, textureW, textureH); if (bitmapFont == nullptr) { LOG_ERROR("Couldn't create texture for bitmap font creating! Error: " << SDL_GetError()); } if(SDL_SetTextureBlendMode(bitmapFont, SDL_BLENDMODE_BLEND) == -1) LOG_ERROR("Couldn't set blendmode for texture when creating bitmap font!"); if(SDL_SetRenderTarget(display->GetRenderer(), bitmapFont) == -1) LOG_ERROR("Couldn't set render target to texture when creating bitmap font!"); display->PushRenderColor(); display->SetRenderColor(255, 255, 255, 0); if(SDL_RenderClear(display->GetRenderer()) == -1) LOG_ERROR("Couldn't clear texture when creating bitmap font!"); display->PopRenderColor(); int x = 0; int y = 0; for (int i = 0; i < numchar; i++) { //If break line charater skip if (i == 10) { glyphPositions.push_back(Rect(0, 0, 0, 0)); continue; } SDL_Surface* surface = nullptr; surface = TTF_RenderGlyph_Blended(font, i, COLOR_WHITE.ToSDLColor()); if (surface == nullptr) { //Don't show error on the NULL character if (i != 0) { LOG_ERROR("Couldn't create glyph surface! Using letter " << (char)i); } glyphPositions.push_back(Rect(0, 0, 0, 0)); continue; } SDL_Texture* texture = nullptr; texture = SDL_CreateTextureFromSurface(display->GetRenderer(), surface); SDL_FreeSurface(surface); if (texture == nullptr) { LOG_ERROR("Couldn't create glyph texture! Using letter " << (char)i); glyphPositions.push_back(Rect(0, 0, 0, 0)); continue; } Rect pos; if (SDL_QueryTexture(texture, NULL, NULL, &pos.w, &pos.h) == -1) { LOG_ERROR("Couldn't query texture when creating bitmap font!"); break; } if (x + pos.GetW() > textureW) { x = 0; y++; } if (y * pos.h > textureH) { LOG_ERROR("Can't render anymore letters to the texture it's full! Font size: " << size); SDL_DestroyTexture(texture); break; } pos.x = x; pos.y = y * pos.h; height = pos.GetH(); glyphPositions.push_back(pos); x += pos.GetW(); //Don't render tab character if (i != 9) { if (SDL_RenderCopy(display->GetRenderer(), texture, NULL, pos.ToSDLRect()) == -1) LOG_ERROR("Couldn't draw on texture when creating bitmap font!"); } SDL_DestroyTexture(texture); } if(SDL_SetRenderTarget(display->GetRenderer(), NULL) == -1) LOG_ERROR("Couldn't set render target back to renderer when creating bitmap font!"); return; }