00001 #include "clip.h"
00002 #include "edl.h"
00003 #include "edlsession.h"
00004 #include "mwindow.h"
00005 #include "mwindowgui.h"
00006 #include "theme.h"
00007 #include "trackcanvas.h"
00008 #include "units.h"
00009 #include "vframe.h"
00010 #include "zoompanel.h"
00011
00012
00013 ZoomHash::ZoomHash(double value, char *text)
00014 {
00015 this->value = value;
00016 this->text = new char[strlen(text) + 1];
00017 strcpy(this->text, text);
00018 }
00019
00020 ZoomHash::~ZoomHash()
00021 {
00022 delete [] text;
00023 }
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 ZoomPanel::ZoomPanel(MWindow *mwindow,
00042 BC_WindowBase *subwindow,
00043 double value,
00044 int x,
00045 int y,
00046 int w,
00047 double min,
00048 double max,
00049 int zoom_type)
00050 {
00051 this->mwindow = mwindow;
00052 this->subwindow = subwindow;
00053 this->x = x;
00054 this->y = y;
00055 this->w = w;
00056 this->value = value;
00057 this->min = min;
00058 this->max = max;
00059 this->zoom_type = zoom_type;
00060 this->menu_images = 0;
00061 this->tumbler_images = 0;
00062 this->user_table = 0;
00063 this->user_size = 0;
00064 }
00065
00066 ZoomPanel::ZoomPanel(MWindow *mwindow,
00067 BC_WindowBase *subwindow,
00068 double value,
00069 int x,
00070 int y,
00071 int w,
00072 double *user_table,
00073 int user_size,
00074 int zoom_type)
00075 {
00076 this->mwindow = mwindow;
00077 this->subwindow = subwindow;
00078 this->x = x;
00079 this->y = y;
00080 this->w = w;
00081 this->value = value;
00082 this->min = min;
00083 this->max = max;
00084 this->zoom_type = zoom_type;
00085 this->menu_images = 0;
00086 this->tumbler_images = 0;
00087 this->user_table = user_table;
00088 this->user_size = user_size;
00089 }
00090
00091 ZoomPanel::~ZoomPanel()
00092 {
00093 delete zoom_text;
00094 delete zoom_tumbler;
00095 zoom_table.remove_all_objects();
00096 }
00097
00098 void ZoomPanel::calculate_menu()
00099 {
00100 if(user_size)
00101 {
00102 for(int i = 0; i < user_size; i++)
00103 {
00104 zoom_text->add_item(new BC_MenuItem(value_to_text(user_table[i], 0)));
00105 zoom_table.append(new ZoomHash(user_table[i], value_to_text(user_table[i], 0)));
00106 }
00107 }
00108 else
00109 {
00110 for(double zoom = min; zoom <= max; zoom *= 2)
00111 {
00112 zoom_text->add_item(new BC_MenuItem(value_to_text(zoom, 0)));
00113 zoom_table.append(new ZoomHash(zoom, value_to_text(zoom, 0)));
00114 }
00115 }
00116 }
00117
00118 void ZoomPanel::update_menu()
00119 {
00120 while(zoom_text->total_items())
00121 {
00122 zoom_text->remove_item(0);
00123 }
00124
00125 zoom_table.remove_all_objects();
00126 calculate_menu();
00127 }
00128
00129 void ZoomPanel::set_menu_images(VFrame **data)
00130 {
00131 this->menu_images = data;
00132 }
00133
00134 void ZoomPanel::set_tumbler_images(VFrame **data)
00135 {
00136 this->tumbler_images = data;
00137 }
00138
00139 int ZoomPanel::create_objects()
00140 {
00141 subwindow->add_subwindow(zoom_text = new ZoomPopup(mwindow,
00142 this,
00143 x,
00144 y));
00145 x += zoom_text->get_w();
00146 subwindow->add_subwindow(zoom_tumbler = new ZoomTumbler(mwindow,
00147 this,
00148 x,
00149 y));
00150 calculate_menu();
00151 return 0;
00152 }
00153
00154 void ZoomPanel::reposition_window(int x, int y)
00155 {
00156 zoom_text->reposition_window(x, y);
00157 x += zoom_text->get_w();
00158 zoom_tumbler->reposition_window(x, y);
00159 }
00160
00161
00162 int ZoomPanel::get_w()
00163 {
00164 return zoom_text->get_w() + zoom_tumbler->get_w();
00165 }
00166
00167 double ZoomPanel::get_value()
00168 {
00169 return value;
00170 }
00171
00172 char* ZoomPanel::get_text()
00173 {
00174 return zoom_text->get_text();
00175 }
00176
00177 void ZoomPanel::set_text(char *text)
00178 {
00179 zoom_text->set_text(text);
00180 }
00181
00182 void ZoomPanel::update(double value)
00183 {
00184 this->value = value;
00185 zoom_text->set_text(value_to_text(value));
00186 }
00187
00188 void ZoomPanel::update(char *value)
00189 {
00190 zoom_text->set_text(value);
00191 }
00192
00193
00194 char* ZoomPanel::value_to_text(double value, int use_table)
00195 {
00196 if(use_table)
00197 {
00198 for(int i = 0; i < zoom_table.total; i++)
00199 {
00200
00201 if(EQUIV(zoom_table.values[i]->value, value))
00202 return zoom_table.values[i]->text;
00203 }
00204
00205 return zoom_table.values[0]->text;
00206 }
00207
00208 switch(zoom_type)
00209 {
00210 case ZOOM_PERCENTAGE:
00211 sprintf(string, "%d%%", (int)(value * 100));
00212 break;
00213
00214 case ZOOM_FLOAT:
00215 sprintf(string, "%.1f", value);
00216 break;
00217
00218 case ZOOM_LONG:
00219 sprintf(string, "%ld", (long)value);
00220 break;
00221
00222 case ZOOM_TIME:
00223 {
00224 double total_seconds = (double)mwindow->gui->canvas->get_w() *
00225 value /
00226 mwindow->edl->session->sample_rate;
00227 Units::totext(string,
00228 total_seconds,
00229 mwindow->edl->session->time_format,
00230 mwindow->edl->session->sample_rate,
00231 mwindow->edl->session->frame_rate,
00232 mwindow->edl->session->frames_per_foot);
00233 break;
00234 }
00235 }
00236 return string;
00237 }
00238
00239 double ZoomPanel::text_to_zoom(char *text, int use_table)
00240 {
00241 if(use_table)
00242 {
00243 for(int i = 0; i < zoom_table.total; i++)
00244 {
00245 if(!strcasecmp(text, zoom_table.values[i]->text))
00246 return zoom_table.values[i]->value;
00247 }
00248 return zoom_table.values[0]->value;
00249 }
00250
00251 switch(zoom_type)
00252 {
00253 case ZOOM_PERCENTAGE:
00254 return atof(text) / 100;
00255 break;
00256 case ZOOM_FLOAT:
00257 case ZOOM_LONG:
00258 return atof(text);
00259 break;
00260 case ZOOM_TIME:
00261 {
00262 double result = 1;
00263 double total_samples = Units::fromtext(text,
00264 mwindow->edl->session->sample_rate,
00265 mwindow->edl->session->time_format,
00266 mwindow->edl->session->frame_rate,
00267 mwindow->edl->session->frames_per_foot);
00268 total_samples /= mwindow->gui->canvas->get_w();
00269 double difference = fabs(total_samples - result);
00270 while(fabs(result - total_samples) <= difference)
00271 {
00272 difference = fabs(result - total_samples);
00273 result *= 2;
00274 }
00275 return result;
00276 break;
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 ZoomPopup::ZoomPopup(MWindow *mwindow, ZoomPanel *panel, int x, int y)
00288 : BC_PopupMenu(x,
00289 y,
00290 panel->w,
00291 panel->value_to_text(panel->value, 0),
00292 1,
00293 panel->menu_images)
00294 {
00295 this->mwindow = mwindow;
00296 this->panel = panel;
00297 }
00298
00299 ZoomPopup::~ZoomPopup()
00300 {
00301 }
00302
00303 int ZoomPopup::handle_event()
00304 {
00305 panel->value = panel->text_to_zoom(get_text());
00306 panel->handle_event();
00307 return 1;
00308 }
00309
00310
00311
00312 ZoomTumbler::ZoomTumbler(MWindow *mwindow, ZoomPanel *panel, int x, int y)
00313 : BC_Tumbler(x,
00314 y,
00315 panel->tumbler_images)
00316 {
00317 this->mwindow = mwindow;
00318 this->panel = panel;
00319 }
00320
00321 ZoomTumbler::~ZoomTumbler()
00322 {
00323 }
00324
00325 int ZoomTumbler::handle_up_event()
00326 {
00327 if(panel->user_table)
00328 {
00329 int current_index = 0;
00330 for(current_index = 0; current_index < panel->user_size; current_index++)
00331 if(EQUIV(panel->user_table[current_index], panel->value)) break;
00332 current_index++;
00333 CLAMP(current_index, 0, panel->user_size - 1);
00334 panel->value = panel->user_table[current_index];
00335 }
00336 else
00337 {
00338 panel->value *= 2;
00339 RECLIP(panel->value, panel->min, panel->max);
00340 }
00341
00342 panel->zoom_text->set_text(panel->value_to_text(panel->value));
00343 panel->handle_event();
00344 return 1;
00345 }
00346
00347 int ZoomTumbler::handle_down_event()
00348 {
00349 if(panel->user_table)
00350 {
00351 int current_index = 0;
00352 for(current_index = 0; current_index < panel->user_size; current_index++)
00353 if(EQUIV(panel->user_table[current_index], panel->value)) break;
00354 current_index--;
00355 CLAMP(current_index, 0, panel->user_size - 1);
00356 panel->value = panel->user_table[current_index];
00357 }
00358 else
00359 {
00360 panel->value /= 2;
00361 RECLIP(panel->value, panel->min, panel->max);
00362 }
00363 panel->zoom_text->set_text(panel->value_to_text(panel->value));
00364 panel->handle_event();
00365 return 1;
00366 }