void Sprite_Impl::draw(Canvas &canvas, const Rectf &src, const Rectf &dest) { SpriteFrame &frame = frames[current_frame]; draw(canvas, Rectf(frame.position.left + src.left, frame.position.top + src.top, src.get_size()), dest.get_top_left(), Pointf(dest.get_width() / src.get_width(), dest.get_height() / src.get_height()) ); }
// LEFT means b1 is left of b2 CollisionData CollisionEngine::collide(const Rectf& b1, const Rectf& b2, const Vector2f& b1_v, const Vector2f& b2_v, float delta) { SweepResult result0 = simple_sweep_1d(b1.left, b1.get_width(), b1_v.x, b2.left, b2.get_width(), b2_v.x); SweepResult result1 = simple_sweep_1d(b1.top, b1.get_height(), b1_v.y, b2.top, b2.get_height(), b2_v.y); CollisionData result; result.delta = delta; if(result0.collision(delta) && result1.collision(delta)) { if(result0.always() && result1.always()) result.state = CollisionData::STUCK; else { if(result0.begin(delta)<result1.begin(delta)) { // x direction prior if(b1.left < b2.left) { result.state=CollisionData::COLLISION; result.direction=Vector2f(-1, 0); } else { result.state=CollisionData::COLLISION; result.direction=Vector2f(1, 0); } result.col_time=result0.t0; } else { // x direction prior if(b1.top < b2.top) { result.state=CollisionData::COLLISION; result.direction=Vector2f(0, -1); } else { result.state=CollisionData::COLLISION; result.direction=Vector2f(0, 1); } result.col_time=result1.t0; } } } return result; }
void EditorInputCenter::update_tile_selection() { Rectf select = tile_drag_rect(); auto tiles = Editor::current()->tileselect.tiles.get(); auto tilemap = dynamic_cast<TileMap*>(Editor::current()->layerselect.selected_tilemap); if ( !tilemap ) { return; } tiles->tiles.clear(); tiles->width = select.get_width() + 1; tiles->height = select.get_height() + 1; int w = tilemap->get_width(); int h = tilemap->get_height(); for (int y = select.p1.y; y <= select.p2.y; y++) { for (int x = select.p1.x; x <= select.p2.x; x++) { if ( x < 0 || y < 0 || x >= w || y >= h) { tiles->tiles.push_back(0); } else { tiles->tiles.push_back(tilemap->get_tile_id(x, y)); } } } }
void X11Window::process_window_resize(const Rect &new_rect) { Rect old_client_area = client_area; client_area = new_rect; if (site) { if (old_client_area.left != client_area.left || old_client_area.top != client_area.top) { (site->sig_window_moved)(); } if (old_client_area.get_width() != client_area.get_width() || old_client_area.get_height() != client_area.get_height()) { Rectf rectf = client_area; rectf.left /= pixel_ratio; rectf.top /= pixel_ratio; rectf.right /= pixel_ratio; rectf.bottom /= pixel_ratio; if (callback_on_resized) callback_on_resized(); // OpenGLWindowProvider::on_window_resized (site->sig_resize)(rectf.get_width(), rectf.get_height()); // TopLevelWindow_Impl::on_resize if (site->func_window_resize) (site->func_window_resize)(rectf); } } }
void D3DGraphicContextProvider::set_viewport(int index, const Rectf &viewport) { if (index >= 0 && index < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) { viewports[index].TopLeftX = viewport.left; viewports[index].TopLeftY = viewport.top; viewports[index].Width = viewport.get_width(); viewports[index].Height = viewport.get_height(); window->get_device_context()->RSSetViewports(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, viewports); } }
void D3DGraphicContextProvider::set_viewport(const Rectf &viewport) { for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { viewports[i].TopLeftX = viewport.left; viewports[i].TopLeftY = viewport.top; viewports[i].Width = viewport.get_width(); viewports[i].Height = viewport.get_height(); } window->get_device_context()->RSSetViewports(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, viewports); }
void GameTerrain::render_sprite(Canvas &canvas, const LightModel &light_model, Rectf dest) { canvas.push_modelview(); canvas.mult_scale(4.0f, 1.0f, 4.0f); canvas.mult_modelview(Mat4f::translate(-size.width/2.0f, 0.0f, -size.height/2.0f)); gc.set_culled(true); gc.set_front_face(cl_face_side_counter_clockwise); PrimitivesArray prim_array(gc); prim_array.set_attributes(0, vertex_buffer, 3, cl_type_float, (int) &static_cast<Vertex*>(0)->position, sizeof(Vertex)); prim_array.set_attributes(1, vertex_buffer, 3, cl_type_float, (int) &static_cast<Vertex*>(0)->normal, sizeof(Vertex)); gc.set_texture(0, texture_base); gc.set_texture(1, texture_areas); gc.set_texture(2, texture_colors); gc.set_texture(3, texture_borders); gc.set_program_object(shader_program); Material material; // material.shininess = 25.0f; shader_program.set_uniform4f("area", Vec4f(dest.left, dest.top, dest.get_width(), dest.get_height())); shader_program.set_uniform1i("texture_base", 0); shader_program.set_uniform1i("texture_areas", 1); shader_program.set_uniform1i("texture_colors", 2); shader_program.set_uniform1i("texture_borders", 3); /* shader_program.set_uniform("lightSourcePosition", light_model.light_sources[0].position); shader_program.set_uniform("frontLightProductAmbient", light_model.get_light_ambient(material, light_model.light_sources[0])); shader_program.set_uniform("frontLightProductDiffuse", light_model.get_light_diffuse(material, light_model.light_sources[0])); shader_program.set_uniform("frontLightProductSpecular", light_model.get_light_specular(material, light_model.light_sources[0])); shader_program.set_uniform("frontMaterialShininess", material.shininess); shader_program.set_uniform("frontLightModelProductSceneColor", light_model.get_scene_color(material)); */ gc.draw_primitives(type_triangles, num_vertices, prim_array); gc.reset_program_object(); gc.reset_texture(0); gc.reset_texture(1); gc.reset_texture(2); gc.reset_texture(3); gc.reset_polygon_rasterizer(); canvas.pop_modelview(); }
void EditorInputCenter::draw_rectangle() { Rectf dr = drag_rect(); dr.p1 = sp_to_tp(dr.p1); dr.p2 = sp_to_tp(dr.p2); bool sgn_x = drag_start.x < sector_pos.x; bool sgn_y = drag_start.y < sector_pos.y; int x_, y_; x_ = sgn_x ? 0 : -dr.get_width(); for (int x = dr.p1.x; x <= dr.p2.x; x++, x_++) { y_ = sgn_y ? 0 : -dr.get_height(); for (int y = dr.p1.y; y <= dr.p2.y; y++, y_++) { input_tile( Vector(x, y), Editor::current()->tileselect.tiles->pos(x_, y_) ); } } }
void EditorToolboxWidget::update_selection() { Rectf select = normalize_selection(); m_tiles->m_tiles.clear(); m_tiles->m_width = static_cast<int>(select.get_width() + 1); m_tiles->m_height = static_cast<int>(select.get_height() + 1); int size = static_cast<int>(m_active_tilegroup->tiles.size()); for (int y = static_cast<int>(select.get_top()); y <= static_cast<int>(select.get_bottom()); y++) { for (int x = static_cast<int>(select.get_left()); x <= static_cast<int>(select.get_right()); x++) { int tile_pos = y*4 + x + m_starting_tile; if (tile_pos < size && tile_pos >= 0) { m_tiles->m_tiles.push_back(m_active_tilegroup->tiles[tile_pos]); } else { m_tiles->m_tiles.push_back(0); } } } }
void DrawingContext::draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer) { DrawingRequest* request = new(obst) DrawingRequest(); request->target = target; request->type = FILLRECT; request->pos = transform.apply(rect.p1); request->layer = layer; request->drawing_effect = transform.drawing_effect; request->alpha = transform.alpha; FillRectRequest* fillrectrequest = new(obst) FillRectRequest; fillrectrequest->size = Vector(rect.get_width(), rect.get_height()); fillrectrequest->color = color; fillrectrequest->color.alpha = color.alpha * transform.alpha; fillrectrequest->radius = radius; request->request_data = fillrectrequest; requests->push_back(request); }
ViewGeometry PositionedLayout::get_geometry(Canvas &canvas, View *view, const Rectf &containing_box) { float x = 0.0f; float width = 0.0f; if (!view->style_cascade().computed_value("left").is_keyword("auto") && !view->style_cascade().computed_value("right").is_keyword("auto")) { x = view->style_cascade().computed_value("left").number(); width = clan::max(containing_box.get_width() - view->style_cascade().computed_value("right").number() - x, 0.0f); } else if (!view->style_cascade().computed_value("left").is_keyword("auto") && !view->style_cascade().computed_value("width").is_keyword("auto")) { x = view->style_cascade().computed_value("left").number(); width = view->style_cascade().computed_value("width").number(); } else if (!view->style_cascade().computed_value("right").is_keyword("auto") && !view->style_cascade().computed_value("width").is_keyword("auto")) { width = view->style_cascade().computed_value("width").number(); x = containing_box.get_width() - view->style_cascade().computed_value("right").number() - width; } else if (!view->style_cascade().computed_value("left").is_keyword("auto")) { x = view->style_cascade().computed_value("left").number(); width = view->get_preferred_width(canvas); } else if (!view->style_cascade().computed_value("right").is_keyword("auto")) { width = view->get_preferred_width(canvas); x = containing_box.get_width() - view->style_cascade().computed_value("right").number() - width; } else { x = 0.0f; width = view->get_preferred_width(canvas); } float y = 0.0f; float height = 0.0f; if (!view->style_cascade().computed_value("top").is_keyword("auto") && !view->style_cascade().computed_value("bottom").is_keyword("auto")) { y = view->style_cascade().computed_value("top").number(); height = clan::max(containing_box.get_height() - view->style_cascade().computed_value("bottom").number() - y, 0.0f); } else if (!view->style_cascade().computed_value("top").is_keyword("auto") && !view->style_cascade().computed_value("height").is_keyword("auto")) { y = view->style_cascade().computed_value("top").number(); height = view->style_cascade().computed_value("height").number(); } else if (!view->style_cascade().computed_value("bottom").is_keyword("auto") && !view->style_cascade().computed_value("height").is_keyword("auto")) { height = view->style_cascade().computed_value("height").number(); y = containing_box.get_height() - view->style_cascade().computed_value("bottom").number() - height; } else if (!view->style_cascade().computed_value("top").is_keyword("auto")) { y = view->style_cascade().computed_value("top").number(); height = view->get_preferred_height(canvas, width); } else if (!view->style_cascade().computed_value("bottom").is_keyword("auto")) { height = view->get_preferred_height(canvas, width); y = containing_box.get_height() - view->style_cascade().computed_value("bottom").number() - height; } else { y = 0.0f; height = view->get_preferred_height(canvas, width); } return ViewGeometry::from_content_box(view->style_cascade(), Rectf::xywh(x, y, width, height)); }
void Sprite_Impl::draw(Canvas &canvas, const Rectf &dest) { SpriteFrame &frame = frames[current_frame]; draw(canvas, frame.position, dest.get_top_left(), Pointf(dest.get_width()/float(frame.position.get_width()), dest.get_height()/float(frame.position.get_height()))); }
ViewGeometry PositionedLayout::get_geometry(Canvas &canvas, View *view, const Rectf &containing_box) { bool definite_left = !view->style_cascade().computed_value("left").is_keyword("auto"); bool definite_right = !view->style_cascade().computed_value("right").is_keyword("auto"); bool definite_width = !view->style_cascade().computed_value("width").is_keyword("auto"); float computed_left = resolve_percentage(view->style_cascade().computed_value("left"), containing_box.get_width()); float computed_right = resolve_percentage(view->style_cascade().computed_value("right"), containing_box.get_width()); float computed_width = resolve_percentage(view->style_cascade().computed_value("width"), containing_box.get_width()); float x = 0.0f; float width = 0.0f; if (definite_left && definite_right) { x = computed_left; width = clan::max(containing_box.get_width() - computed_right - x, 0.0f); } else if (definite_left && definite_width) { x = computed_left; width = computed_width; } else if (definite_right && definite_width) { width = computed_width; x = containing_box.get_width() - computed_right - width; } else if (definite_left) { x = computed_left; width = view->preferred_width(canvas); // Note: in HTML there's an additional implicit "max-width: calc(100%-left)" rule active here. // We are not emulating this "feature" as it is most likely a bug that got standardized for backwards compatibility. // The user should add an max-width rule themselves if they want such an odd constraint active. } else if (definite_right) { width = view->preferred_width(canvas); x = containing_box.get_width() - computed_right - width; } else if (definite_width) { x = 0.0f; width = view->style_cascade().computed_value("width").number(); } else { x = 0.0f; width = view->preferred_width(canvas); } bool definite_top = !view->style_cascade().computed_value("top").is_keyword("auto"); bool definite_bottom = !view->style_cascade().computed_value("bottom").is_keyword("auto"); bool definite_height = !view->style_cascade().computed_value("height").is_keyword("auto"); float computed_top = resolve_percentage(view->style_cascade().computed_value("top"), containing_box.get_height()); float computed_bottom = resolve_percentage(view->style_cascade().computed_value("bottom"), containing_box.get_height()); float computed_height = resolve_percentage(view->style_cascade().computed_value("height"), containing_box.get_height()); float y = 0.0f; float height = 0.0f; if (definite_top && definite_bottom) { y = computed_top; height = clan::max(containing_box.get_height() - computed_bottom - y, 0.0f); } else if (definite_top && definite_height) { y = computed_top; height = computed_height; } else if (definite_bottom && definite_height) { height = computed_height; y = containing_box.get_height() - computed_bottom - height; } else if (definite_top) { y = computed_top; height = view->preferred_height(canvas, width); } else if (definite_bottom) { height = view->preferred_height(canvas, width); y = containing_box.get_height() - computed_bottom - height; } else if (definite_height) { y = 0.0f; height = computed_height; } else { y = 0.0f; height = view->preferred_height(canvas, width); } x += containing_box.left; y += containing_box.top; auto tl = canvas.grid_fit(Pointf(x, y)); auto br = canvas.grid_fit(Pointf(x + width, y + height)); Rectf box = Rectf(tl.x, tl.y, br.x, br.y); return ViewGeometry::from_content_box(view->style_cascade(), box); }
// Danger: This function could delete "this" void X11Window::process_message(XEvent &event, X11Window *mouse_capture_window) { switch(event.type) { case ConfigureNotify: { // Resize or Move Rect new_client_area = (event.xany.send_event == 0) ? get_screen_position() : Rect::xywh( event.xconfigure.x + event.xconfigure.border_width, event.xconfigure.y + event.xconfigure.border_width, event.xconfigure.width, event.xconfigure.height ); process_window_resize(new_client_area); break; } case ClientMessage: { // handle window manager messages Atom WM_PROTOCOLS = atoms["WM_PROTOCOLS"]; if (WM_PROTOCOLS == None) { log_event("debug", "clan::X11Window::process_message: WM_PROTOCOLS not supported by WM."); break; } else if (event.xclient.message_type == WM_PROTOCOLS) { unsigned long protocol = event.xclient.data.l[0]; if (protocol == None) { log_event("debug", "clan::X11Window::process_message: WM_PROTOCOLS event protocol supplied is None."); break; } Atom WM_DELETE_WINDOW = atoms["WM_DELETE_WINDOW"]; Atom _NET_WM_PING = atoms["_NET_WM_PING"]; if (protocol == WM_DELETE_WINDOW && site) { (site->sig_window_close)(); } else if (protocol == _NET_WM_PING) { XSendEvent(handle.display, RootWindow(handle.display, handle.screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } } break; } case Expose: { // Window exposure repaint_request = true; break; } case FocusIn: if (site) (site->sig_got_focus)(); break; case FocusOut: if (site) { if (!has_focus()) // For an unknown reason, FocusOut is called when clicking on title bar of window { (site->sig_lost_focus)(); } } break; case PropertyNotify: { // Iconify, Maximized, ... if (!site) break; Atom _NET_WM_STATE = atoms["_NET_WM_STATE"]; Atom WM_STATE = atoms["WM_STATE"]; // legacy. if (_NET_WM_STATE != None && event.xproperty.atom == _NET_WM_STATE && event.xproperty.state == PropertyNewValue) { if (is_minimized()) { if (!minimized && site != nullptr) (site->sig_window_minimized)(); minimized = true; maximized = false; } else if (is_maximized()) { if (!maximized && site != nullptr) (site->sig_window_maximized)(); if (minimized && site != nullptr) { // generate resize events for minimized -> maximized transition Rectf rectf = get_geometry(); rectf.left /= pixel_ratio; rectf.top /= pixel_ratio; rectf.right /= pixel_ratio; rectf.bottom /= pixel_ratio; (site->sig_window_moved)(); if (site->func_window_resize) (site->func_window_resize)(rectf); if (callback_on_resized) callback_on_resized(); (site->sig_resize)(rectf.get_width(), rectf.get_height()); } minimized = false; maximized = true; } else { if ((minimized || maximized) && site != nullptr) (site->sig_window_restored)(); minimized = false; maximized = false; } } else if (WM_STATE != None && event.xproperty.atom == WM_STATE && event.xproperty.state == PropertyNewValue) { if (is_minimized()) { if (!minimized && site != nullptr) (site->sig_window_minimized)(); minimized = true; } else { if (minimized && site != nullptr) (site->sig_window_restored)(); minimized = false; } } break; } case KeyRelease: case KeyPress: if (get_keyboard_provider()) { get_keyboard_provider()->received_keyboard_input(keyboard, event.xkey); } break; case ButtonPress: case ButtonRelease: if (mouse_capture_window->get_mouse_provider() && event.xany.send_event==0) { if (callback_on_clicked) { // This callback is required for GL layered windows if (!callback_on_clicked(event.xbutton)) break; } if (this != mouse_capture_window) // This is so you can capture mouse events in another window, as if it was this window (Set by capture_mouse()) { Rect this_scr = client_area; Rect capture_scr = mouse_capture_window->client_area; event.xbutton.x += this_scr.left - capture_scr.left; event.xbutton.y += this_scr.top - capture_scr.top; } mouse_capture_window->get_mouse_provider()->received_mouse_input(mouse_capture_window->mouse, event.xbutton); } break; case MotionNotify: if (mouse_capture_window->get_mouse_provider() && event.xany.send_event == 0) { if (this != mouse_capture_window) // This is so you can capture mouse events in another window, as if it was this window (Set by capture_mouse()) { Rect this_scr = client_area; Rect capture_scr = mouse_capture_window->client_area; event.xmotion.x += this_scr.left - capture_scr.left; event.xmotion.y += this_scr.top - capture_scr.top; } mouse_capture_window->get_mouse_provider()->received_mouse_move(mouse_capture_window->mouse, event.xmotion); } break; case SelectionClear: // New clipboard selection owner clipboard.event_selection_clear(event.xselectionclear); break; case SelectionNotify: clipboard.event_selection_notify(); break; case SelectionRequest: // Clipboard requests clipboard.event_selection_request(event.xselectionrequest); break; default: break; } }