For Programmers: Free Programming Magazines  


Home > Archive > Tcl > February 2007 > How can one create a widget from scratch and display it ?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How can one create a widget from scratch and display it ?
canvas_remix

2007-02-23, 8:12 am

Hello,

I need to create a widget "mycanvas" from scratch.
It is supposed to be a scaled-down version of the Tk canvas such that
it will serve to draw just the lines/rectangles/text and then forget
about them.
This is being done to have an efficient widget for a specific purpose.
(If somebody has already done such a thing, please point me to it.)

However, with the following code, the widget's 3D box is not drawn on
the screen.
Please help.


typedef struct {
Tk_Window tkwin;
Display *display;
Tcl_Interp *interp;
int x, y;
int size;
int borderWidth;
Tk_3DBorder bgBorder;
Tk_3DBorder fgBorder;
int relief;
GC gc;
int updatePending;
} Mycanvas;

void DisplayMycanvas(ClientData clientData) {

Mycanvas *mycanvasPtr = (Mycanvas *) clientData;
Tk_Window tkwin = mycanvasPtr->tkwin;
Pixmap pix_map;
mycanvasPtr->updatePending = 0;
if (!Tk_IsMapped(tkwin)) {
return;
}

pix_map = XCreatePixmap(
Tk_Display(tkwin),
Tk_WindowId(tkwin),
Tk_Width(tkwin),
Tk_Height(tkwin),
Tk_Depth(tkwin)
);

Tk_Fill3DRectangle(
tkwin,
pix_map,
mycanvasPtr->bgBorder,
0, 0, Tk_Width(tkwin), Tk_Height(tkwin),
mycanvasPtr->borderWidth,
mycanvasPtr->relief
);
Tk_Fill3DRectangle(
tkwin,
pix_map,
mycanvasPtr->fgBorder,
mycanvasPtr->x, mycanvasPtr->y, mycanvasPtr->size, mycanvasPtr-
>size,

mycanvasPtr->borderWidth,
mycanvasPtr->relief
);
XCopyArea(
Tk_Display(tkwin),
pix_map,
Tk_WindowId(tkwin),
mycanvasPtr->gc, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin),
0, 0
);
XFreePixmap(Tk_Display(tkwin), pix_map);
}

int MycanvasCmd STD_TCL_ARGS {
Tk_Window main = (Tk_Window) clientData;
Mycanvas *mycanvasPtr;
Tk_Window tkwin;

if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " pathName ?options?\"", (char *) NULL);
return TCL_ERROR;
}
tkwin = Tk_CreateWindowFromPath(interp, main, argv[1], (char *)
NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
Tk_SetClass(tkwin, "Mycanvas");
mycanvasPtr = (Mycanvas *) malloc(sizeof(Mycanvas));
mycanvasPtr->tkwin = tkwin;
mycanvasPtr->display = Tk_Display(tkwin);
mycanvasPtr->interp = interp;
mycanvasPtr->x = 0;
mycanvasPtr->y = 0;
mycanvasPtr->size = 20;
mycanvasPtr->bgBorder = NULL;
mycanvasPtr->fgBorder = NULL;
mycanvasPtr->gc = None;
mycanvasPtr->updatePending = 0;
#if 0
Tk_CreateEventHandler(tkwin,
ExposureMask|StructureNotifyMask, MycanvasEventProc,
(ClientData) mycanvasPtr);
Tcl_CreateCommand(interp, Tk_PathName(tkwin),
MycanvasWidgetCmd, (ClientData mycanvasPtr),
(Tcl_CmdDeleteProc *) NULL);
if (ConfigureMycanvas(interp, mycanvasPtr, argc-2, argv+2, 0)
!= TCL_OK) {
Tk_DestroyWindow(mycanvasPtr->tkwin);
return TCL_ERROR;
}
#endif
interp->result = Tk_PathName(tkwin);
Tk_DoWhenIdle(DisplayMycanvas, mycanvasPtr);
return TCL_OK;
}



>From the tcl side, I give the commands


toplevel .t
mycanvas .t.c
pack .t.c

Georgios Petasis

2007-02-23, 7:14 pm

Its difficult to tell, since not all code is there.
Have you defined a specs array and use Tk_CreateOptionTable to
initialise it? If not, then it is probable that your border
is NULL, and thus you get no border at all.

As an example you can see a small clock widget in C in:

http://wiki.tcl.tk/15946

I remember that there was a simpler widget in C somewhere, a box that
only had a border. But I failed to locate it :-)

George


O/H canvas_remix _γραψε:
> Hello,
>
> I need to create a widget "mycanvas" from scratch.
> It is supposed to be a scaled-down version of the Tk canvas such that
> it will serve to draw just the lines/rectangles/text and then forget
> about them.
> This is being done to have an efficient widget for a specific purpose.
> (If somebody has already done such a thing, please point me to it.)
>
> However, with the following code, the widget's 3D box is not drawn on
> the screen.
> Please help.
>
>
> typedef struct {
> Tk_Window tkwin;
> Display *display;
> Tcl_Interp *interp;
> int x, y;
> int size;
> int borderWidth;
> Tk_3DBorder bgBorder;
> Tk_3DBorder fgBorder;
> int relief;
> GC gc;
> int updatePending;
> } Mycanvas;
>
> void DisplayMycanvas(ClientData clientData) {
>
> Mycanvas *mycanvasPtr = (Mycanvas *) clientData;
> Tk_Window tkwin = mycanvasPtr->tkwin;
> Pixmap pix_map;
> mycanvasPtr->updatePending = 0;
> if (!Tk_IsMapped(tkwin)) {
> return;
> }
>
> pix_map = XCreatePixmap(
> Tk_Display(tkwin),
> Tk_WindowId(tkwin),
> Tk_Width(tkwin),
> Tk_Height(tkwin),
> Tk_Depth(tkwin)
> );
>
> Tk_Fill3DRectangle(
> tkwin,
> pix_map,
> mycanvasPtr->bgBorder,
> 0, 0, Tk_Width(tkwin), Tk_Height(tkwin),
> mycanvasPtr->borderWidth,
> mycanvasPtr->relief
> );
> Tk_Fill3DRectangle(
> tkwin,
> pix_map,
> mycanvasPtr->fgBorder,
> mycanvasPtr->x, mycanvasPtr->y, mycanvasPtr->size, mycanvasPtr-
> mycanvasPtr->borderWidth,
> mycanvasPtr->relief
> );
> XCopyArea(
> Tk_Display(tkwin),
> pix_map,
> Tk_WindowId(tkwin),
> mycanvasPtr->gc, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin),
> 0, 0
> );
> XFreePixmap(Tk_Display(tkwin), pix_map);
> }
>
> int MycanvasCmd STD_TCL_ARGS {
> Tk_Window main = (Tk_Window) clientData;
> Mycanvas *mycanvasPtr;
> Tk_Window tkwin;
>
> if (argc < 2) {
> Tcl_AppendResult(interp, "wrong # args: should be \"",
> argv[0], " pathName ?options?\"", (char *) NULL);
> return TCL_ERROR;
> }
> tkwin = Tk_CreateWindowFromPath(interp, main, argv[1], (char *)
> NULL);
> if (tkwin == NULL) {
> return TCL_ERROR;
> }
> Tk_SetClass(tkwin, "Mycanvas");
> mycanvasPtr = (Mycanvas *) malloc(sizeof(Mycanvas));
> mycanvasPtr->tkwin = tkwin;
> mycanvasPtr->display = Tk_Display(tkwin);
> mycanvasPtr->interp = interp;
> mycanvasPtr->x = 0;
> mycanvasPtr->y = 0;
> mycanvasPtr->size = 20;
> mycanvasPtr->bgBorder = NULL;
> mycanvasPtr->fgBorder = NULL;
> mycanvasPtr->gc = None;
> mycanvasPtr->updatePending = 0;
> #if 0
> Tk_CreateEventHandler(tkwin,
> ExposureMask|StructureNotifyMask, MycanvasEventProc,
> (ClientData) mycanvasPtr);
> Tcl_CreateCommand(interp, Tk_PathName(tkwin),
> MycanvasWidgetCmd, (ClientData mycanvasPtr),
> (Tcl_CmdDeleteProc *) NULL);
> if (ConfigureMycanvas(interp, mycanvasPtr, argc-2, argv+2, 0)
> != TCL_OK) {
> Tk_DestroyWindow(mycanvasPtr->tkwin);
> return TCL_ERROR;
> }
> #endif
> interp->result = Tk_PathName(tkwin);
> Tk_DoWhenIdle(DisplayMycanvas, mycanvasPtr);
> return TCL_OK;
> }
>
>
>
>
> toplevel .t
> mycanvas .t.c
> pack .t.c
>

Aric Bills

2007-02-23, 7:14 pm

> I remember that there was a simpler widget in C somewhere, a box that
> only had a border. But I failed to locate it :-)
>
> George


Could this be it?

http://wiki.tcl.tk/7855

Georgios Petasis

2007-02-24, 4:20 am

O/H Aric Bills _γραψε:
>
> Could this be it?
>
> http://wiki.tcl.tk/7855
>


Yes, this is it :-)

George
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com