00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #include <gtk/gtk.h>
00030 #ifdef XWIN
00031 #include <gdk/gdkx.h>
00032 #endif
00033 #include <glib.h>
00034 #include "paledit.h"
00035 #include "u7drag.h"
00036 #include "utils.h"
00037 #include <iostream>
00038 #include <iomanip>
00039 #include <ctype.h>
00040 #include <stdio.h>
00041 #include "studio.h"
00042 #include "shapefile.h"
00043
00044 using std::cout;
00045 using std::endl;
00046 using std::string;
00047 using std::vector;
00048 using std::ostream;
00049 using std::ofstream;
00050 using std::setw;
00051 using std::ifstream;
00052 using EStudio::Prompt;
00053 using EStudio::Alert;
00054
00055
00056
00057
00058
00059 static void Write_palette
00060 (
00061 unsigned char *buf,
00062 GdkRgbCmap *pal
00063 )
00064 {
00065 for (int i = 0; i < 256; i++)
00066 {
00067 int r = (pal->colors[i]>>16)&255,
00068 g = (pal->colors[i]>>8)&255,
00069 b = pal->colors[i]&255;
00070 buf[3*i] = r/4;
00071 buf[3*i + 1] = g/4;
00072 buf[3*i + 2] = b/4;
00073 }
00074 }
00075
00076
00077
00078
00079
00080 inline void Palette_edit::show
00081 (
00082 int x, int y, int w, int h
00083 )
00084 {
00085 int stride = draw->allocation.width;
00086 gdk_draw_indexed_image(draw->window, drawgc, x, y, w, h,
00087 GDK_RGB_DITHER_NORMAL,
00088 image + y*stride + x,
00089 stride, palettes[cur_pal]);
00090 if (selected >= 0)
00091
00092 gdk_draw_rectangle(draw->window, drawgc, FALSE,
00093 selected_box.x, selected_box.y,
00094 selected_box.w, selected_box.h);
00095 }
00096
00097
00098
00099
00100
00101
00102 void Palette_edit::select
00103 (
00104 int new_sel
00105 )
00106 {
00107 selected = new_sel;
00108
00109 gtk_statusbar_pop(GTK_STATUSBAR(sbar), sbar_sel);
00110 char buf[150];
00111 g_snprintf(buf, sizeof(buf), "Color %d (0x%02x)", new_sel, new_sel);
00112 gtk_statusbar_push(GTK_STATUSBAR(sbar), sbar_sel, buf);
00113 }
00114
00115
00116
00117
00118
00119 void Palette_edit::load
00120 (
00121 )
00122 {
00123
00124 for (vector<GdkRgbCmap*>::iterator it = palettes.begin();
00125 it != palettes.end(); ++it)
00126 gdk_rgb_cmap_free(*it);
00127 int cnt = flex_info->size();
00128 palettes.resize(cnt);
00129 if (!cnt)
00130 new_palette();
00131 else
00132 {
00133 for (int pnum = 0; pnum < cnt; pnum++)
00134 {
00135 size_t len;
00136 unsigned char *buf = (unsigned char *)
00137 flex_info->get(pnum, len);
00138 assert(len = 3*256);
00139 guint32 colors[256];
00140 for (int i = 0; i < 256; i++)
00141 colors[i] = (buf[3*i]<<16)*4 +
00142 (buf[3*i+1]<<8)*4 + buf[3*i+2]*4;
00143 palettes[pnum] = gdk_rgb_cmap_new(colors, 256);
00144 }
00145 }
00146 }
00147
00148
00149
00150
00151
00152 void Palette_edit::render
00153 (
00154 )
00155 {
00156 int neww = draw->allocation.width, newh = draw->allocation.height;
00157
00158 if (neww != width || newh != height)
00159 {
00160 delete image;
00161 width = neww;
00162 height = newh;
00163 image = new guchar[width*height];
00164 }
00165
00166 int eachw = width/16, eachh = height/16;
00167
00168 int extraw = width%16, extrah = height%16;
00169 int color = 0;
00170 int cury = 0;
00171 unsigned char *out = image;
00172 for (int y = 0; y < 16; y++, color += 16)
00173 {
00174 int curx = 0;
00175 int stopy = cury + eachh + (y < extrah);
00176 for ( ; cury < stopy; cury++)
00177 for (int x = 0, c = color; x < 16; x++, c++)
00178 {
00179 int cntx = eachw + (x < extraw);
00180 while (cntx--)
00181 *out++ = c;
00182 }
00183 }
00184 if (selected >= 0)
00185 {
00186 int selx = selected%16, sely = selected/16;
00187 selected_box.x = selx*eachw;
00188 selected_box.y = sely*eachh;
00189 selected_box.w = eachw;
00190 selected_box.h = eachh;
00191 if (selx < extraw)
00192 { selected_box.w++; selected_box.x += selx; }
00193 else
00194 selected_box.x += extraw;
00195 if (sely < extrah)
00196 { selected_box.h++; selected_box.y += sely; }
00197 else
00198 selected_box.y += extrah;
00199 select(selected);
00200 }
00201 }
00202
00203
00204
00205
00206
00207 int Palette_edit::color_closed
00208 (
00209 GtkWidget *dlg,
00210 GdkEvent *event,
00211 gpointer data
00212 )
00213 {
00214 cout << "color_closed" << endl;
00215 Palette_edit *paled = (Palette_edit *) data;
00216 paled->colorsel = 0;
00217 return FALSE;
00218 }
00219
00220
00221
00222
00223
00224 void Palette_edit::color_cancel
00225 (
00226 GtkWidget *dlg,
00227 gpointer data
00228 )
00229 {
00230 Palette_edit *paled = (Palette_edit *) data;
00231 if (paled->colorsel)
00232 gtk_widget_destroy(GTK_WIDGET(paled->colorsel));
00233 paled->colorsel = 0;
00234 }
00235
00236
00237
00238
00239
00240 void Palette_edit::color_okay
00241 (
00242 GtkWidget *dlg,
00243 gpointer data
00244 )
00245 {
00246 Palette_edit *paled = (Palette_edit *) data;
00247 if (paled->colorsel)
00248 {
00249 gdouble rgb[3];
00250 gtk_color_selection_get_color(
00251 GTK_COLOR_SELECTION(paled->colorsel->colorsel), rgb);
00252 unsigned char r = (unsigned char) (rgb[0]*256),
00253 g = (unsigned char) (rgb[1]*256),
00254 b = (unsigned char) (rgb[2]*256);
00255 if (paled->selected >= 0)
00256 paled->palettes[paled->cur_pal]->colors[
00257 paled->selected] =
00258 (r<<16) + (g<<8) + b;
00259 gtk_widget_destroy(GTK_WIDGET(paled->colorsel));
00260
00261 paled->update_flex(paled->cur_pal);
00262 paled->render();
00263 paled->show();
00264 }
00265 paled->colorsel = 0;
00266 }
00267
00268
00269
00270
00271
00272 void Palette_edit::double_clicked
00273 (
00274 )
00275 {
00276 cout << "Double-clicked" << endl;
00277 if (selected < 0 || colorsel)
00278 return;
00279 char buf[150];
00280 g_snprintf(buf, sizeof(buf), "Color %d (0x%02x)", selected, selected);
00281 colorsel = GTK_COLOR_SELECTION_DIALOG(
00282 gtk_color_selection_dialog_new(buf));
00283
00284 gtk_signal_connect(GTK_OBJECT(colorsel->ok_button), "clicked",
00285 GTK_SIGNAL_FUNC(color_okay), this);
00286 gtk_signal_connect(GTK_OBJECT(colorsel->cancel_button), "clicked",
00287 GTK_SIGNAL_FUNC(color_cancel), this);
00288
00289 gtk_signal_connect(GTK_OBJECT(colorsel), "delete_event",
00290 GTK_SIGNAL_FUNC(color_closed), this);
00291
00292 guint32 c = palettes[cur_pal]->colors[selected];
00293 gdouble rgb[3];
00294 rgb[0] = ((double) ((c>>16)&0xff))/256;
00295 rgb[1] = ((double) ((c>>8)&0xff))/256;
00296 rgb[2] = ((double) ((c>>0)&0xff))/256;
00297 gtk_color_selection_set_color(GTK_COLOR_SELECTION(colorsel->colorsel),
00298 rgb);
00299 gtk_widget_show(GTK_WIDGET(colorsel));
00300 }
00301
00302
00303
00304
00305
00306 gint Palette_edit::configure
00307 (
00308 GtkWidget *widget,
00309 GdkEventConfigure *event,
00310 gpointer data
00311 )
00312 {
00313 Palette_edit *paled = (Palette_edit *) data;
00314 if (!paled->width)
00315 {
00316 paled->drawgc = gdk_gc_new(widget->window);
00317
00318 gdk_rgb_gc_set_foreground(paled->drawgc,
00319 (255<<16) + (255<<8));
00320 }
00321 paled->render();
00322 return (TRUE);
00323 }
00324
00325
00326
00327
00328
00329 gint Palette_edit::expose
00330 (
00331 GtkWidget *widget,
00332 GdkEventExpose *event,
00333 gpointer data
00334 )
00335 {
00336 Palette_edit *paled = (Palette_edit *) data;
00337 paled->show(event->area.x, event->area.y, event->area.width,
00338 event->area.height);
00339 return (TRUE);
00340 }
00341
00342
00343
00344
00345
00346 gint Palette_edit::mouse_press
00347 (
00348 GtkWidget *widget,
00349 GdkEventButton *event,
00350 gpointer data
00351 )
00352 {
00353 Palette_edit *paled = (Palette_edit *) data;
00354
00355 if (event->button == 4 || event->button == 5)
00356 return (TRUE);
00357
00358 if (paled->colorsel)
00359 return (TRUE);
00360 int old_selected = paled->selected;
00361 int width = paled->width, height = paled->height;
00362 int eventx = (int) event->x, eventy = (int) event->y;
00363
00364 int eachw = width/16, eachh = height/16;
00365
00366 int extraw = width%16, extrah = height%16;
00367 int extrax = extraw*(eachw + 1);
00368 int extray = extrah*(eachh + 1);
00369 int selx, sely;
00370 if (eventx < extrax)
00371 selx = eventx/(eachw + 1);
00372 else
00373 selx = extraw + (eventx - extrax)/eachw;
00374 if (eventy < extray)
00375 sely = eventy/(eachh + 1);
00376 else
00377 sely = extrah + (eventy - extray)/eachh;
00378 paled->selected = sely*16 + selx;
00379 if (paled->selected == old_selected)
00380 {
00381 if (((GdkEvent *) event)->type == GDK_2BUTTON_PRESS)
00382 paled->double_clicked();
00383 }
00384 else
00385 {
00386 paled->render();
00387 paled->show();
00388 }
00389 if (event->button == 3)
00390 gtk_menu_popup(GTK_MENU(paled->create_popup()),
00391 0, 0, 0, 0, event->button, event->time);
00392 return (TRUE);
00393 }
00394
00395
00396
00397
00398
00399 void Palette_edit::drag_data_get
00400 (
00401 GtkWidget *widget,
00402 GdkDragContext *context,
00403 GtkSelectionData *seldata,
00404 guint info,
00405 guint time,
00406 gpointer data
00407 )
00408 {
00409 cout << "In DRAG_DATA_GET" << endl;
00410 Palette_edit *paled = (Palette_edit *) data;
00411 #if 0
00412 if (paled->selected < 0 || info != U7_TARGET_SHAPEID)
00413 return;
00414 guchar buf[30];
00415 int file = U7_SHAPE_SHAPES;
00416 Shape_info& shinfo = paled->info[paled->selected];
00417 int len = Store_u7_shapeid(buf, file, shinfo.shapenum,
00418 shinfo.framenum);
00419 cout << "Setting selection data (" << shinfo.shapenum <<
00420 '/' << shinfo.framenum << ')' << endl;
00421
00422 gtk_selection_owner_set(widget, gdk_atom_intern("XdndSelection", 0),
00423 time);
00424
00425 gtk_selection_data_set(seldata,
00426 gdk_atom_intern(U7_TARGET_SHAPEID_NAME, 0),
00427 8, buf, len);
00428 #endif
00429 }
00430
00431
00432
00433
00434
00435 gint Palette_edit::selection_clear
00436 (
00437 GtkWidget *widget,
00438 GdkEventSelection *event,
00439 gpointer data
00440 )
00441 {
00442
00443 cout << "SELECTION_CLEAR" << endl;
00444 return TRUE;
00445 }
00446
00447
00448
00449
00450
00451 gint Palette_edit::drag_begin
00452 (
00453 GtkWidget *widget,
00454 GdkDragContext *context,
00455 gpointer data
00456 )
00457 {
00458 cout << "In DRAG_BEGIN" << endl;
00459 Palette_edit *paled = (Palette_edit *) data;
00460
00461 return TRUE;
00462 }
00463
00464
00465
00466
00467
00468 void Palette_edit::palnum_changed
00469 (
00470 GtkAdjustment *adj,
00471 gpointer data
00472 )
00473 {
00474 Palette_edit *ed = (Palette_edit *) data;
00475 gint newnum = (gint) adj->value;
00476 ed->show_palette(newnum);
00477 ed->render();
00478 ed->show();
00479 ed->enable_controls();
00480 }
00481
00482
00483
00484
00485 void
00486 on_exportbtn_clicked (GtkButton *button,
00487 gpointer user_data)
00488 {
00489 GtkFileSelection *fsel = Create_file_selection(
00490 "Export palette to text format",
00491 (File_sel_okay_fun) Palette_edit::export_palette,
00492 user_data);
00493 gtk_widget_show(GTK_WIDGET(fsel));
00494 }
00495
00496 void
00497 on_importbtn_clicked (GtkButton *button,
00498 gpointer user_data)
00499 {
00500 GtkFileSelection *fsel = Create_file_selection(
00501 "Import palette from text format",
00502 (File_sel_okay_fun) Palette_edit::import_palette,
00503 user_data);
00504 gtk_widget_show(GTK_WIDGET(fsel));
00505 }
00506
00507 void
00508 on_insert_btn_clicked (GtkButton *button,
00509 gpointer user_data)
00510 {
00511 Palette_edit *ed = (Palette_edit *) user_data;
00512 ed->add_palette();
00513 }
00514 void
00515 on_remove_btn_clicked (GtkButton *button,
00516 gpointer user_data)
00517 {
00518 Palette_edit *ed = (Palette_edit *) user_data;
00519 ed->remove_palette();
00520 }
00521 void
00522 on_up_btn_clicked (GtkButton *button,
00523 gpointer user_data)
00524 {
00525 Palette_edit *ed = (Palette_edit *) user_data;
00526 ed->move_palette(true);
00527 }
00528 void
00529 on_down_btn_clicked (GtkButton *button,
00530 gpointer user_data)
00531 {
00532 Palette_edit *ed = (Palette_edit *) user_data;
00533 ed->move_palette(false);
00534 }
00535
00536
00537
00538
00539
00540 GtkWidget *Palette_edit::create_controls
00541 (
00542 )
00543 {
00544
00545 GtkWidget *topframe = gtk_frame_new (NULL);
00546 gtk_widget_show(topframe);
00547 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
00548 gtk_widget_show(vbox);
00549 gtk_container_add (GTK_CONTAINER (topframe), vbox);
00550
00551 GtkWidget *hbox0 = gtk_hbox_new(FALSE, 0);
00552 gtk_widget_show(hbox0);
00553 gtk_box_pack_start(GTK_BOX(vbox), hbox0, TRUE, TRUE, 2);
00554
00555
00556
00557 GtkWidget *frame = gtk_frame_new ("Edit");
00558 gtk_widget_show(frame);
00559 gtk_box_pack_start (GTK_BOX (hbox0), frame, FALSE, FALSE, 2);
00560 GtkWidget *hbuttonbox = gtk_hbutton_box_new ();
00561 gtk_widget_show (hbuttonbox);
00562 gtk_container_add (GTK_CONTAINER (frame), hbuttonbox);
00563 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
00564 GTK_BUTTONBOX_START);
00565 gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 0);
00566
00567 insert_btn = gtk_button_new_with_label ("New");
00568 gtk_widget_show (insert_btn);
00569 gtk_container_add (GTK_CONTAINER (hbuttonbox), insert_btn);
00570 GTK_WIDGET_SET_FLAGS (insert_btn, GTK_CAN_DEFAULT);
00571
00572 remove_btn = gtk_button_new_with_label ("Remove");
00573 gtk_widget_show (remove_btn);
00574 gtk_container_add (GTK_CONTAINER (hbuttonbox), remove_btn);
00575 GTK_WIDGET_SET_FLAGS (remove_btn, GTK_CAN_DEFAULT);
00576 gtk_signal_connect (GTK_OBJECT (insert_btn), "clicked",
00577 GTK_SIGNAL_FUNC (on_insert_btn_clicked),
00578 this);
00579 gtk_signal_connect (GTK_OBJECT (remove_btn), "clicked",
00580 GTK_SIGNAL_FUNC (on_remove_btn_clicked),
00581 this);
00582
00583
00584
00585 frame = gtk_frame_new ("Move");
00586 gtk_widget_show(frame);
00587 gtk_box_pack_start (GTK_BOX (hbox0), frame, FALSE, FALSE, 2);
00588 GtkWidget *bbox = gtk_hbox_new(TRUE, 0);
00589 gtk_widget_show(bbox);
00590 gtk_container_add(GTK_CONTAINER (frame), bbox);
00591 down_btn = gtk_button_new();
00592 gtk_widget_show (down_btn);
00593 gtk_box_pack_start (GTK_BOX (bbox), down_btn, FALSE, FALSE, 0);
00594 GTK_WIDGET_SET_FLAGS (down_btn, GTK_CAN_DEFAULT);
00595 GtkWidget *arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
00596 gtk_widget_show(arrow);
00597 gtk_container_add(GTK_CONTAINER(down_btn), arrow);
00598
00599 up_btn = gtk_button_new();
00600 gtk_widget_show (up_btn);
00601 gtk_box_pack_start (GTK_BOX (bbox), up_btn, FALSE, FALSE, 0);
00602 GTK_WIDGET_SET_FLAGS (up_btn, GTK_CAN_DEFAULT);
00603 arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
00604 gtk_widget_show(arrow);
00605 gtk_container_add(GTK_CONTAINER(up_btn), arrow);
00606 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
00607 GTK_SIGNAL_FUNC (on_down_btn_clicked),
00608 this);
00609 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
00610 GTK_SIGNAL_FUNC (on_up_btn_clicked),
00611 this);
00612
00613
00614
00615 frame = gtk_frame_new ("File");
00616 gtk_widget_show(frame);
00617 gtk_box_pack_start (GTK_BOX (hbox0), frame, FALSE, FALSE, 2);
00618 hbuttonbox = gtk_hbutton_box_new ();
00619 gtk_widget_show (hbuttonbox);
00620 gtk_container_add (GTK_CONTAINER (frame), hbuttonbox);
00621 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
00622 GTK_BUTTONBOX_START);
00623 gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 0);
00624
00625 GtkWidget *importbtn = gtk_button_new_with_label ("Import");
00626 gtk_widget_show (importbtn);
00627 gtk_container_add (GTK_CONTAINER (hbuttonbox), importbtn);
00628 GTK_WIDGET_SET_FLAGS (importbtn, GTK_CAN_DEFAULT);
00629
00630 GtkWidget *exportbtn = gtk_button_new_with_label ("Export");
00631 gtk_widget_show (exportbtn);
00632 gtk_container_add (GTK_CONTAINER (hbuttonbox), exportbtn);
00633 GTK_WIDGET_SET_FLAGS (exportbtn, GTK_CAN_DEFAULT);
00634 gtk_signal_connect (GTK_OBJECT (importbtn), "clicked",
00635 GTK_SIGNAL_FUNC (on_importbtn_clicked),
00636 this);
00637 gtk_signal_connect (GTK_OBJECT (exportbtn), "clicked",
00638 GTK_SIGNAL_FUNC (on_exportbtn_clicked),
00639 this);
00640 return topframe;
00641 }
00642
00643
00644
00645
00646
00647 void Palette_edit::enable_controls
00648 (
00649 )
00650 {
00651
00652 gtk_widget_set_sensitive(remove_btn, cur_pal >= 0 &&
00653 palettes.size() > 1);
00654 if (cur_pal == -1)
00655 {
00656 gtk_widget_set_sensitive(down_btn, false);
00657 gtk_widget_set_sensitive(up_btn, false);
00658 gtk_widget_set_sensitive(remove_btn, false);
00659 }
00660 else
00661 {
00662 gtk_widget_set_sensitive(down_btn,
00663 cur_pal < palettes.size() - 1);
00664 gtk_widget_set_sensitive(up_btn, cur_pal > 0);
00665 gtk_widget_set_sensitive(remove_btn, palettes.size() > 1);
00666 }
00667 }
00668
00669
00670
00671
00672
00673 void Palette_edit::setup
00674 (
00675 )
00676 {
00677
00678 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
00679 gtk_widget_show(vbox);
00680 set_widget(vbox);
00681
00682 GtkWidget *frame = gtk_frame_new(NULL);
00683 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
00684 gtk_widget_show(frame);
00685 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
00686 draw = gtk_drawing_area_new();
00687
00688
00689 gtk_widget_set_events(draw, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
00690 | GDK_POINTER_MOTION_HINT_MASK |
00691 GDK_BUTTON1_MOTION_MASK);
00692
00693 gtk_signal_connect(GTK_OBJECT(draw), "configure_event",
00694 GTK_SIGNAL_FUNC(configure), this);
00695
00696 gtk_signal_connect(GTK_OBJECT(draw), "expose_event",
00697 GTK_SIGNAL_FUNC(expose), this);
00698
00699 gtk_signal_connect(GTK_OBJECT(draw), "button_press_event",
00700 GTK_SIGNAL_FUNC(mouse_press), this);
00701
00702 gtk_signal_connect(GTK_OBJECT(draw), "drag_begin",
00703 GTK_SIGNAL_FUNC(drag_begin), this);
00704 gtk_signal_connect (GTK_OBJECT(draw), "drag_data_get",
00705 GTK_SIGNAL_FUNC(drag_data_get), this);
00706 gtk_signal_connect (GTK_OBJECT(draw), "selection_clear_event",
00707 GTK_SIGNAL_FUNC(selection_clear), this);
00708 gtk_container_add (GTK_CONTAINER (frame), draw);
00709 gtk_widget_show(draw);
00710
00711 sbar = gtk_statusbar_new();
00712 sbar_sel = gtk_statusbar_get_context_id(GTK_STATUSBAR(sbar),
00713 "selection");
00714
00715 GtkWidget *hbox1 = gtk_hbox_new(FALSE, 0);
00716 gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 0);
00717 gtk_widget_show(hbox1);
00718 gtk_box_pack_start(GTK_BOX(hbox1), sbar, TRUE, TRUE, 0);
00719
00720 GtkWidget *label = gtk_label_new("Palette #:");
00721 gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 4);
00722 gtk_widget_show(label);
00723
00724 palnum_adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0,
00725 palettes.size() - 1, 1,
00726 2, 2));
00727 pspin = gtk_spin_button_new(palnum_adj, 1, 0);
00728 gtk_signal_connect(GTK_OBJECT(palnum_adj), "value_changed",
00729 GTK_SIGNAL_FUNC(palnum_changed), this);
00730 gtk_box_pack_start(GTK_BOX(hbox1), pspin, FALSE, FALSE, 0);
00731 gtk_widget_show(pspin);
00732
00733
00734 gtk_box_pack_start(GTK_BOX(vbox), create_controls(), FALSE, FALSE, 0);
00735 gtk_widget_show(sbar);
00736 enable_controls();
00737 }
00738
00739
00740
00741
00742
00743 void Palette_edit::new_palette
00744 (
00745 )
00746 {
00747 guint32 colors[256];
00748 memset(&colors[0], 0, sizeof(colors));
00749 colors[0] = 255<<16;
00750 colors[1] = 255<<8;
00751 colors[2] = 255;
00752 GdkRgbCmap *newpal = gdk_rgb_cmap_new(colors, 256);
00753 int index = palettes.size();
00754 palettes.push_back(newpal);
00755 update_flex(index);
00756 }
00757
00758
00759
00760
00761
00762 void Palette_edit::update_flex
00763 (
00764 int pnum
00765 )
00766 {
00767 unsigned char *buf = new unsigned char[3*256];
00768 Write_palette(buf, palettes[pnum]);
00769
00770 flex_info->set(pnum, (char *) buf, 3*256);
00771 flex_info->set_modified();
00772 }
00773
00774
00775
00776
00777
00778 Palette_edit::Palette_edit
00779 (
00780 Flex_file_info *flinfo
00781 ) : Object_browser(0, flinfo),
00782 flex_info(flinfo), image(0), width(0), height(0),
00783 colorsel(0), cur_pal(0)
00784 {
00785 load();
00786 setup();
00787 }
00788
00789
00790
00791
00792
00793 Palette_edit::~Palette_edit
00794 (
00795 )
00796 {
00797 for (vector<GdkRgbCmap*>::iterator it = palettes.begin();
00798 it != palettes.end(); ++it)
00799 gdk_rgb_cmap_free(*it);
00800 gtk_widget_destroy(get_widget());
00801 delete image;
00802 }
00803
00804
00805
00806
00807
00808 void Palette_edit::show_palette
00809 (
00810 int palnum
00811 )
00812 {
00813 cur_pal = palnum;
00814 }
00815
00816
00817
00818
00819
00820 void Palette_edit::unselect
00821 (
00822 bool need_render
00823 )
00824 {
00825 if (selected >= 0)
00826 {
00827 selected = -1;
00828 if (need_render)
00829 {
00830 render();
00831 show();
00832 }
00833 }
00834 }
00835
00836
00837
00838
00839
00840 void Palette_edit::move_palette
00841 (
00842 bool up
00843 )
00844 {
00845 if (cur_pal < 0)
00846 return;
00847 GdkRgbCmap *tmp;
00848 if (up)
00849 {
00850 if (cur_pal > 0)
00851 {
00852 tmp = palettes[cur_pal - 1];
00853 palettes[cur_pal - 1] = palettes[cur_pal];
00854 palettes[cur_pal] = tmp;
00855 cur_pal--;
00856 flex_info->swap(cur_pal);
00857 }
00858 }
00859 else
00860 {
00861 if (cur_pal < palettes.size() - 1)
00862 {
00863 tmp = palettes[cur_pal + 1];
00864 palettes[cur_pal + 1] = palettes[cur_pal];
00865 palettes[cur_pal] = tmp;
00866 flex_info->swap(cur_pal);
00867 cur_pal++;
00868 }
00869 }
00870 flex_info->set_modified();
00871 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pspin), cur_pal);
00872 }
00873
00874
00875
00876
00877
00878 void Update_range_upper
00879 (
00880 GtkAdjustment *adj,
00881 int new_upper
00882 )
00883 {
00884 adj->upper = new_upper;
00885 gtk_signal_emit_by_name(GTK_OBJECT(adj), "changed");
00886 }
00887
00888
00889
00890
00891
00892 void Palette_edit::add_palette
00893 (
00894 )
00895 {
00896 new_palette();
00897 cur_pal = palettes.size() - 1;
00898 Update_range_upper(palnum_adj, palettes.size() - 1);
00899
00900 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pspin), cur_pal);
00901 }
00902
00903
00904
00905
00906
00907 void Palette_edit::remove_palette
00908 (
00909 )
00910 {
00911
00912 if (cur_pal < 0 || palettes.size() < 2)
00913 return;
00914 if (Prompt(
00915 "Do you really want to delete the palette you're viewing?",
00916 "Yes", "No") != 0)
00917 return;
00918 gdk_rgb_cmap_free(palettes[cur_pal]);
00919 palettes.erase(palettes.begin() + cur_pal);
00920 flex_info->remove(cur_pal);
00921 flex_info->set_modified();
00922 if (cur_pal >= palettes.size())
00923 cur_pal = palettes.size() - 1;
00924 Update_range_upper(palnum_adj, palettes.size() - 1);
00925
00926 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pspin), cur_pal);
00927 render();
00928 show();
00929 }
00930
00931
00932
00933
00934
00935 void Palette_edit::export_palette
00936 (
00937 char *fname,
00938 gpointer user_data
00939 )
00940 {
00941 Palette_edit *ed = (Palette_edit *) user_data;
00942 if (U7exists(fname))
00943 {
00944 char *msg = g_strdup_printf(
00945 "'%s' already exists. Overwrite?", fname);
00946 int answer = Prompt(msg, "Yes", "No");
00947 g_free(msg);
00948 if (answer != 0)
00949 return;
00950 }
00951
00952 GdkRgbCmap *pal = ed->palettes[ed->cur_pal];
00953 ofstream out(fname);
00954 out << "Palette from ExultStudio" << endl;
00955 int i;
00956 for (i = 255; i > 0; i--)
00957 if (pal->colors[i] != 0)
00958 break;
00959 int last_color = i;
00960 for (i = 0; i <= last_color; i++)
00961 {
00962 int r = (pal->colors[i]>>16)&255,
00963 g = (pal->colors[i]>>8)&255,
00964 b = pal->colors[i]&255;
00965 out << setw(3) << r << ' ' << setw(3) << g << ' ' <<
00966 setw(3) << b << endl;
00967 }
00968 out.close();
00969 }
00970
00971
00972
00973
00974
00975 void Palette_edit::import_palette
00976 (
00977 char *fname,
00978 gpointer user_data
00979 )
00980 {
00981 Palette_edit *ed = (Palette_edit *) user_data;
00982 char *msg = g_strdup_printf(
00983 "Overwrite current palette from '%s'?", fname);
00984 int answer = Prompt(msg, "Yes", "No");
00985 g_free(msg);
00986 if (answer != 0)
00987 return;
00988
00989 GdkRgbCmap *pal = ed->palettes[ed->cur_pal];
00990 ifstream in(fname);
00991 char buf[256];
00992 in.getline(buf, sizeof(buf));
00993 if (!in.good())
00994 {
00995 Alert("Error reading '%s'", fname);
00996 return;
00997 }
00998 int i = 0;
00999 while (i < 256 && !in.eof())
01000 {
01001 in.getline(buf, sizeof(buf));
01002 char *ptr = &buf[0];
01003
01004 while (ptr < buf + sizeof(buf) && *ptr && isspace(*ptr))
01005 ptr++;
01006 if (*ptr == '#')
01007 continue;
01008 int r, g, b;
01009 if (sscanf(buf, "%d %d %d", &r, &g, &b) == 3)
01010 pal->colors[i++] = (r<<16) + (g<<8) + b;
01011 }
01012 in.close();
01013
01014 ed->update_flex(ed->cur_pal);
01015 ed->render();
01016 ed->show();
01017 }
01018