/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include "arch.hh" #include "window/dragwin.hh" #include "device/kernel.hh" #include "error/error.hh" #include "window/win_evt.hh" #include "area/rectlist.hh" #include "image/image.hh" class i4_drag_frame_class : public i4_window_class { i4_coord ghost_x,ghost_y; public : i4_bool need_remove_ghost, draw_self; char *name() { return "drag_frame"; } i4_drag_frame_class(w16 w, w16 h) : i4_window_class(w,h) { need_remove_ghost=i4_F; draw_self=i4_T; } virtual void draw(i4_draw_context_class &context) { // this draw is special in that it should not be subject to clipping and // window coordinate transformations i4_rect_list_class no_clip(0,0,local_image->width()-1,local_image->height()-1); context.clip.swap(&no_clip); i4_coord old_xoff=context.xoff,old_yoff=context.yoff; context.xoff=0; context.yoff=0; if (need_remove_ghost) { i4_coord x1=ghost_x,y1=ghost_y; i4_coord x2=x1+width()-1,y2=y1+height()-1; i4_color c=0xffffffff; local_image->xor_bar(x1,y1,x2,y1,c,context); local_image->xor_bar(x2,y1,x2,y2,c,context); local_image->xor_bar(x1,y1,x1,y2,c,context); local_image->xor_bar(x1,y2,x2,y2,c,context); } if (draw_self) { i4_coord x1=x(),y1=y(); i4_coord x2=x1+width()-1,y2=y1+height()-1; i4_color c=0xffffffff; local_image->xor_bar(x1,y1,x2,y1,c,context); local_image->xor_bar(x2,y1,x2,y2,c,context); local_image->xor_bar(x1,y1,x1,y2,c,context); local_image->xor_bar(x1,y2,x2,y2,c,context); ghost_x=x(); ghost_y=y(); } draw_self=i4_T; need_remove_ghost=i4_T; context.xoff=old_xoff; context.yoff=old_yoff; context.clip.swap(&no_clip); } virtual void show_self(w32 indent) { char fmt[50]; sprintf(fmt,"%%%ds drag_window",indent); i4_warning(fmt," "); } } ; i4_draggable_window_class::i4_draggable_window_class(w16 w, w16 h) : i4_parent_window_class(w,h) { drag_frame=0; last_mouse_x=0; last_mouse_y=0; } void i4_draggable_window_class::receive_event(i4_event *ev) { if (ev->type()==i4_event::WINDOW_MESSAGE) { CAST_PTR(message,i4_window_request_drag_start_class,ev); // must have a parent in order to move/be dragged if (message->sub_type==i4_window_message_class::REQUEST_DRAG_START && parent) { // see if we can grab the mouse i4_window_request_mouse_grab_class grab(message->from()); // ask ourself, we will check with our parent.. i4_kernel.send_event(this,&grab); if (grab.return_result) { drag_frame=new i4_drag_frame_class(width(),height()); parent->add_child(x(),y(),drag_frame); message->return_result=i4_T; } else { message->return_result=i4_F; i4_warning("draggable window:: unable to grab mouse"); } } // must have a parent in order to move/be dragged else if (message->sub_type==i4_window_message_class::REQUEST_DRAG_END && parent) { if (!drag_frame) i4_error("got drag end message and not dragging"); i4_window_request_mouse_ungrab_class ungrab(this); i4_kernel.send_event(this,&ungrab); // move ourself to the final position of the drag frame move(drag_frame->x()-x(),drag_frame->y()-y()); request_redraw(); // tell ourselves to delete the dragger next tick, // so it gets a chance to clear itself off the screen i4_kernel.delete_handler(drag_frame); drag_frame->need_remove_ghost=i4_T; drag_frame->draw_self=i4_F; drag_frame=0; // assume it is deleted now } else i4_parent_window_class::receive_event(ev); } else if (ev->type()==i4_event::MOUSE_MOVE) { CAST_PTR(move,i4_mouse_move_event_class,ev); current_mouse_x=move->x+x(); current_mouse_y=move->y+y(); if (drag_frame && ((current_mouse_x!=last_mouse_x || current_mouse_y!=last_mouse_y))) { if (current_mouse_x<0) current_mouse_x=0; if (current_mouse_y<0) current_mouse_y=0; i4_coord xo=current_mouse_x-last_mouse_x,yo=current_mouse_y-last_mouse_y; drag_frame->move(xo,yo,i4_F); drag_frame->request_redraw(); } last_mouse_x=current_mouse_x; last_mouse_y=current_mouse_y; i4_parent_window_class::receive_event(ev); } else i4_parent_window_class::receive_event(ev); }