00001
00020 #include "mfcpch.h"
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #ifdef __UNIX__
00024 #include <signal.h>
00025 #endif
00026 #include "grphics.h"
00027
00028
00029 #include "grphshm.h"
00030 #include "evntlst.h"
00031 #ifdef WXSBSERVANT
00032
00033 #if defined(__GNUG__) && !defined(__APPLE__)
00034 #pragma implementation
00035 #pragma interface
00036 #endif
00037
00038
00039 #include "wx/wxprec.h"
00040
00041 #ifdef __BORLANDC__
00042 #pragma hdrstop
00043 #endif
00044
00045
00046
00047 #ifndef WX_PRECOMP
00048 #include "wx/wx.h"
00049 #endif
00050
00051 #include "wx/colordlg.h"
00052 #include "wx/image.h"
00053 #include "wx/artprov.h"
00054 #include "wx/socket.h"
00055 #include "wx/settings.h"
00056 #include "wx/wfstream.h"
00057 #include "wx/listctrl.h"
00058 #include "wx/sizer.h"
00059 #include "wx/protocol/protocol.h"
00060 #endif //WXSBSERVANT
00061
00062 #define XSIZE_INCREMENT 8
00063 #define YSIZE_INCREMENT 30
00064
00065 void def_overlap_picture_ops(BOOL8 update);
00066
00067 WINCREATEFUNC create_func = WINFD::create;
00068 void (*overlap_func) (BOOL8) = def_overlap_picture_ops;
00069
00098 WINDOW WINFD::create(
00099 const char *name,
00100 INT8 window_type,
00101 INT16 xpos,
00102 INT16 ypos,
00103 INT16 xsize,
00104 INT16 ysize,
00105 float xmin,
00106 float xmax,
00107 float ymin,
00108 float ymax,
00109 BOOL8 downon,
00110 BOOL8 moveon,
00111 BOOL8 upon,
00112 BOOL8 keyon) {
00113 INT16 fd;
00114 CREATEOP *newop;
00115 WINDOW win;
00116
00117 #ifdef NO_X_WINDOWS
00118 return NO_WINDOW;
00119 #endif
00120
00121 if (xmin == xmax || ymin == ymax)
00122 return NO_WINDOW;
00123 if (maxsbfd == 0) {
00124 maxsbfd = 1;
00125 start_sbdaemon();
00126 }
00127
00128
00129 for (fd = 1; fd < maxsbfd && sbfds[fd].used; fd++);
00130 if (fd == maxsbfd) {
00131 if (maxsbfd == MAXWINDOWS)
00132 return NO_WINDOW;
00133 maxsbfd++;
00134 }
00135 win = &sbfds[fd];
00136 win->fd = fd;
00137 win->used = TRUE;
00138 win->downevent = downon;
00139 win->moveevent = moveon;
00140 win->upevent = upon;
00141 win->keyevent = keyon;
00142 win->click_handler = NULL;
00143 win->selection_handler = NULL;
00144 win->key_handler = NULL;
00145 win->destroy_handler = NULL;
00146 win->events = NULL;
00147 win->lastevent = NULL;
00148
00149 newop = (CREATEOP *) getshm (sizeof (CREATEOP));
00150 if (newop != NULL) {
00151 newop->header.fd = fd;
00152 newop->type = CREATE;
00153 newop->window_type = window_type;
00154
00155 strncpy (newop->name, name, MAXWINDOWNAME - 1);
00156 newop->name[MAXWINDOWNAME - 1] = '\0';
00157 newop->xpos = xpos;
00158 newop->ypos = ypos;
00159 newop->xsize = xsize;
00160 newop->ysize = ysize;
00161 newop->xmin = xmin;
00162 newop->xmax = xmax;
00163 newop->ymin = ymin;
00164 newop->ymax = ymax;
00165 newop->downon = downon;
00166 newop->moveon = moveon;
00167 newop->upon = upon;
00168 newop->keyon = keyon;
00169 }
00170 return win;
00171 }
00172
00173
00174
00180 void WINFD::Line_color_index(
00181 COLOUR index
00182 ) {
00183 ONEOP *newop;
00184
00185
00186 newop = (ONEOP *) getshm (sizeof (ONEOP));
00187 if (newop != NULL) {
00188 newop->header.fd = fd;
00189 newop->type = LINECOLOUR;
00190 newop->param.p.i = index;
00191 }
00192 }
00193
00194
00200 void WINFD::Perimeter_color_index(
00201 COLOUR index
00202 ) {
00203 ONEOP *newop;
00204
00205
00206 newop = (ONEOP *) getshm (sizeof (ONEOP));
00207 if (newop != NULL) {
00208 newop->header.fd = fd;
00209
00210 newop->type = PERIMETERCOLOUR;
00211 newop->param.p.i = index;
00212 }
00213 }
00214
00215
00221 void WINFD::Fill_color_index(
00222 COLOUR index
00223 ) {
00224 ONEOP *newop;
00225
00226
00227 newop = (ONEOP *) getshm (sizeof (ONEOP));
00228 if (newop != NULL) {
00229 newop->header.fd = fd;
00230 newop->type = FILLCOLOUR;
00231 newop->param.p.i = index;
00232 }
00233 }
00234
00235
00241 void WINFD::Fill_color(
00242 UINT8 red,
00243 UINT8 green,
00244 UINT8 blue) {
00245 ONEOP *newop;
00246 UINT32 packed_colour;
00247
00248 packed_colour = (blue << 24) + (green << 16) + (red << 8);
00249
00250 newop = (ONEOP *) getshm (sizeof (ONEOP));
00251 if (newop != NULL) {
00252 newop->header.fd = fd;
00253 newop->type = FILLCOLOUR;
00254
00255 newop->param.p.i = (INT32) packed_colour;
00256 }
00257 }
00258
00259
00265 void WINFD::Marker_color_index(
00266 COLOUR index
00267 ) {
00268 ONEOP *newop;
00269
00270
00271 newop = (ONEOP *) getshm (sizeof (ONEOP));
00272 if (newop != NULL) {
00273 newop->header.fd = fd;
00274 newop->type = MARKERCOLOUR;
00275 newop->param.p.i = index;
00276 }
00277 }
00278
00279
00285 void WINFD::Text_color_index(
00286 COLOUR index
00287 ) {
00288 ONEOP *newop;
00289
00290
00291 newop = (ONEOP *) getshm (sizeof (ONEOP));
00292 if (newop != NULL) {
00293 newop->header.fd = fd;
00294 newop->type = TEXTCOLOUR;
00295 newop->param.p.i = index;
00296 }
00297 }
00298
00299
00305 void WINFD::Text_font_index(
00306 INT16 index
00307 ) {
00308 ONEOP *newop;
00309
00310
00311 newop = (ONEOP *) getshm (sizeof (ONEOP));
00312 if (newop != NULL) {
00313 newop->header.fd = fd;
00314 newop->type = TEXTFONT;
00315 newop->param.p.i = index;
00316 }
00317 }
00318
00319
00325 void WINFD::Character_height(
00326 float height
00327 ) {
00328 ONEOP *newop;
00329
00330
00331 newop = (ONEOP *) getshm (sizeof (ONEOP));
00332 if (newop != NULL) {
00333 newop->header.fd = fd;
00334 newop->type = CHARHEIGHT;
00335 newop->param.p.f = height;
00336 }
00337 }
00338
00339
00345 void WINFD::Line_type(
00346 INT16 style
00347 ) {
00348 ONEOP *newop;
00349
00350
00351 newop = (ONEOP *) getshm (sizeof (ONEOP));
00352 if (newop != NULL) {
00353 newop->header.fd = fd;
00354 newop->type = LINETYPE;
00355 newop->param.p.i = style;
00356 }
00357 }
00358
00359
00365 void WINFD::Marker_type(
00366 INT16 type
00367 ) {
00368 ONEOP *newop;
00369
00370
00371 newop = (ONEOP *) getshm (sizeof (ONEOP));
00372 if (newop != NULL) {
00373 newop->header.fd = fd;
00374 newop->type = MARKERTYPE;
00375 newop->param.p.i = type;
00376 }
00377 }
00378
00379
00385 void WINFD::Interior_style(
00386 INT16 style,
00387 INT16 edged
00388 ) {
00389 TWOOP *newop;
00390
00391
00392 newop = (TWOOP *) getshm (sizeof (TWOOP));
00393 if (newop != NULL) {
00394 newop->header.fd = fd;
00395 newop->type = INTERIORSTYLE;
00396 newop->param.p[0].i = style;
00397 newop->param.p[1].i = edged;
00398 }
00399 }
00400
00401
00407 void WINFD::Marker_size(
00408 float size
00409 ) {
00410 TWOOP *newop;
00411
00412
00413 newop = (TWOOP *) getshm (sizeof (TWOOP));
00414 if (newop != NULL) {
00415 newop->header.fd = fd;
00416 newop->type = MARKERSIZE;
00417 newop->param.p[0].f = size;
00418 newop->param.p[1].i = FALSE;
00419 }
00420 }
00421
00422
00428 void WINFD::Move2d(
00429 float x,
00430 float y
00431 ) {
00432 TWOOP *newop;
00433
00434
00435 newop = (TWOOP *) getshm (sizeof (TWOOP));
00436 if (newop != NULL) {
00437 newop->header.fd = fd;
00438 newop->type = MOVE2D;
00439 newop->param.p[0].f = x;
00440 newop->param.p[1].f = y;
00441 }
00442 }
00443
00444
00450 void WINFD::Draw2d(
00451 float x,
00452 float y
00453 ) {
00454 TWOOP *newop;
00455
00456
00457 newop = (TWOOP *) getshm (sizeof (TWOOP));
00458 if (newop != NULL) {
00459 newop->header.fd = fd;
00460 newop->type = DRAW2D;
00461 newop->param.p[0].f = x;
00462 newop->param.p[1].f = y;
00463 }
00464 }
00465
00466
00472 void WINFD::Rectangle(
00473 float x1,
00474 float y1,
00475 float x2,
00476 float y2
00477 ) {
00478 FOUROP *newop;
00479
00480
00481 newop = (FOUROP *) getshm (sizeof (FOUROP));
00482 if (newop != NULL) {
00483 newop->header.fd = fd;
00484 newop->type = RECTANGLE;
00485 newop->param.p[0].f = x1;
00486 newop->param.p[1].f = y1;
00487 newop->param.p[2].f = x2;
00488 newop->param.p[3].f = y2;
00489 }
00490 }
00491
00492
00498 void WINFD::Text_alignment(
00499 INT32 h_select,
00500 INT32 v_select,
00501 float horiz,
00502 float vert
00503 ) {
00504 #ifndef WXSBSERVANT
00505 FOUROP *newop;
00506
00507
00508 newop = (FOUROP *) getshm (sizeof (FOUROP));
00509 if (newop != NULL) {
00510 newop->header.fd = fd;
00511 newop->type = TEXT_ALIGNMENT;
00512 newop->param.p[0].i = h_select;
00513 newop->param.p[1].i = v_select;
00514 newop->param.p[2].f = horiz;
00515 newop->param.p[3].f = vert;
00516 }
00517 #else // WXSBSERVANT
00518 #endif //WXSBSERVANT
00519 }
00520
00521
00527 void
00528 WINFD::Polyline2d (
00529 float clist[],
00530 INT16 numpts,
00531 INT16 flags
00532 ) {
00533 POLYOP *newop;
00534 INT32 floatcount;
00535
00536 floatcount = flags ? numpts * 3
00537 : numpts * 2;
00538
00539 newop = (POLYOP *) getshm (sizeof (POLYOP) + sizeof (float) * (floatcount - 1));
00540 if (newop != NULL) {
00541 newop->header.fd = fd;
00542 newop->type = POLYLINE2D;
00543
00544 newop->param.clist = newop->clist;
00545 newop->param.numpts = numpts;
00546 newop->param.flags = flags;
00547 memcpy (newop->clist, clist, (UINT32) floatcount * sizeof (float));
00548 }
00549 }
00550
00551
00557 void
00558 WINFD::Polygon2d (
00559 float clist[],
00560 INT16 numpts,
00561 INT16 flags
00562 ) {
00563 POLYOP *newop;
00564 INT32 floatcount;
00565
00566 floatcount = flags ? numpts * 3
00567 : numpts * 2;
00568
00569 newop = (POLYOP *) getshm (sizeof (POLYOP) + sizeof (float) * (floatcount - 1));
00570 if (newop != NULL) {
00571 newop->header.fd = fd;
00572 newop->type = POLYGON2D;
00573
00574 newop->param.clist = newop->clist;
00575 newop->param.numpts = numpts;
00576 newop->param.flags = flags;
00577 memcpy (newop->clist, clist, (UINT32) floatcount * sizeof (float));
00578 }
00579 }
00580
00581
00587 void
00588 WINFD::Polymarker2d (
00589 float clist[],
00590 INT16 numpts,
00591 INT16 flags
00592 ) {
00593 POLYOP *newop;
00594 INT32 floatcount;
00595
00596 floatcount = flags ? numpts * 3
00597 : numpts * 2;
00598
00599 newop = (POLYOP *) getshm (sizeof (POLYOP) + sizeof (float) * (floatcount - 1));
00600 if (newop != NULL) {
00601 newop->header.fd = fd;
00602 newop->type = POLYMARKER2D;
00603
00604 newop->param.clist = newop->clist;
00605 newop->param.numpts = numpts;
00606 newop->param.flags = flags;
00607 memcpy (newop->clist, clist, (UINT32) floatcount * sizeof (float));
00608 }
00609 }
00610
00611
00617 void WINFD::Text2d(
00618 float x,
00619 float y,
00620 const char *string,
00621 INT16 xform,
00622 INT16 more
00623 ) {
00624 TEXTOP *newop;
00625 INT16 length;
00626
00627 length = strlen (string) + 1;
00628 length += 3;
00629 length &= ~3;
00630
00631 newop = (TEXTOP *) getshm (sizeof (TEXTOP) + length - 4);
00632 if (newop != NULL) {
00633 newop->header.fd = fd;
00634 newop->type = TEXT2D;
00635 newop->param.x = x;
00636 newop->param.y = y;
00637 newop->param.string = newop->chars;
00638 newop->param.xform = xform;
00639 newop->param.more = more;
00640
00641 strcpy (newop->chars, string);
00642 }
00643 }
00644
00645
00651 void WINFD::Append_text(
00652 const char *string,
00653 INT16 xform,
00654 INT16 more
00655 ) {
00656 APPENDOP *newop;
00657 INT16 length;
00658
00659 length = strlen (string) + 1;
00660 length += 3;
00661 length &= ~3;
00662
00663 newop = (APPENDOP *) getshm (sizeof (APPENDOP) + length - 4);
00664 if (newop != NULL) {
00665 newop->header.fd = fd;
00666 newop->type = APPENDTEXT;
00667 newop->param.string = newop->chars;
00668 newop->param.xform = xform;
00669 newop->param.more = more;
00670
00671 strcpy (newop->chars, string);
00672 }
00673 }
00674
00675
00681 void WINFD::Ellipse(
00682 float x_radius,
00683 float y_radius,
00684 float x_center,
00685 float y_center,
00686 float rotation
00687 ) {
00688 EIGHTOP *newop;
00689
00690
00691 newop = (EIGHTOP *) getshm (sizeof (EIGHTOP));
00692 if (newop != NULL) {
00693 newop->header.fd = fd;
00694 newop->type = ELLIPSE;
00695
00696 newop->param.p[0].f = x_radius;
00697 newop->param.p[1].f = y_radius;
00698 newop->param.p[2].f = x_center;
00699 newop->param.p[3].f = y_center;
00700 newop->param.p[4].f = rotation;
00701 }
00702 }
00703
00704
00710 void WINFD::Arc(
00711 float x_radius,
00712 float y_radius,
00713 float x_center,
00714 float y_center,
00715 float start,
00716 float stop,
00717 float rotation,
00718 INT16 close_type
00719 ) {
00720 EIGHTOP *newop;
00721
00722
00723 newop = (EIGHTOP *) getshm (sizeof (EIGHTOP));
00724 if (newop != NULL) {
00725 newop->header.fd = fd;
00726 newop->type = ARC;
00727
00728 newop->param.p[0].f = x_radius;
00729 newop->param.p[1].f = y_radius;
00730 newop->param.p[2].f = x_center;
00731 newop->param.p[3].f = y_center;
00732 newop->param.p[4].f = start;
00733 newop->param.p[5].f = stop;
00734 newop->param.p[6].f = rotation;
00735 newop->param.p[7].i = close_type;
00736 }
00737 }
00738
00739
00743 WINFD::WINFD() {
00744 fd = -1;
00745 used = FALSE;
00746 downevent = FALSE;
00747 moveevent = FALSE;
00748 upevent = FALSE;
00749 keyevent = FALSE;
00750 click_handler = NULL;
00751 selection_handler = NULL;
00752 key_handler = NULL;
00753 destroy_handler = NULL;
00754 events = NULL;
00755 lastevent = NULL;
00756 }
00757
00758
00759 WINFD::~WINFD () {
00760 }
00761
00762
00768 void WINFD::Destroy_window() {
00769 ONEOP *newop;
00770
00771 if (fd < 1 || fd > maxsbfd || sbfds[fd].used == FALSE) {
00772 return;
00773 }
00774 else {
00775 Clear_event_queue();
00776 sbfds[fd].used = FALSE;
00777 sbfds[fd].click_handler = NULL;
00778
00779 newop = (ONEOP *) getshm (sizeof (ONEOP));
00780 if (newop != NULL) {
00781 newop->header.fd = fd;
00782 newop->type = DESTROY;
00783 }
00784 }
00785 }
00786
00787
00793 void WINFD::Clear_event_queue() {
00794 INT16 fd;
00795 GRAPHICS_EVENT *event;
00796 GRAPHICS_EVENT *nextevent;
00797
00798 if (this == NULL) {
00799 for (fd = 1; fd < maxsbfd; fd++) {
00800 if (sbfds[fd].used) {
00801 sbfds[fd].Clear_event_queue ();
00802 }
00803 }
00804 }
00805 else {
00806 for (event = events; event != NULL; event = nextevent) {
00807 nextevent = event->next;
00808 delete event;
00809 }
00810 events = NULL;
00811 }
00812 }
00813
00814
00820 void WINFD::Clear_view_surface() {
00821 ONEOP *newop;
00822
00823
00824 newop = (ONEOP *) getshm (sizeof (ONEOP));
00825 if (newop != NULL) {
00826 newop->header.fd = fd;
00827 newop->type = CLEAR;
00828 }
00829 }
00830
00831
00837 void WINFD::Re_compute_colourmap() {
00838 ONEOP *newop;
00839
00840
00841 newop = (ONEOP *) getshm (sizeof (ONEOP));
00842 if (newop != NULL) {
00843 newop->header.fd = fd;
00844 newop->type = RE_COMP_COLMAP;
00845 }
00846
00847
00848
00849
00850
00851
00852
00853 }
00854
00855
00861 void WINFD::Vdc_extent(
00862 float Xmin,
00863 float Ymin,
00864 float Xmax,
00865 float Ymax
00866 ) {
00867 EIGHTOP *newop;
00868
00869
00870 newop = (EIGHTOP *) getshm (sizeof (EIGHTOP));
00871 if (newop != NULL) {
00872 newop->header.fd = fd;
00873 newop->type = VDCEXTENT;
00874 newop->param.p[0].f = Xmin;
00875 newop->param.p[1].f = Ymin;
00876 newop->param.p[2].f = 0.0f;
00877 newop->param.p[3].f = Xmax;
00878 newop->param.p[4].f = Ymax;
00879 newop->param.p[5].f = 0.0f;
00880 }
00881 }
00882
00883
00889 void WINFD::Set_echo(
00890 ECHO_TYPE echo_type,
00891 float xorig,
00892 float yorig
00893 ) {
00894 FOUROP *newop;
00895
00896
00897 newop = (FOUROP *) getshm (sizeof (FOUROP));
00898 if (newop != NULL) {
00899 newop->header.fd = fd;
00900 newop->type = SETECHO;
00901 newop->param.p[0].i = echo_type;
00902 newop->param.p[1].f = xorig;
00903 newop->param.p[2].f = yorig;
00904 }
00905 }
00906
00907
00916 DLLSYM void def_overlap_picture_ops(
00917 BOOL8 update
00918 ) {
00919 ONEOP *newop;
00920 INT16 fd;
00921
00922 if (update) {
00923 for (fd = 1; fd < maxsbfd; fd++) {
00924 if (sbfds[fd].used) {
00925
00926 newop = (ONEOP *) getshm (sizeof (ONEOP));
00927 if (newop != NULL) {
00928 newop->header.fd = fd;
00929
00930 newop->type = MAKECURRENT;
00931 }
00932 }
00933 }
00934 }
00935 kick_daemon(FLUSH_OUT);
00936 }
00937
00938
00946 void WINFD::Make_picture_current() {
00947 ONEOP *newop;
00948
00949 if (this == NULL || fd <= 0) {
00950 overlap_picture_ops(TRUE);
00951 }
00952 else {
00953
00954 newop = (ONEOP *) getshm (sizeof (ONEOP));
00955 if (newop != NULL) {
00956 newop->header.fd = fd;
00957 newop->type = MAKECURRENT;
00958 kick_daemon(FLUSH_IN);
00959 }
00960 }
00961 }
00962
00963
00969 void WINFD::Synchronize_windows(
00970 WINDOW fd2
00971 ) {
00972 ONEOP *newop;
00973
00974
00975 newop = (ONEOP *) getshm (sizeof (ONEOP));
00976 if (newop != NULL) {
00977 newop->header.fd = fd;
00978 newop->type = SYNCWIN;
00979 newop->param.p.i = fd2->fd;
00980 }
00981 }
00982
00983
00991 void WINFD::Set_click_handler(
00992 EVENT_HANDLER handler
00993 ) {
00994 click_handler = handler;
00995 }
00996
00997
01005 void WINFD::Set_selection_handler(
01006 EVENT_HANDLER handler
01007 ) {
01008 selection_handler = handler;
01009 }
01010
01011
01019 void WINFD::Set_key_handler(
01020 EVENT_HANDLER handler
01021 ) {
01022 key_handler = handler;
01023 }
01024
01025
01033 void WINFD::Set_destroy_handler(
01034 EVENT_HANDLER handler
01035 ) {
01036 destroy_handler = handler;
01037 }
01038
01039 #ifdef WXSBSERVANT
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01054
01055
01056 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
01057 #include "mondrian.xpm"
01058 #endif
01059
01060
01061
01062
01063
01064
01065
01066 enum ScreenToShow
01067 {
01068 Show_Default,
01069 Show_Text,
01070 Show_Lines,
01071 Show_Brushes,
01072 Show_Polygons,
01073 Show_Mask,
01074 Show_Ops,
01075 Show_Regions,
01076 Show_Circles,
01077 Show_Splines
01078 };
01079
01080
01081
01082
01083 extern class MyCanvas
01084
01085 void MyCanvas::DrawTestBrushes(wxDC& dc) {
01086 static const wxCoord WIDTH = 200;
01087 static const wxCoord HEIGHT = 80;
01088
01089 wxCoord x = 10,
01090 y = 10;
01091
01092 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID));
01093 dc.DrawRectangle(x, y, WIDTH, HEIGHT);
01094 dc.DrawText(_T("Solid green"), x + 10, y + 10);
01095
01096
01097 }
01098
01099 void MyCanvas::DrawTestPoly(wxDC& dc)
01100 {
01101 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH);
01102 dc.SetBrush(brushHatch);
01103
01104 wxPoint star[5];
01105 star[0] = wxPoint(100, 60);
01106 star[1] = wxPoint(60, 150);
01107 star[2] = wxPoint(160, 100);
01108 star[3] = wxPoint(40, 100);
01109 star[4] = wxPoint(140, 150);
01110
01111 dc.DrawText(_T("You should see two (irregular) stars below, the left one ")
01112 _T("hatched"), 10, 10);
01113 dc.DrawText(_T("except for the central region and the right ")
01114 _T("one entirely hatched"), 10, 30);
01115 dc.DrawText(_T("The third star only has a hatched outline"), 10, 50);
01116
01117 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30);
01118 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE);
01119
01120 }
01121
01122 void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
01123 {
01124 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) );
01125 dc.SetBrush( *wxRED_BRUSH );
01126 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10);
01127 dc.DrawRectangle( x+10, y+10, 100, 190 );
01128
01129 }
01130
01131 void MyCanvas::DrawDefault(wxDC& dc)
01132 {
01133
01134 dc.DrawCircle(0, 0, 10);
01135
01136 #ifdef wxMAC_USE_CORE_GRAPHICS
01137 #if !wxMAC_USE_CORE_GRAPHICS
01138
01139
01140
01141 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
01142
01143 wxColour tmpColour ;
01144 dc.GetPixel(1,1, &tmpColour);
01145 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
01146 #endif
01147 #endif// wxMAC_USE_CORE_GRAPHICS
01148
01149 dc.DrawCheckMark(5, 80, 15, 15);
01150 dc.DrawCheckMark(25, 80, 30, 30);
01151 dc.DrawCheckMark(60, 80, 60, 60);
01152
01153 }
01154
01155 void MyCanvas::DrawText(wxDC& dc)
01156 {
01157
01158 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, true) );
01159 dc.DrawText( _T("This is text"), 110, 10 );
01160 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
01161
01162
01163
01164 dc.SetFont( *wxSWISS_FONT );
01165
01166 wxString text;
01167 dc.SetBackgroundMode(wxTRANSPARENT);
01168
01169 for ( int n = -180; n < 180; n += 30 )
01170 {
01171 text.Printf(wxT(" %d rotated text"), n);
01172 dc.DrawRotatedText(text , 400, 400, n);
01173 }
01174
01175 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
01176
01177 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
01178
01179 }
01180
01181 static const struct
01182 {
01183 const wxChar *name;
01184 int rop;
01185 } rasterOperations[] =
01186 {
01187 { wxT("wxAND"), wxAND },
01188 { wxT("wxAND_INVERT"), wxAND_INVERT },
01189 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
01190 { wxT("wxCLEAR"), wxCLEAR },
01191 { wxT("wxCOPY"), wxCOPY },
01192 { wxT("wxEQUIV"), wxEQUIV },
01193 { wxT("wxINVERT"), wxINVERT },
01194 { wxT("wxNAND"), wxNAND },
01195 { wxT("wxNO_OP"), wxNO_OP },
01196 { wxT("wxOR"), wxOR },
01197 { wxT("wxOR_INVERT"), wxOR_INVERT },
01198 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
01199 { wxT("wxSET"), wxSET },
01200 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
01201 { wxT("wxXOR"), wxXOR },
01202 };
01203
01204 void MyCanvas::DrawImages(wxDC& dc)
01205 {
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 }
01231
01232 void MyCanvas::DrawWithLogicalOps(wxDC& dc) {
01233 static const wxCoord w = 60;
01234 static const wxCoord h = 60;
01235
01236
01237 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
01238 dc.SetBrush(*wxTRANSPARENT_BRUSH);
01239
01240 size_t n;
01241 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ ) {
01242 wxCoord x = 20 + 150*(n%4),
01243 y = 20 + 100*(n/4);
01244
01245 dc.DrawText(rasterOperations[n].name, x, y - 20);
01246 dc.SetLogicalFunction(rasterOperations[n].rop);
01247 dc.DrawRectangle(x, y, w, h);
01248 dc.DrawLine(x, y, x + w, y + h);
01249 dc.DrawLine(x + w, y, x, y + h);
01250 }
01251
01252 }
01253
01254 void MyCanvas::DrawCircles(wxDC& dc)
01255 {
01256 int x = 100,
01257 y = 100,
01258 r = 20;
01259
01260 dc.DrawText(_T("Some circles"), 0, y);
01261 dc.DrawCircle(x, y, r);
01262 dc.DrawCircle(x + 2*r, y, r);
01263 dc.DrawCircle(x + 4*r, y, r);
01264
01265 }
01266
01267 void MyCanvas::DrawSplines(wxDC& dc)
01268 {
01269 #if wxUSE_SPLINES
01270 dc.DrawText(_T("Some splines"), 10, 5);
01271
01272
01273
01274
01275
01276
01277 const int R = 300;
01278 const wxPoint center( R + 20, R + 20 );
01279 const int angles[7] = { 0, 10, 33, 77, 13, 145, 90 };
01280 const int radii[5] = { 100 , 59, 85, 33, 90 };
01281 const int n = 200;
01282 wxPoint pts[n];
01283
01284
01285 unsigned int radius_pos = 0;
01286 unsigned int angle_pos = 0;
01287 int angle = 0;
01288 for ( int i = 0; i < n; i++ )
01289 {
01290 angle += angles[ angle_pos ];
01291 int r = R * radii[ radius_pos ] / 100;
01292 pts[ i ].x = center.x + (wxCoord)( r * cos( M_PI * angle / 180.0) );
01293 pts[ i ].y = center.y + (wxCoord)( r * sin( M_PI * angle / 180.0) );
01294
01295 angle_pos++;
01296 if ( angle_pos >= WXSIZEOF(angles) ) angle_pos = 0;
01297
01298 radius_pos++;
01299 if ( radius_pos >= WXSIZEOF(radii) ) radius_pos = 0;
01300 }
01301
01302
01303 dc.SetPen(*wxRED_PEN);
01304 dc.DrawSpline(WXSIZEOF(pts), pts);
01305
01306
01307 wxPoint letters[4][5];
01308
01309 letters[0][0] = wxPoint( 0,1);
01310 letters[0][1] = wxPoint( 1,3);
01311 letters[0][2] = wxPoint( 2,2);
01312 letters[0][3] = wxPoint( 3,3);
01313 letters[0][4] = wxPoint( 4,1);
01314
01315 letters[1][0] = wxPoint( 5,1);
01316 letters[1][1] = wxPoint( 6,1);
01317 letters[1][2] = wxPoint( 7,2);
01318 letters[1][3] = wxPoint( 8,3);
01319 letters[1][4] = wxPoint( 9,3);
01320
01321 letters[2][0] = wxPoint( 5,3);
01322 letters[2][1] = wxPoint( 6,3);
01323 letters[2][2] = wxPoint( 7,2);
01324 letters[2][3] = wxPoint( 8,1);
01325 letters[2][4] = wxPoint( 9,1);
01326
01327 letters[3][0] = wxPoint(10,0);
01328 letters[3][1] = wxPoint(11,3);
01329 letters[3][2] = wxPoint(12,1);
01330 letters[3][3] = wxPoint(13,3);
01331 letters[3][4] = wxPoint(14,0);
01332
01333 const int dx = 2 * R / letters[3][4].x;
01334 const int h[4] = { -R/2, 0, R/4, R/2 };
01335
01336 for ( int m = 0; m < 4; m++ )
01337 {
01338 for ( int n = 0; n < 5; n++ )
01339 {
01340 letters[m][n].x = center.x - R + letters[m][n].x * dx;
01341 letters[m][n].y = center.y + h[ letters[m][n].y ];
01342 }
01343
01344 dc.SetPen( wxPen( wxT("blue"), 1, wxDOT) );
01345 dc.DrawLines(5, letters[m]);
01346 dc.SetPen( wxPen( wxT("black"), 4, wxSOLID) );
01347 dc.DrawSpline(5, letters[m]);
01348 }
01349
01350 #else
01351 dc.DrawText(_T("Splines not supported."), 10, 5);
01352 #endif
01353 }
01354
01355 void MyCanvas::DrawRegions(wxDC& dc)
01356 {
01357 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
01358 _T("on the left"), 10, 5);
01359 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
01360 10, 5 + dc.GetCharHeight());
01361 dc.DrawText(_T("The second copy should be identical but right part of it ")
01362 _T("should be offset by 10 pixels."),
01363 10, 5 + 2*dc.GetCharHeight());
01364
01365 DrawRegionsHelper(dc, 10, true);
01366 DrawRegionsHelper(dc, 350, false);
01367 }
01368
01369 void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
01370 {
01371 wxCoord y = 100;
01372
01373 dc.DestroyClippingRegion();
01374 dc.SetBrush( *wxWHITE_BRUSH );
01375 dc.SetPen( *wxTRANSPARENT_PEN );
01376 dc.DrawRectangle( x, y, 310, 310 );
01377
01378 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
01379
01380 dc.SetBrush( *wxRED_BRUSH );
01381 dc.DrawRectangle( x, y, 310, 310 );
01382
01383 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
01384
01385 dc.SetBrush( *wxCYAN_BRUSH );
01386 dc.DrawRectangle( x, y, 310, 310 );
01387
01388 dc.DestroyClippingRegion();
01389
01390 wxRegion region(x + 110, y + 20, 100, 270);
01391 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
01392 if ( !firstTime )
01393 region.Offset(10, 10);
01394 #endif
01395 dc.SetClippingRegion(region);
01396
01397 dc.SetBrush( *wxGREY_BRUSH );
01398 dc.DrawRectangle( x, y, 310, 310 );
01399
01400 if (m_smile_bmp.Ok()) {
01401 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, true );
01402 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, true );
01403 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, true );
01404 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, true );
01405 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, true );
01406 }
01407 }
01408
01409 void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
01410 {
01411 wxPaintDC dc(this);
01412 PrepareDC(dc);
01413
01414 m_owner->PrepareDC(dc);
01415
01416 dc.SetBackgroundMode( m_owner->m_backgroundMode );
01417 if ( m_owner->m_backgroundBrush.Ok() )
01418 dc.SetBackground( m_owner->m_backgroundBrush );
01419 if ( m_owner->m_colourForeground.Ok() )
01420 dc.SetTextForeground( m_owner->m_colourForeground );
01421 if ( m_owner->m_colourBackground.Ok() )
01422 dc.SetTextBackground( m_owner->m_colourBackground );
01423
01424 if ( m_owner->m_textureBackground) {
01425 if ( ! m_owner->m_backgroundBrush.Ok() ) {
01426 wxColour clr(0,128,0);
01427 wxBrush b(clr, wxSOLID);
01428 dc.SetBackground(b);
01429 }
01430 }
01431
01432 if ( m_clip )
01433 dc.SetClippingRegion(100, 100, 100, 100);
01434
01435 dc.Clear();
01436
01437 if ( m_owner->m_textureBackground ) {
01438 dc.SetPen(*wxMEDIUM_GREY_PEN);
01439 for ( int i = 0; i < 200; i++ ) {
01440 dc.DrawLine(0, i*10, i*10, 0);
01441 }
01442 }
01443
01444 switch ( m_show ) {
01445 case Show_Default:
01446 DrawDefault(dc);
01447 break;
01448
01449 case Show_Circles:
01450 DrawCircles(dc);
01451 break;
01452
01453 case Show_Splines:
01454 DrawSplines(dc);
01455 break;
01456
01457 case Show_Regions:
01458 DrawRegions(dc);
01459 break;
01460
01461 case Show_Text:
01462 DrawText(dc);
01463 break;
01464
01465 case Show_Lines:
01466 DrawTestLines( 0, 100, 0, dc );
01467 DrawTestLines( 0, 320, 1, dc );
01468 DrawTestLines( 0, 540, 2, dc );
01469 DrawTestLines( 0, 760, 6, dc );
01470 break;
01471
01472 case Show_Brushes:
01473 DrawTestBrushes(dc);
01474 break;
01475
01476 case Show_Polygons:
01477 DrawTestPoly(dc);
01478 break;
01479
01480 case Show_Mask:
01481 DrawImages(dc);
01482 break;
01483
01484 case Show_Ops:
01485 DrawWithLogicalOps(dc);
01486 break;
01487 }
01488 }
01489
01490 void MyCanvas::OnMouseMove(wxMouseEvent &event)
01491 {
01492 #if wxUSE_STATUSBAR
01493 wxClientDC dc(this);
01494 PrepareDC(dc);
01495 m_owner->PrepareDC(dc);
01496
01497 wxPoint pos = event.GetPosition();
01498 long x = dc.DeviceToLogicalX( pos.x );
01499 long y = dc.DeviceToLogicalY( pos.y );
01500 wxString str;
01501 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
01502 m_owner->SetStatusText( str );
01503 #else
01504 wxUnusedVar(event);
01505 #endif // wxUSE_STATUSBAR
01506 }
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 #endif //WXSBSERVANT