Rev 2107 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
964 | jag | 1 | /* |
2 | * countries.cc |
||
2302 | jag | 3 | * DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath |
1713 | jag | 4 | * DIN Is Noise is released under GNU Public License 2.0 |
1479 | jag | 5 | * For more information, please visit https://dinisnoise.org/ |
964 | jag | 6 | */ |
7 | |||
8 | |||
9 | #include "countries.h" |
||
10 | #include "vector2d.h" |
||
1579 | jag | 11 | #include "console.h" |
12 | #include "log.h" |
||
964 | jag | 13 | #include <vector> |
14 | #include <fstream> |
||
15 | #include <algorithm> |
||
16 | using namespace std; |
||
17 | |||
18 | |||
19 | extern string user_data_dir; |
||
20 | extern string country_data_dir; |
||
21 | |||
22 | extern console cons; |
||
23 | |||
24 | bool area::operator< (const area& rhs) const { |
||
25 | return num_vertices > rhs.num_vertices; |
||
26 | } |
||
27 | |||
28 | countries::countries () { |
||
29 | name = "Countries"; |
||
30 | id = -1; |
||
31 | p_cur_country = 0; |
||
32 | area_id = 0; |
||
33 | change_curve_name = 1; |
||
34 | } |
||
35 | |||
36 | countries::~countries () { |
||
37 | widget_save ("d_countries", ctrls); |
||
38 | save_params (); |
||
39 | } |
||
40 | |||
41 | void countries::load_params () { |
||
42 | ifstream f (make_fname().c_str(), ios::in); |
||
43 | string ignore; |
||
44 | float step; |
||
45 | f >> ignore >> id >> ignore >> area_id >> ignore >> step; |
||
1579 | jag | 46 | pt.step.set_value (step); |
964 | jag | 47 | load_country (index[id]); |
48 | } |
||
49 | |||
50 | void countries::save_params () { |
||
51 | ofstream f (make_fname().c_str(), ios::out); |
||
52 | if (f) { |
||
53 | f << "id " << id << endl; |
||
54 | f << "area_id " << area_id << endl; |
||
2107 | jag | 55 | f << "step " << int(pt.step.value) << endl; |
964 | jag | 56 | } |
57 | } |
||
58 | |||
59 | void countries::load_index () { |
||
60 | string fname (country_data_dir + "index"); |
||
61 | ifstream f (fname.c_str(), ios::in); |
||
62 | if (!f) { |
||
63 | dlog << "couldnt read from : " << fname << endl; |
||
64 | return; |
||
65 | } |
||
66 | f >> num_countries; |
||
1579 | jag | 67 | index.resize (num_countries); |
964 | jag | 68 | for (int i = 0; i < num_countries; ++i) { |
69 | f >> fname; |
||
1579 | jag | 70 | index[i] = fname; |
964 | jag | 71 | } |
72 | sort (index.begin (), index.end()); |
||
73 | } |
||
74 | |||
75 | |||
76 | void countries::setup () { |
||
77 | |||
78 | plugin::setup (); |
||
79 | |||
80 | load_index (); |
||
81 | |||
1579 | jag | 82 | widget* _ctrls [] = {&ol_country, &ol_area, &lf_search, &pt.step, &pt.start, &pt.end, &close}; |
83 | for (int i = 0; i < 7; ++i) { |
||
84 | ctrls.push_back (_ctrls[i]); |
||
85 | } |
||
964 | jag | 86 | |
87 | num_ctrls = ctrls.size (); |
||
88 | |||
1579 | jag | 89 | //for (int i = 0; i < num_ctrls; ++i) ctrls[i]->set_moveable(1); |
90 | |||
1120 | jag | 91 | lf_search.set_text ("Country?"); |
964 | jag | 92 | lf_search.set_listener (this); |
1521 | jag | 93 | lf_search.fld.expr = 0; |
94 | |||
964 | jag | 95 | ol_country.set_text ("Country = "); |
96 | ol_country.set_listener (this); |
||
97 | ol_country.set_click_repeat (1); |
||
1521 | jag | 98 | |
964 | jag | 99 | ol_area.set_listener (this); |
100 | ol_area.set_click_repeat (1); |
||
101 | ol_area.set_text ("Area = "); |
||
102 | |||
1579 | jag | 103 | pt.start.set ("Start", 1, 1, MILLION, this, 0); |
104 | pt.end.set ("End", 1, 1, MILLION, this, 0); |
||
105 | pt.step.set ("Step", 1, 1, MILLION, this, 0); |
||
964 | jag | 106 | |
1579 | jag | 107 | close.set_text ("Close"); |
108 | close.set_listener (&cll); |
||
109 | |||
964 | jag | 110 | widget_load ("d_countries", ctrls); |
111 | |||
112 | load_params (); |
||
113 | lf_search.fld.set_text (index[id]); |
||
114 | |||
115 | } |
||
116 | |||
117 | void countries::render () { |
||
118 | if (p_cur_country) { |
||
119 | points.clear (); |
||
120 | area& a0 = p_cur_country->areas[area_id]; |
||
2107 | jag | 121 | int start = pt.start.value; |
1579 | jag | 122 | float a0x = a0.x[start], a0y = a0.y[start]; |
964 | jag | 123 | point<float> pa0 (a0x, a0y); |
124 | points.push_back (pa0); |
||
2107 | jag | 125 | for (int i = start + 1, j = pt.end.value, di = pt.step.value; i < j; i += di) points.push_back (point<float>(a0.x[i], a0.y[i])); |
1579 | jag | 126 | if (close.state || (points.size () == 1)) points.push_back (pa0); |
127 | gen_pts (); |
||
964 | jag | 128 | ss.str(""); |
129 | ss << p_cur_country->name; |
||
130 | } |
||
131 | } |
||
132 | |||
133 | country* countries::load_country (const string& which) { |
||
134 | country& c = the_countries [which]; |
||
135 | if (c.num_areas == 0) { |
||
136 | string fname (country_data_dir + which); |
||
137 | ifstream f (fname.c_str(), ios::in); |
||
138 | if (!f) { |
||
139 | dlog << "couldnt load from : " << fname << endl; |
||
140 | return 0; |
||
141 | } |
||
142 | c.name = which; |
||
143 | string ignore; |
||
144 | while (!f.eof()) { |
||
145 | f >> ignore >> c.num_areas; |
||
146 | for (int i = 0; i < c.num_areas; ++i) { |
||
147 | c.areas.push_back (area()); |
||
148 | area& ai = c.areas[i]; |
||
149 | f >> ignore >> ai.num_vertices; |
||
150 | float l, b, r, t; f >> ignore >> l >> b >> r >> t; |
||
151 | ai.bbox (l, b, r, t); |
||
1579 | jag | 152 | |
1582 | jag | 153 | /*dlog << "name = " << c.name << " ratio = " << ai.bbox.width * 1.0 / ai.bbox.height << endl; |
154 | float fac = ai.bbox.width * 1.0 / ai.bbox.height - 1.0;*/ |
||
155 | |||
1579 | jag | 156 | int& q = ai.num_vertices; |
157 | int n1 = q + 1; |
||
158 | ai.x.resize (n1); |
||
159 | ai.y.resize (n1); |
||
160 | for (int p = 0; p < q; ++p) f >> ai.x[p] >> ai.y[p]; |
||
161 | ai.x[q] = ai.x[0]; |
||
162 | ai.y[q] = ai.y[0]; |
||
163 | ++q; |
||
964 | jag | 164 | } |
165 | } |
||
166 | } |
||
167 | p_cur_country = &c; |
||
168 | set_country (which); |
||
169 | return &c; |
||
170 | } |
||
171 | |||
172 | void countries::picked (label& lbl, int dir) { |
||
173 | if (&lbl == &ol_country.option) { |
||
174 | id += dir; |
||
175 | if (id < 0) id = num_countries - 1; else if (id >= num_countries) id = 0; |
||
176 | string name (index[id]); |
||
177 | load_country (name); |
||
178 | } else if (&lbl == &ol_area.option) { |
||
179 | if (p_cur_country) { |
||
180 | area_id += dir; |
||
181 | render_area (); |
||
182 | } |
||
183 | } |
||
184 | } |
||
185 | |||
186 | void countries::changed (field& f) { |
||
187 | if (&f == &lf_search.fld) { |
||
188 | string name (f.text); |
||
1579 | jag | 189 | for (int i = 0, j = name.size (); i < j; ++i) if (name[i] == ' ') name[i]= '_'; |
964 | jag | 190 | int nid = find_id (name); |
191 | if (nid == -1) { |
||
1579 | jag | 192 | cons << RED << "Couldnt find " << name << eol; |
964 | jag | 193 | if (name == "") f.set_text (index[id]); |
194 | } else { |
||
195 | id = nid; |
||
196 | load_country (name); |
||
197 | } |
||
198 | } else { |
||
199 | render (); |
||
200 | if (cb_auto_apply.state) clicked (b_apply); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | void countries::render_area () { |
||
205 | if (area_id < 0) area_id = p_cur_country->num_areas - 1; else if (area_id >= p_cur_country->num_areas) area_id = 0; |
||
206 | stringstream ss; ss << "Area " << (area_id+1) << " of " << p_cur_country->num_areas; |
||
207 | ol_area.set_text (ss.str()); |
||
1579 | jag | 208 | |
209 | int n_1 = p_cur_country->areas[area_id].num_vertices - 1; |
||
210 | pt.start.set_limits (0, n_1); |
||
211 | pt.end.set_limits (0, n_1); |
||
212 | pt.start.set_value (0); |
||
213 | pt.end.set_value (n_1); |
||
214 | |||
964 | jag | 215 | render (); |
216 | if (cb_auto_apply.state) clicked (b_apply); |
||
217 | } |
||
218 | |||
219 | void countries::set_country (const string& name) { |
||
220 | ol_country.set_text (name); |
||
221 | lf_search.set_text (name); |
||
222 | area_id = 0; |
||
223 | render_area (); |
||
224 | } |
||
225 | |||
226 | int countries::find_id (const string& name) { |
||
1579 | jag | 227 | for (int i = 0, j = index.size (); i < j; ++i) if (index[i] == name) return i; |
964 | jag | 228 | return -1; |
229 | } |
||
230 | |||
1579 | jag | 231 | void countries::closer::changed (checkbutton& cb) { |
232 | extern countries countries_; |
||
233 | countries_.do_render (); |
||
234 | } |
||
235 | |||
964 | jag | 236 | void area::calc_bbox () { |
237 | if (num_vertices) { |
||
1579 | jag | 238 | float xmin = x[0], ymin = y[0]; |
239 | float xmax = xmin, ymax = ymin; |
||
964 | jag | 240 | for (int i = 1, j = num_vertices; i < j; ++i) { |
241 | float xi = x[i], yi = y[i]; |
||
242 | if (xi < xmin) xmin = xi; else if (xi > xmax) xmax = xi; |
||
243 | if (yi < ymin) ymin = yi; else if (yi > ymax) ymax = yi; |
||
244 | } |
||
245 | bbox (xmin, ymin, xmax, ymax); |
||
246 | } |
||
247 | } |
||
248 | |||
249 | void area::normalise () { |
||
250 | float aspect_ratio = bbox.width * 1. / bbox.height; |
||
251 | float xw = aspect_ratio * 2.0f, xwh = xw / 2.0f; |
||
252 | for (int i = 0, j = num_vertices; i < j; ++i) { |
||
253 | float xi = x[i], yi = y[i]; |
||
254 | float fx = (xi - bbox.left) * bbox.width_1; |
||
255 | float fy = (yi - bbox.bottom) * bbox.height_1; |
||
256 | float xj = -xwh + fx * xw; |
||
257 | float yj = -1 + fy * 2.0f; |
||
258 | x[i] = xj; |
||
259 | y[i] = yj; |
||
260 | } |
||
261 | bbox (-xwh, -1.0f, xwh, 1.0f); |
||
262 | } |