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 "shapedraw.h"
00030 #include "vgafile.h"
00031 #include "ibuf8.h"
00032 #include "u7drag.h"
00033
00034 using std::cout;
00035 using std::endl;
00036
00037
00038
00039
00040
00041 void Shape_draw::show
00042 (
00043 GdkDrawable *drawable,
00044 int x, int y, int w, int h
00045 )
00046 {
00047 int stride = iwin->get_line_width();
00048 gdk_draw_indexed_image(drawable, drawgc, x, y, w, h,
00049 GDK_RGB_DITHER_NORMAL,
00050 iwin->get_bits() + y*stride + x,
00051 stride, palette);
00052 }
00053
00054
00055
00056
00057
00058 void Shape_draw::draw_shape
00059 (
00060 Shape_frame *shape,
00061 int x, int y
00062 )
00063 {
00064 shape->paint(iwin, x + shape->get_xleft(), y + shape->get_yabove());
00065 }
00066
00067
00068
00069
00070
00071 void Shape_draw::draw_shape
00072 (
00073 int shapenum, int framenum,
00074 int x, int y
00075 )
00076 {
00077 if (shapenum < 0 || shapenum >= ifile->get_num_shapes())
00078 return;
00079 Shape_frame *shape = ifile->get_shape(shapenum, framenum);
00080 if (shape)
00081 draw_shape(shape, x, y);
00082 }
00083
00084
00085
00086
00087
00088 void Shape_draw::draw_shape_outline
00089 (
00090 int shapenum, int framenum,
00091 int x, int y,
00092 unsigned char color
00093 )
00094 {
00095 if (shapenum < 0 || shapenum >= ifile->get_num_shapes())
00096 return;
00097 Shape_frame *shape = ifile->get_shape(shapenum, framenum);
00098 if (shape)
00099 {
00100 if (shape->is_rle())
00101 shape->paint_rle_outline(iwin, x + shape->get_xleft(),
00102 y + shape->get_yabove(), color);
00103 else
00104 {
00105 int w = shape->get_width(), h = shape->get_height();
00106 iwin->fill_line8(color, w, x, y);
00107 iwin->fill_line8(color, w, x, y + h - 1);
00108 iwin->fill8(color, 1, h, x, y);
00109 iwin->fill8(color, 1, h, x + w - 1, y);
00110 }
00111 }
00112 }
00113
00114
00115
00116
00117
00118 void Shape_draw::draw_shape_centered
00119 (
00120 int shapenum,
00121 int framenum
00122 )
00123 {
00124 iwin->fill8(255);
00125 if (shapenum < 0 || shapenum >= ifile->get_num_shapes())
00126 return;
00127 Shape_frame *shape = ifile->get_shape(shapenum, framenum);
00128 if (!shape)
00129 return;
00130
00131 gint winw = draw->allocation.width, winh = draw->allocation.height;
00132 draw_shape(shape, (winw - shape->get_width())/2,
00133 (winh - shape->get_height())/2);
00134 }
00135
00136
00137
00138
00139
00140 Shape_draw::Shape_draw
00141 (
00142 Vga_file *i,
00143 unsigned char *palbuf,
00144 GtkWidget *drw
00145 ) : ifile(i),
00146 iwin(0), palette(0), draw(drw), drawgc(0),
00147 drop_callback(0), drop_user_data(0), dragging(false)
00148 {
00149 guint32 colors[256];
00150 for (int i = 0; i < 256; i++)
00151 colors[i] = (palbuf[3*i]<<16)*4 + (palbuf[3*i+1]<<8)*4 +
00152 palbuf[3*i+2]*4;
00153 palette = gdk_rgb_cmap_new(colors, 256);
00154 }
00155
00156
00157
00158
00159
00160 Shape_draw::~Shape_draw
00161 (
00162 )
00163 {
00164 gdk_rgb_cmap_free(palette);
00165 delete iwin;
00166 }
00167
00168
00169
00170
00171
00172 void Shape_draw::render
00173 (
00174 )
00175 {
00176 }
00177
00178
00179
00180
00181
00182 void Shape_draw::set_background_color
00183 (
00184 guint32 c
00185 )
00186 {
00187 palette->colors[255] = c;
00188 render();
00189 show();
00190 }
00191
00192
00193
00194
00195
00196 void Shape_draw::configure
00197 (
00198 )
00199 {
00200 if (!draw->window)
00201 return;
00202 if (!iwin)
00203 {
00204 drawgc = gdk_gc_new(draw->window);
00205
00206 gdk_rgb_gc_set_foreground(drawgc, (255<<16) + (255<<8));
00207 iwin = new Image_buffer8(
00208 draw->allocation.width, draw->allocation.height);
00209 }
00210 else if (iwin->get_width() != draw->allocation.width ||
00211 iwin->get_height() != draw->allocation.height)
00212 {
00213 delete iwin;
00214 iwin = new Image_buffer8(
00215 draw->allocation.width, draw->allocation.height);
00216 }
00217 }
00218
00219
00220
00221
00222
00223 void Shape_draw::drag_data_received
00224 (
00225 GtkWidget *widget,
00226 GdkDragContext *context,
00227 gint x,
00228 gint y,
00229 GtkSelectionData *seldata,
00230 guint info,
00231 guint time,
00232 gpointer udata
00233 )
00234 {
00235 Shape_draw *draw = (Shape_draw *) udata;
00236 cout << "drag_data_received" << endl;
00237 if (draw->drop_callback &&
00238 seldata->type == gdk_atom_intern(U7_TARGET_SHAPEID_NAME, 0) &&
00239 seldata->format == 8 && seldata->length > 0)
00240 {
00241 int file, shape, frame;
00242 Get_u7_shapeid(seldata->data, file, shape, frame);
00243 (*draw->drop_callback)(file, shape, frame,
00244 draw->drop_user_data);
00245 }
00246 }
00247
00248
00249
00250
00251
00252 void Shape_draw::enable_drop
00253 (
00254 Drop_callback callback,
00255 void *udata
00256 )
00257 {
00258 gtk_widget_realize(draw);
00259 #ifndef WIN32
00260 drop_callback = callback;
00261 drop_user_data = udata;
00262 GtkTargetEntry tents[1];
00263 tents[0].target = U7_TARGET_SHAPEID_NAME;
00264 tents[0].flags = 0;
00265 tents[0].info = U7_TARGET_SHAPEID;
00266 gtk_drag_dest_set(draw, GTK_DEST_DEFAULT_ALL, tents, 1,
00267 (GdkDragAction) (GDK_ACTION_COPY | GDK_ACTION_MOVE));
00268
00269 gtk_signal_connect(GTK_OBJECT(draw), "drag_data_received",
00270 GTK_SIGNAL_FUNC(drag_data_received), this);
00271 #endif
00272 }
00273
00274
00275
00276
00277
00278 void Shape_draw::set_drag_icon
00279 (
00280 GdkDragContext *context,
00281 Shape_frame *shape
00282 )
00283 {
00284 int w = shape->get_width(), h = shape->get_height(),
00285 xright = shape->get_xright(), ybelow = shape->get_ybelow();
00286 Image_buffer8 tbuf(w, h);
00287 tbuf.fill8(0xff);
00288 unsigned char *tbits = tbuf.get_bits();
00289 shape->paint(&tbuf, w - 1 - xright, h - 1 - ybelow);
00290
00291 GdkPixmap *pixmap = gdk_pixmap_new(draw->window, w, h, -1);
00292 gdk_draw_indexed_image(pixmap, drawgc, 0, 0, w, h,
00293 GDK_RGB_DITHER_NORMAL, tbits,
00294 tbuf.get_line_width(), palette);
00295 int mask_stride = (w + 7)/8;
00296 char *mdata = new char[mask_stride*h];
00297 for (int y = 0; y < h; y++)
00298
00299 for (int b = 0; b < mask_stride; b++)
00300 {
00301 char bits = 0;
00302 unsigned char *vals = tbits + y*w + b*8;
00303 for (int i = 0; i < 8; i++)
00304 if (vals[i] != 0xff)
00305 bits |= (1<<i);
00306 mdata[y*mask_stride + b] = bits;
00307 }
00308 GdkBitmap *mask = gdk_bitmap_create_from_data(draw->window,
00309 mdata, w, h);
00310 delete mdata;
00311
00312 gtk_drag_set_icon_pixmap(context,
00313 gdk_window_get_colormap(draw->window), pixmap, mask,
00314 w - 2 - xright, h - 2 - ybelow);
00315 gdk_pixmap_unref(pixmap);
00316 gdk_bitmap_unref(mask);
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 void Shape_draw::start_drag
00326 (
00327 char *target,
00328 int id,
00329 GdkEvent *event
00330 )
00331 {
00332 if (dragging)
00333 return;
00334 dragging = true;
00335 GtkTargetEntry tents[1];
00336 tents[0].target = target;
00337 tents[0].flags = 0;
00338 tents[0].info = id;
00339 GtkTargetList *tlist = gtk_target_list_new(&tents[0], 1);
00340
00341 gtk_drag_begin(draw, tlist,
00342 (GdkDragAction) (GDK_ACTION_COPY | GDK_ACTION_MOVE),
00343 1, event);
00344 }