📄 region.cpp
字号:
for(children_list_t::iterator it2=cl.begin();it2!=cl.end();it2++) (*it2)->clear_cache(); } m_children_cs.leave(); // XXXX note that this does *not* propagate the change to the // renderers yet: if they cache information they will have to // invalidate it on the next redraw.}lib::rect surface_impl::get_fit_rect_noalign(const lib::size& src_size, lib::rect* out_src_rect) const{ const_cast<surface_impl*>(this)->need_bounds(); const int image_width = src_size.w; const int image_height = src_size.h; const int region_width = m_inner_bounds.width(); const int region_height = m_inner_bounds.height(); const int min_width = std::min(image_width, region_width); const int min_height = std::min(image_height, region_height); const double scale_width = (double)region_width / std::max((double)image_width, 0.1); const double scale_height = (double)region_height / std::max((double)image_height, 0.1); double scale; fit_t fit = (m_info == NULL?fit_default : m_info->get_fit()); // This is a bit of a hack: if no fit value is specified we pick it up // from our parent. This is needed for subregions (nodes). if (fit == fit_default && m_parent && m_parent->m_info) fit = m_parent->m_info->get_fit(); switch (fit) { case fit_fill: // Fill the area with the image, ignore aspect ration *out_src_rect = lib::rect(lib::point(0, 0), src_size); return m_inner_bounds; case fit_scroll: case fit_default: case fit_hidden: // Don't scale at all *out_src_rect = lib::rect(lib::point(0, 0), lib::size(min_width, min_height)); return rect(lib::point(0, 0), lib::size(min_width, min_height)); case fit_meet: // Scale to make smallest edge fit (showing some background color) scale = std::min(scale_width, scale_height); break; case fit_meetbest: // Scale to make smallest edge fit (showing some background color), // but never scale up scale = std::min(scale_width, scale_height); if (scale > 1.0) scale = 1.0; break; case fit_slice: // Scale to make largest edge fit (not showing the full source image) scale = std::max(scale_width, scale_height); break; } // We end up here as common case for meet and slice int proposed_width = std::min((int)(scale*(image_width+0.5)), region_width); int proposed_height = std::min((int)(scale*(image_height+0.5)), region_height); *out_src_rect = lib::rect(lib::point(0, 0), lib::size((int)(proposed_width/scale), (int)(proposed_height/scale))); return rect(lib::point(0, 0), lib::size(proposed_width, proposed_height));}lib::rect surface_impl::get_fit_rect(const lib::size& src_size, lib::rect* out_src_rect, const common::alignment *align) const{ if (align == NULL) return get_fit_rect_noalign(src_size, out_src_rect); const_cast<surface_impl*>(this)->need_bounds(); const int image_width = src_size.w; const int image_height = src_size.h; const int region_width = m_inner_bounds.width(); const int region_height = m_inner_bounds.height(); lib::size region_size = lib::size(region_width, region_height); lib::point xy_image = align->get_image_fixpoint(src_size); lib::point xy_region = align->get_surface_fixpoint(region_size); const int x_image_left = xy_image.x; const int x_image_right = image_width - xy_image.x; const int y_image_top = xy_image.y; const int y_image_bottom = image_height - xy_image.y; const int x_region_left = xy_region.x; const int x_region_right = region_width - xy_region.x; const int y_region_top = xy_region.y; const int y_region_bottom = region_height - xy_region.y; AM_DBG lib::logger::get_logger()->debug("get_fit_rect: image size=(%d, %d)", image_width, image_height); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: region size=(%d, %d)", region_width, region_height); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: image fixpoint=(%d, %d)", xy_image.x, xy_image.y); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: region fixpoint=(%d, %d)", xy_region.x, xy_region.y); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: image delta fixpoint to ltrb=(%d, %d, %d, %d)", x_image_left, y_image_top, x_image_right, y_image_bottom); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: region delta fixpoint to ltrb=(%d, %d, %d, %d)", x_region_left, y_region_top, x_region_right, y_region_bottom); double scale_min_horizontal, scale_max_horizontal, scale_min_vertical, scale_max_vertical; if (x_image_left == 0) { scale_min_horizontal = scale_max_horizontal = (double)x_region_right / (double)x_image_right; } else { scale_min_horizontal = scale_max_horizontal = (double)x_region_left / (double)x_image_left; if (x_image_right != 0) { double scale_right = (double)x_region_right / (double)x_image_right; if (scale_min_horizontal == 0) scale_min_horizontal = scale_right; else scale_min_horizontal = std::min(scale_min_horizontal, scale_right); scale_max_horizontal = std::max(scale_max_horizontal, scale_right); } } if (y_image_top == 0) { scale_min_vertical = scale_max_vertical = (double)y_region_bottom / (double)y_image_bottom; } else { scale_min_vertical = scale_max_vertical = (double)y_region_top / (double)y_image_top; if (y_image_bottom != 0) { double scale_bottom = (double)y_region_bottom / (double)y_image_bottom; if (scale_min_vertical == 0) scale_min_vertical = scale_bottom; else scale_min_vertical = std::min(scale_min_vertical, scale_bottom); scale_max_vertical = std::max(scale_max_vertical, scale_bottom); } } double scale_horizontal, scale_vertical; fit_t fit = (m_info == NULL?fit_default : m_info->get_fit()); // This is a bit of a hack: if no fit value is specified we pick it up // from our parent. This is needed for subregions (nodes). if (fit == fit_default && m_parent && m_parent->m_info) fit = m_parent->m_info->get_fit(); switch (fit) { case fit_fill: // Fill the area with the image, ignore aspect ration // XXX I don't think this is correct. Or is it? scale_horizontal = scale_min_horizontal; scale_vertical = scale_min_vertical; break; case fit_scroll: // XXXX incorrect case fit_default: case fit_hidden: scale_horizontal = scale_vertical = 1.0; break; case fit_meet: // Scale to make smallest edge fit (showing some background color) scale_horizontal = scale_vertical = std::min(scale_min_horizontal, scale_min_vertical); break; case fit_meetbest: // Scale to make smallest edge fit (showing some background color) scale_vertical = std::min(scale_min_horizontal, scale_min_vertical); if (scale_vertical > 1.0) scale_vertical = 1.0; scale_horizontal = scale_vertical; break; case fit_slice: // Scale to make largest edge fit (not showing the full source image) scale_horizontal = scale_vertical = std::max(scale_max_horizontal, scale_max_vertical); break; } AM_DBG lib::logger::get_logger()->debug("get_fit_rect: scale_hor=%f, scale_vert=%f", scale_horizontal, scale_vertical); if (scale_horizontal == 0 || scale_vertical == 0) { *out_src_rect = lib::rect(point(0,0), size(0,0)); return lib::rect(point(0,0), size(0,0)); } // Convert the image fixpoint to scaled coordinates int x_image_scaled = (int)((xy_image.x * scale_horizontal) + 0.5); int y_image_scaled = (int)((xy_image.y * scale_vertical) + 0.5); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: scaled image fixpoint=(%d, %d)", x_image_scaled, y_image_scaled); // Find out where image (0, 0) would end up, and similarly for other // corners. At this point we still allow negative values or values > max int x_region_for_image_left = xy_region.x - x_image_scaled; int x_region_for_image_right = x_region_for_image_left + (int)((image_width * scale_horizontal) + 0.5); int y_region_for_image_top = xy_region.y - y_image_scaled; int y_region_for_image_bottom = y_region_for_image_top + (int)((image_height * scale_vertical) + 0.5); int x_image_for_region_left = 0; int x_image_for_region_right = image_width; int y_image_for_region_top = 0; int y_image_for_region_bottom = image_height; AM_DBG lib::logger::get_logger()->debug("get_fit_rect: full image would have region lrtb=(%d, %d, %d, %d)", x_region_for_image_left, y_region_for_image_top, x_region_for_image_right, y_region_for_image_bottom); // Finally clamp all values if (x_region_for_image_left < 0) { x_image_for_region_left = (int)((-x_region_for_image_left / scale_horizontal) + 0.5); x_region_for_image_left = 0; } if (x_region_for_image_right > region_width) { // XXXX Or +1? int overshoot = x_region_for_image_right - region_width; x_region_for_image_right = region_width; x_image_for_region_right = x_image_for_region_right - (int)((overshoot / scale_horizontal) + 0.5); } if (y_region_for_image_top < 0) { y_image_for_region_top = (int)((-y_region_for_image_top / scale_vertical) + 0.5); y_region_for_image_top = 0; } if (y_region_for_image_bottom > region_height) { int overshoot = y_region_for_image_bottom - region_height; y_region_for_image_bottom = region_height; y_image_for_region_bottom = y_image_for_region_bottom - (int)((overshoot / scale_vertical) + 0.5); } AM_DBG lib::logger::get_logger()->debug("get_fit_rect: image selection ltrb=(%d, %d, %d, %d)", x_image_for_region_left, y_image_for_region_top, x_image_for_region_right, y_image_for_region_bottom); AM_DBG lib::logger::get_logger()->debug("get_fit_rect: region selection lrtb=(%d, %d, %d, %d)", x_region_for_image_left, y_region_for_image_top, x_region_for_image_right, y_region_for_image_bottom); *out_src_rect = lib::rect( point(x_image_for_region_left, y_image_for_region_top), size(x_image_for_region_right-x_image_for_region_left, y_image_for_region_bottom-y_image_for_region_top)); return lib::rect( point(x_region_for_image_left, y_region_for_image_top), size(x_region_for_image_right-x_region_for_image_left, y_region_for_image_bottom-y_region_for_image_top));}boolsurface_impl::is_tiled() const{ common::tiling t = m_info->get_tiling(); return (t == common::tiling_horizontal || t == common::tiling_vertical || t == common::tiling_both || t == common::tiling_default);}tile_positionssurface_impl::get_tiles(lib::size image_size, lib::rect surface_rect) const{ assert(is_tiled()); tile_positions rv; int x, y; int width = image_size.w; int height = image_size.h; int max_x = surface_rect.left()+width; int max_y = surface_rect.top()+height; common::tiling t = m_info->get_tiling(); if (t == common::tiling_horizontal || t == common::tiling_both || t == common::tiling_default) max_x = surface_rect.right(); if (t == common::tiling_vertical || t == common::tiling_both || t == common::tiling_default) max_y = surface_rect.bottom(); for (x=surface_rect.left(); x < max_x; x += width) { for (y=surface_rect.top(); y < max_y; y += height) { int w = std::min<int>(width, max_x-x); int h = std::min<int>(height, max_y-y); rect srcrect(point(0, 0), size(w, h)); rect dstrect(point(x, y), size(w, h)); rv.push_back(common::tile_position(srcrect, dstrect)); } } return rv;}void surface_impl::transition_done(lib::rect area){ if (!m_parent) return; // Audio region or some such area &= m_inner_bounds; m_parent->transition_done(m_outer_bounds.outercoordinates(area));}void surface_impl::transition_freeze_end(lib::rect r){ AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s, ltrb=(%d, %d, %d, %d))", (void *)this, m_name.c_str(), r.left(), r.top(), r.right(), r.bottom()); r &= m_outer_bounds; r = m_outer_bounds.innercoordinates(r); if (r.empty()) { AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s) returning: no overlap", (void *)this, m_name.c_str()); return; } // Signal the active renderers // For the win32 arrangement we should have at most one active m_children_cs.enter(); assert(m_renderers.size()<=1); std::list<gui_events*>::iterator ar; for (ar=m_renderers.begin(); ar!=m_renderers.end(); ar++) { AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s) ->renderer 0x%x", (void *)this, m_name.c_str(), (void *)(*ar)); (*ar)->transition_freeze_end(r); } // Finally the children regions of this for(children_map_t::iterator it2=m_active_children.begin();it2!=m_active_children.end();it2++) { AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s) examining next z-order list", (void*)this, m_name.c_str()); children_list_t& cl = (*it2).second; for(children_list_t::iterator it3=cl.begin();it3!=cl.end();it3++) { AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s) -> child 0x%x", (void *)this, m_name.c_str(), (void *)(*it3)); (*it3)->transition_freeze_end(r); } } AM_DBG lib::logger::get_logger()->debug("surface_impl.transition_freeze_end(0x%x %s) returning", (void*)this, m_name.c_str()); m_children_cs.leave();}void surface_impl::add_subregion(zindex_t z, surface_impl *rgn){ m_children_cs.enter(); m_subregions[z].push_back(rgn); m_children_cs.leave();}void surface_impl::del_subregion(zindex_t z, surface_impl *rgn){ m_children_cs.enter(); m_subregions[z].remove(rgn); m_children_cs.leave();}renderer_private_data*surface_impl::get_renderer_private_data(renderer_private_id idd) { if (m_info && m_info->is_subregion()) { assert(m_parent); return m_parent->get_renderer_private_data(idd); } if (idd == m_renderer_id) return m_renderer_data; return NULL;}void surface_impl::set_renderer_private_data(renderer_private_id idd, renderer_private_data* data) { if (m_info && m_info->is_subregion()) { assert(m_parent); m_parent->set_renderer_private_data(idd, data); } // Release the old data if (m_renderer_data) m_renderer_data->release(); m_renderer_data = data; m_renderer_data->add_ref(); m_renderer_id = idd;}voidsurface_impl::highlight(bool onoff){ m_highlighting = onoff; need_redraw(m_inner_bounds);} // toplevel_surface_impltoplevel_surface_impl::toplevel_surface_impl(const region_info *info, lib::size bounds, bgrenderer *bgrenderer, window_factory *wf): surface_impl(info?info->get_name():"topLayout", NULL, rect(point(0, 0), bounds), info, bgrenderer){ m_gui_window = wf->new_window(m_name, bounds, this); AM_DBG lib::logger::get_logger()->debug("toplevel_surface_impl(0x%x, \"%s\"): window=0x%x", (void *)this, m_name.c_str(), (void *)m_gui_window);} toplevel_surface_impl::~toplevel_surface_impl(){ AM_DBG lib::logger::get_logger()->debug("~toplevel_surface_impl(0x%x)", (void*)this); if (m_gui_window) delete m_gui_window; m_gui_window = NULL;}voidtoplevel_surface_impl::need_redraw(const lib::rect &r){ if (m_gui_window) m_gui_window->need_redraw(r); else { lib::logger::get_logger()->debug("toplevel_surface_impl::need_redraw: m_gui_window == NULL"); lib::logger::get_logger()->warn(gettext("Programmer error encountered, will attempt to continue")); }}voidtoplevel_surface_impl::need_events(bool want){ if (m_gui_window) m_gui_window->need_events(want); else { lib::logger::get_logger()->trace("toplevel_surface_impl::need_events: m_gui_window == NULL"); lib::logger::get_logger()->warn(gettext("Programmer error encountered, will attempt to continue")); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -