* Decide which cargo was clicked at in a #CFT_CARGO field. * @param left Left industry neighbour if available (else \c nullptr should be supplied). * @param right Right industry neighbour if available (else \c nullptr should be supplied). * @param pt Click position in the cargo field. * @return Cargo clicked at, or #INVALID_CARGO if none. */
| 2280 | * @return Cargo clicked at, or #INVALID_CARGO if none. |
| 2281 | */ |
| 2282 | CargoType CargoClickedAt(const CargoesField *left, const CargoesField *right, Point pt) const |
| 2283 | { |
| 2284 | assert(this->type == CFT_CARGO); |
| 2285 | |
| 2286 | /* Vertical matching. */ |
| 2287 | int cpos = this->GetCargoBase(0); |
| 2288 | uint col; |
| 2289 | for (col = 0; col < this->u.cargo.num_cargoes; col++) { |
| 2290 | if (pt.x < cpos) break; |
| 2291 | if (pt.x < cpos + static_cast<int>(CargoesField::cargo_line.width)) return this->u.cargo.vertical_cargoes[col]; |
| 2292 | cpos += CargoesField::cargo_line.width + CargoesField::cargo_space.width; |
| 2293 | } |
| 2294 | /* col = 0 -> left of first col, 1 -> left of 2nd col, ... this->u.cargo.num_cargoes right of last-col. */ |
| 2295 | |
| 2296 | int vpos = (vert_inter_industry_space / 2) + CargoesField::cargo_border.height + (GetCharacterHeight(FS_NORMAL) - CargoesField::cargo_line.height) / 2; |
| 2297 | uint row; |
| 2298 | for (row = 0; row < MAX_CARGOES; row++) { |
| 2299 | if (pt.y < vpos) return INVALID_CARGO; |
| 2300 | if (pt.y < vpos + static_cast<int>(CargoesField::cargo_line.height)) break; |
| 2301 | vpos += GetCharacterHeight(FS_NORMAL) + CargoesField::cargo_space.height; |
| 2302 | } |
| 2303 | if (row == MAX_CARGOES) return INVALID_CARGO; |
| 2304 | |
| 2305 | /* row = 0 -> at first horizontal row, row = 1 -> second horizontal row, 2 = 3rd horizontal row. */ |
| 2306 | if (col == 0) { |
| 2307 | if (HasBit(this->u.cargo.supp_cargoes, row)) return this->u.cargo.vertical_cargoes[row]; |
| 2308 | if (left != nullptr) { |
| 2309 | if (left->type == CFT_INDUSTRY) return left->u.industry.other_produced[row]; |
| 2310 | if (left->type == CFT_CARGO_LABEL && !left->u.cargo_label.left_align) return left->u.cargo_label.cargoes[row]; |
| 2311 | } |
| 2312 | return INVALID_CARGO; |
| 2313 | } |
| 2314 | if (col == this->u.cargo.num_cargoes) { |
| 2315 | if (HasBit(this->u.cargo.cust_cargoes, row)) return this->u.cargo.vertical_cargoes[row]; |
| 2316 | if (right != nullptr) { |
| 2317 | if (right->type == CFT_INDUSTRY) return right->u.industry.other_accepted[row]; |
| 2318 | if (right->type == CFT_CARGO_LABEL && right->u.cargo_label.left_align) return right->u.cargo_label.cargoes[row]; |
| 2319 | } |
| 2320 | return INVALID_CARGO; |
| 2321 | } |
| 2322 | if (row >= col) { |
| 2323 | /* Clicked somewhere in-between vertical cargo connection. |
| 2324 | * Since the horizontal connection is made in the same order as the vertical list, the above condition |
| 2325 | * ensures we are left-below the main diagonal, thus at the supplying side. |
| 2326 | */ |
| 2327 | if (HasBit(this->u.cargo.supp_cargoes, row)) return this->u.cargo.vertical_cargoes[row]; |
| 2328 | return INVALID_CARGO; |
| 2329 | } |
| 2330 | /* Clicked at a customer connection. */ |
| 2331 | if (HasBit(this->u.cargo.cust_cargoes, row)) return this->u.cargo.vertical_cargoes[row]; |
| 2332 | return INVALID_CARGO; |
| 2333 | } |
| 2334 | |
| 2335 | /** |
| 2336 | * Decide what cargo the user clicked in the cargo label field. |
no test coverage detected