void editor_map::sanity_check() { int errors = 0; if (total_width() != static_cast<int>(tiles_.size())) { ERR_ED << "total_width is " << total_width() << " but tiles_.size() is " << tiles_.size() << "\n"; ++errors; } if (total_height() != static_cast<int>(tiles_[0].size())) { ERR_ED << "total_height is " << total_height() << " but tiles_[0].size() is " << tiles_.size() << "\n"; ++errors; } if (w() + 2 * border_size() != total_width()) { ERR_ED << "h is " << h_ << " and border_size is " << border_size() << " but total_width is " << total_width() << "\n"; ++errors; } if (h() + 2 * border_size() != total_height()) { ERR_ED << "w is " << w_ << " and border_size is " << border_size() << " but total_height is " << total_height() << "\n"; ++errors; } for (size_t i = 1; i < tiles_.size(); ++i) { if (tiles_[i].size() != tiles_[0].size()) { ERR_ED << "tiles_[ " << i << "] has size() " << tiles_[i].size() << " but tiles[0] has size() " << tiles_[0].size() << "\n"; ++errors; } } BOOST_FOREACH(const map_location& loc, selection_) { if (!on_board_with_border(loc)) { ERR_ED << "Off-map tile in selection: " << loc << "\n"; } } if (errors) { throw editor_map_integrity_error(); } }
gamemap editor_map::mask_to(const gamemap& target) const { if (target.w() != w() || target.h() != h()) { throw editor_action_exception(_("The size of the target map is different from the current map")); } gamemap mask(target); map_location iter; for (iter.x = -border_size(); iter.x < w() + border_size(); ++iter.x) { for (iter.y = -border_size(); iter.y < h() + border_size(); ++iter.y) { if (target.get_terrain(iter) == get_terrain(iter)) { mask.set_terrain(iter, t_translation::FOGGED); } } } return mask; }
void gamemap::read(const std::string& data, const bool allow_invalid) { tiles_ = t_translation::ter_map(); villages_.clear(); starting_positions_.clear(); if(data.empty()) { w_ = 0; h_ = 0; if(allow_invalid) return; } int offset = read_header(data); const std::string& data_only = std::string(data, offset); try { tiles_ = t_translation::read_game_map(data_only, starting_positions_, t_translation::coordinate{ border_size(), border_size() }); } catch(const t_translation::error& e) { // We re-throw the error but as map error. // Since all codepaths test for this, it's the least work. throw incorrect_map_format_error(e.message); } // Post processing on the map w_ = total_width() - 2 * border_size(); h_ = total_height() - 2 * border_size(); //Disabled since there are callcases which pass along a valid map header but empty //map data. Still, loading (and actually applying) an empty map causes problems later on. //Other callcases which need to load a dummy map use completely empty data :(. //VALIDATE((w_ >= 1 && h_ >= 1), "A map needs at least 1 tile, the map cannot be loaded."); for(int x = 0; x < total_width(); ++x) { for(int y = 0; y < total_height(); ++y) { // Is the terrain valid? t_translation::terrain_code t = tiles_.get(x, y); if(tdata_->map().count(t) == 0) { if(!tdata_->try_merge_terrains(t)) { std::stringstream ss; ss << "Unknown tile in map: (" << t_translation::write_terrain_code(t) << ") '" << t << "'"; throw incorrect_map_format_error(ss.str().c_str()); } } // Is it a village? if(x >= border_size() && y >= border_size() && x < total_width()- border_size() && y < total_height()- border_size() && tdata_->is_village(tiles_.get(x, y))) { villages_.push_back(map_location(x - border_size(), y - border_size())); } } } }
std::vector<map_location> gamemap::parse_location_range(const std::string &x, const std::string &y, bool with_border) const { std::vector<map_location> res; const std::vector<std::string> xvals = utils::split(x); const std::vector<std::string> yvals = utils::split(y); int xmin = 1, xmax = w(), ymin = 1, ymax = h(); if (with_border) { int bs = border_size(); xmin -= bs; xmax += bs; ymin -= bs; ymax += bs; } for (unsigned i = 0; i < xvals.size() || i < yvals.size(); ++i) { std::pair<int,int> xrange, yrange; if (i < xvals.size()) { xrange = utils::parse_range(xvals[i]); if (xrange.first < xmin) xrange.first = xmin; if (xrange.second > xmax) xrange.second = xmax; } else { xrange.first = xmin; xrange.second = xmax; } if (i < yvals.size()) { yrange = utils::parse_range(yvals[i]); if (yrange.first < ymin) yrange.first = ymin; if (yrange.second > ymax) yrange.second = ymax; } else { yrange.first = ymin; yrange.second = ymax; } for(int x = xrange.first; x <= xrange.second; ++x) { for(int y = yrange.first; y <= yrange.second; ++y) { res.push_back(map_location(x-1,y-1)); } } } return res; }
void gamemap::overlay(const gamemap& m, const config& rules_cfg, int xpos, int ypos, bool border) { const config::const_child_itors &rules = rules_cfg.child_range("rule"); int actual_border = (m.border_size() == border_size()) && border ? border_size() : 0; const int xstart = std::max<int>(-actual_border, -xpos - actual_border); const int ystart = std::max<int>(-actual_border, -ypos - actual_border - ((xpos & 1) ? 1 : 0)); const int xend = std::min<int>(m.w() + actual_border, w() + actual_border - xpos); const int yend = std::min<int>(m.h() + actual_border, h() + actual_border - ypos); for(int x1 = xstart; x1 < xend; ++x1) { for(int y1 = ystart; y1 < yend; ++y1) { const int x2 = x1 + xpos; const int y2 = y1 + ypos + ((xpos & 1) && (x1 & 1) ? 1 : 0); const t_translation::t_terrain t = m[x1][y1 + m.border_size_]; const t_translation::t_terrain current = (*this)[x2][y2 + border_size_]; if(t == t_translation::FOGGED || t == t_translation::VOID_TERRAIN) { continue; } // See if there is a matching rule config::const_child_iterator rule = rules.first; for( ; rule != rules.second; ++rule) { static const std::string src_key = "old", dst_key = "new"; const config &cfg = *rule; const t_translation::t_list& src = t_translation::read_list(cfg[src_key]); if(!src.empty() && t_translation::terrain_matches(current, src) == false) { continue; } const t_translation::t_list& dst = t_translation::read_list(cfg[dst_key]); if(!dst.empty() && t_translation::terrain_matches(t, dst) == false) { continue; } break; } if (rule != rules.second) { const config &cfg = *rule; const t_translation::t_list& terrain = t_translation::read_list(cfg["terrain"]); terrain_type_data::tmerge_mode mode = terrain_type_data::BOTH; if (cfg["layer"] == "base") { mode = terrain_type_data::BASE; } else if (cfg["layer"] == "overlay") { mode = terrain_type_data::OVERLAY; } t_translation::t_terrain new_terrain = t; if(!terrain.empty()) { new_terrain = terrain[0]; } if (!cfg["use_old"].to_bool()) { set_terrain(map_location(x2, y2), new_terrain, mode, cfg["replace_if_failed"].to_bool()); } } else { set_terrain(map_location(x2,y2),t); } } } for(const map_location* pos = m.startingPositions_; pos != m.startingPositions_ + sizeof(m.startingPositions_)/sizeof(*m.startingPositions_); ++pos) { if(pos->valid()) { startingPositions_[pos - m.startingPositions_] = *pos; } } }
void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) { if (IsShown()) return; onShow(); // find selection selected_item = selection(); // width size_t count = itemCount(); if (item_size.width == 100) { // not initialized wxClientDC dc(this); dc.SetFont(*wxNORMAL_FONT); for (size_t i = 0 ; i < count ; ++i) { int text_width; dc.GetTextExtent(capitalize(itemText(i)), &text_width, 0); item_size.width = max(item_size.width, text_width + icon_size.width + 14); // 14 = room for popup arrow + padding } } // height int line_count = 0; for (size_t i = 0 ; i < count ; ++i) if (lineBelow(i)) line_count += 1; // size RealSize border_size(2,2); // GetClientSize() - GetSize(), assume 1px borders RealSize size( item_size.width + marginW * 2, item_size.height * count + marginH * 2 + line_count ); // placement int parent_height = 0; if (!in_place && viewer) { // Position the drop down list below the editor control (based on the style) Rotation rot = viewer->viewer.getRotation(); Rotater rr(rot, viewer->getRotation()); RealRect r = rot.trRectToBB(rect ? *rect : rot.getInternalRect()); if (viewer->viewer.nativeLook()) { pos = RealPoint(r.x - 3, r.y - 3); size.width = max(size.width, r.width + 6); parent_height = (int)r.height + 6; } else { pos = RealPoint(r.x - 1, r.y - 1); parent_height = (int)r.height; } } else if (parent_menu) { parent_height = -(int)item_size.height - 1; } pos = GetParent()->ClientToScreen(pos); // virtual size = item size RealSize virtual_size = size; SetVirtualSize(virtual_size); item_size.width = virtual_size.width - marginW * 2; // is there enough room for all items, or do we need a scrollbar? int room_below = wxGetDisplaySize().y - border_size.height - pos.y - parent_height - 50; int max_height = max(300, room_below); if (size.height > max_height) { size.height = max_height; size.width += wxSystemSettings::GetMetric(wxSYS_VSCROLL_ARROW_X); // width of scrollbar SetScrollbar(wxVERTICAL, 0, size.height, virtual_size.height, false); } else { SetScrollbar(wxVERTICAL,0,0,0,false); } // move & resize SetSize(add_diagonal(size, border_size)); Position(pos, wxSize(0, parent_height)); // visible item visible_start = 0; ensureSelectedItemVisible(); // set event handler if (hider) { assert(hider2); wxGetTopLevelParent(GetParent())->PushEventHandler(hider); GetParent() ->PushEventHandler(hider2); } // show if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default mouse_down = false; close_on_mouse_out = false; wxPopupWindow::Show(); if (isRoot() && GetParent()->HasCapture()) { // release capture on parent GetParent()->ReleaseMouse(); } // fix drop down arrow redrawArrowOnParent(); }
Rect get_window_frame_size() { #ifdef WIN32 RECT border_rect; border_rect.left = 200; border_rect.right = 200 + 200; border_rect.top = 200; border_rect.bottom = 200 + 200; AdjustWindowRectEx(&border_rect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX, FALSE, 0); Rect border_size(border_rect.left - 200, border_rect.top - 200, border_rect.right - 400, border_rect.bottom - 400); #else Display *d; Window w; d=XOpenDisplay(NULL); if(d==NULL) { throw Exception("Cannot open display"); } int s=DefaultScreen(d); const int win_xpos = 128; const int win_ypos = 128; const int win_width = 128; const int win_height = 128; w=XCreateSimpleWindow(d, RootWindow(d, s), win_xpos, win_ypos, win_width, win_height, 0, BlackPixel(d, s), WhitePixel(d, s)); XSelectInput(d, w, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PropertyChangeMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | KeymapStateMask | FocusChangeMask); // setup size hints: XSizeHints size_hints; memset(&size_hints, 0, sizeof(XSizeHints)); size_hints.x = win_xpos; size_hints.y = win_ypos; size_hints.width = win_width; size_hints.height = win_height; size_hints.base_width = win_width; size_hints.base_height = win_height; size_hints.min_width = size_hints.width; size_hints.min_height = size_hints.height; size_hints.max_width = size_hints.width; size_hints.max_height = size_hints.height; size_hints.flags = PSize|PBaseSize; size_hints.flags |= PMinSize | PMaxSize | PPosition; // These flags are important XSetWMNormalHints(d, w, &size_hints); XMapWindow(d, w); // Wait for mapped XEvent event; do { XMaskEvent(d, StructureNotifyMask, &event); }while ( (event.type != MapNotify) || (event.xmap.event != w) ); int xpos; int ypos; unsigned int width; unsigned int height; Window *children_ptr; unsigned int num_child; Window temp_window; XWindowAttributes attr; XGetWindowAttributes(d, w, &attr); xpos = attr.x; ypos = attr.y; width = attr.width; height = attr.height; // Search all parent windows .... there MUST be an easier may Window current_window = w; while(true) { children_ptr = NULL; XQueryTree(d, current_window, &temp_window, ¤t_window, &children_ptr, &num_child); if (children_ptr) XFree(children_ptr); if (!current_window) break; XGetWindowAttributes(d, current_window, &attr); xpos += attr.x; ypos += attr.y; } XDestroyWindow(d, w); XCloseDisplay(d); xpos -= win_xpos; ypos -= win_ypos; Rect border_size = Rect(-xpos, -ypos, 0, 0); #endif return border_size; }
bool gamemap::on_board_with_border(const map_location& loc) const { return !tiles_.data.empty() && // tiles_ is not empty when initialized. loc.x >= -border_size() && loc.x < w_ + border_size() && loc.y >= -border_size() && loc.y < h_ + border_size(); }
std::string gamemap::write() const { return t_translation::write_game_map(tiles_, starting_positions_, t_translation::coordinate{ border_size(), border_size() }) + "\n"; }
int MapStatistics::num_interior_vertex() { return num_vertex() - border_size() ; }
/*-+-+-* Logger *-+-+-*/ void MapStatistics::show(bool mesh, bool geom, bool error, bool param) { if(mesh) { Logger::out("Components") << num_components() << std::endl ; Logger::out("Mesh stats") << num_vertex() << " vertices, " << num_facet() << " facets, " << border_size() << "/" << num_edge() << " border edges." << sock_factor() << " sock factor." << std::endl ; } if(geom) { bounding_box() ; Logger::out("Vertex bounding box") << "[" << bbox_[0] << "," << bbox_[1] << "]x[" << bbox_[2] << "," << bbox_[3] << "]x[" << bbox_[4] << "," << bbox_[5] << "]" << std::endl ; gravity_center() ; Logger::out("Gravity center") << "(" << G_.x() << ", " << G_.y() << ", " << G_.z() << ")" << std::endl ; Logger::out("Surface area") << "area2D = " << total_area_2D() << " area3D = " << total_area_3D() << std::endl ; Logger::out("Facet area 3D") << min_facet_area_3D() << " min. " << average_facet_area_3D() << " av. " << max_facet_area_3D() << " max." << std::endl ; if(is_parameterized()) { Logger::out("Facet area 2D") << min_facet_area_2D() << " min. " << average_facet_area_2D() << " av. " << max_facet_area_2D() << " max." << std::endl ; } Logger::out("Mesh length") << "Total length 2D = " << total_length_2D() << " Total length3D = " << total_length_3D() << std::endl ; if(is_parameterized_) { Logger::out("Edge length 2D") << min_edge_length_2D() << " min. " << average_edge_length_2D() << " av. " << max_edge_length_2D() << " max." << std::endl ; } Logger::out("Edge length 3D") << min_edge_length_3D() << " min. " << average_edge_length_3D() << " av. " << max_edge_length_3D() << " max." << std::endl ; if(border_size() > 0) { Logger::out("Border count") << "Total length2D " << border_length2D() << " Total length3D " << border_length3D() << std::endl ; } else Logger::out("Border count") << "Surface is closed." << std::endl ; } if(error) { Logger::out("Errors") << num_null_edge_3D() << " null 3D edges, " << num_null_edge_2D() << " null 2D edges. " << num_flat_facet_3D() << " flat 3D facets, " << num_flat_facet_2D() << " flat 2D facets." << std::endl ; } if(param && is_parameterized()) { Logger::out("Atlas stats") << "Surfacic deformation: " << average_area_deformation() << "% av. " << max_area_deformation() << "% max." << std::endl ; Logger::out("Atlas stats") << "Error on Jacobian: " << jacobian_error() << "%." << std::endl ; Logger::out("Atlas stats") << "Angular deformation: " << average_angle_deformation() << "% av. " << max_angle_deformation() << "% max." << std::endl ; Logger::out("Atlas stats") << "Length deformation: " << average_length_deformation() << "% av. " << max_length_deformation() << "% max." << std::endl ; } else Logger::out("Atlas Stats") << "Surface is not parameterized." << std::endl ; }