|
Post by alexfish on Dec 4, 2022 22:23:16 GMT 1
Hi All Not absolute on this one
Removed
|
|
|
Post by alexfish on Dec 5, 2022 11:59:57 GMT 1
Geo Location these bits are from Navigation app , it works on openstreetmap cords & zoom in principal it gives the location of a piece of map should be in a directory
here this gives the location of the file in the directory
then gives the gps location within the square 256*256
this is a fresh cut from the original app + needs more work
HaveFun + BR Alex
OPTION PARSE FALSE
USEH #if FLT_RADIX == 2 #define LOG2(x) (ilogb(x)) #else #define LOG2(x) ((int)floor(log2(abs(x)))) #endif ENDUSEH
DECLARE SCR_ROWS , SCR_COLS,SCR_W_CENTER,SCR_H_CENTER,LOC_X,LOC_Y DECLARE home_lat, home_lon TYPE double DECLARE zoom = 17 TYPE int DECLARE IDX, IDY TYPE int DECLARE IDLAT, IDLON TYPE double DECLARE IDLAT2, IDLON2 TYPE double DECLARE MAPMAX_X, MAPMAX_Y TYPE int
DEF FN ASINH = asinh DEF FN ATAN = atan 'radius at equater DEF FN OSM_EQ_RADIUS = 6378137.0 DEF FN ISNAN = isnan DECLARE OSMDIR$ TYPE STRING DEF FN DEG2RAD(deg) = (deg * M_PI / 180.0) DEF FN RAD2DEG(rad) = (rad / M_PI * 180.0) DECLARE slippy_xpos =0 TYPE int DECLARE slippy_ypos =0 TYPE int
' =================================== FUNCTION LONDEG2LONMIN ( float lon) TYPE STRING ' ===================================
LOCAL lonmin[20] TYPE static char LOCAL degrees TYPE int LOCAL minutes TYPE float
degrees = (abs( (lon>0) ? floor(lon) : ceil(lon) )) minutes = ((fabs(lon) - (float)degrees) * 60)
sprintf (lonmin,"%d°%.3f' %s",degrees,minutes,(lon>0) ? "E" : "W")
RETURN lonmin
END FUNCTION
' ================================= FUNCTION LATDEG2LATMIN (float lat) TYPE STRING ' =================================
LOCAL latmin[20] TYPE static char LOCAL degrees TYPE int LOCAL minutes TYPE float
degrees = (abs( (lat>0) ? floor(lat) : ceil(lat) )) minutes = ((fabs(lat) - (float)degrees) * 60)
sprintf (latmin,"%d°%.3f' %s", degrees,minutes,(lat>0) ? "N" : "S")
RETURN latmin
END FUNCTION
' ================================= FUNCTION LATDEG2LATSEC(float lat) TYPE STRING ' =================================
LOCAL latsec[20] TYPE static char LOCAL degrees, full_minutes TYPE int LOCAL minutes, seconds TYPE float
degrees = abs( (lat>0) ? floor(lat) : ceil(lat) ) minutes = (fabs(lat) - (float)degrees) * 60 full_minutes = floor(minutes) seconds = (minutes - (float)full_minutes) * 60
sprintf( latsec,"%d°%d'%.2f\" %s", degrees,full_minutes,seconds,(lat>0) ? "N" : "S")
RETURN latsec END FUNCTION
' ================================== FUNCTION LONDEG2LONSEC ( float lon) TYPE STRING ' ==================================
LOCAL lonmin[20] TYPE static char LOCAL degrees, full_minutes TYPE int LOCAL minutes, seconds TYPE float
degrees = (abs( (lon>0) ? floor(lon) : ceil(lon) )) minutes = ((fabs(lon) - (float)degrees) * 60) full_minutes = (floor(minutes)) seconds = ((minutes - (float)full_minutes) * 60)
sprintf(lonmin,"%d°%d'%.2f\" %s",degrees,full_minutes,seconds,(lon>0) ? "E" : "W")
RETURN lonmin
END FUNCTION
' ========================================================= FUNCTION GET_DISTANCE (double lat1, double lon1, double lat2, double lon2) TYPE float ' =========================================================
LOCAL distance = 0 TYPE double LOCAL tmp TYPE double
tmp = sin(DEG2RAD(lat1)) * sin(DEG2RAD(lat2)) + cos(DEG2RAD(lat1)) * cos(DEG2RAD(lat2)) * cos(DEG2RAD(lon2) - DEG2RAD(lon1))
distance = (6371.0 * acos(tmp))
RETURN distance
END FUNCTION
' ======================================================== FUNCTION GET_BEARING(double lat1, double lon1, double lat2, double lon2) TYPE float ' ======================================================== LOCAL bearing, tmp TYPE double
tmp = atan2(sin(DEG2RAD(lon2)-DEG2RAD(lon1)) * cos(DEG2RAD(lat2)), \ cos(DEG2RAD(lat1)) * sin(DEG2RAD(lat2)) - \ sin(DEG2RAD(lat1)) * cos(DEG2RAD(lat2)) * cos(DEG2RAD(lon2)-DEG2RAD(lon1)) )
bearing = ((tmp < 0) ? tmp + M_PI*2 : tmp)
RETURN RAD2DEG(bearing)
END FUNCTION
FUNCTION LONG_TO_PIX(int ZOOM, double longditude) TYPE int LOCAL TILE_X TYPE int TILE_X = (int)(FLOOR(( longditude +180.0) /360 *(1 << ZOOM))) RETURN TILE_X
END FUNCTION
' ===================================================== FUNCTION LAT_TO_PIX(int ZOOM, double latitude) TYPE int
LOCAL TILE_Y TYPE int LOCAL LAT_RAD TYPE double
LAT_RAD = latitude * PI / 180
TILE_Y = (int)FLOOR( (1.0 - ASINH(TAN(LAT_RAD)) / PI) / 2.0 * (1 << ZOOM)) RETURN TILE_Y
END FUNCTION
' ===================================================== FUNCTION TILE_X_TO_LONG(int x, int z) TYPE double
RETURN x / (double)(1 << z) * 360.0 - 180
END FUNCTION
' ===================================================== FUNCTION TILE_Y_TO_LAT(int y, int z) TYPE double
LOCAL n TYPE double n = PI - 2.0 * PI * y / (double)(1 << z) RETURN 180.0 / PI * ATAN(0.5 * (exp(n) - exp(-n)))
END FUNCTION ' =====================================================
FUNCTION CHECK_NAN(float numb) TYPE STRING IF ( ISNAN(numb)) THEN RETURN "NAN" ELSE RETURN STR$(numb) END IF END FUNCTION
SUB Test() LOCAL tileXlon, tileYlat LOCAL tileXlon2, tileYlat2 'LATDEG2LATMIN B$ = LATDEG2LATMIN (home_lat) 'PRINT "lat : " , B$ C$ = LONDEG2LONMIN (home_lon) 'PRINT "lon :", C$ LOCAL Cord$ TYPE STRING Cords$ = B$ & " " & C$
tileYlat = LAT_TO_PIX(zoom,home_lat) tileXlon= LONG_TO_PIX(zoom,home_lon) LOCAL X_LON_1, X_LON_2 TYPE double LOCAL Y_LAT_1, Y_LAT_2 TYPE double '==============================
X_LON_1 = TILE_X_TO_LONG(tileXlon,zoom) Y_LAT_1 = TILE_Y_TO_LAT(tileYlat,zoom)
LOCAL BEARING , BEARING2 TYPE double BEARING =GET_BEARING(home_lat,home_lon, Y_LAT_1, X_LON_1)
'PRINT "Look at : " , tileXlon, " : ", tileXlon+1 X_LON_2 = TILE_X_TO_LONG(tileXlon+1,zoom) Y_LAT_2 = TILE_Y_TO_LAT(tileYlat,zoom)
'PRINT "Results TOP Left :" , Y_LAT_1, " : ", X_LON_1 , " Bearing :" , BEARING 'PRINT "Results TOP Right :" , Y_LAT_2, " : ", X_LON_2 , " Bearing :" , BEARING
LOCAL DISTANCE,DISTANCE2, DISTANCE3 , DISTANCE4 TYPE float DISTANCE = GET_DISTANCE (Y_LAT_1, X_LON_1, Y_LAT_2, X_LON_2 ) 'PRINT "Dist : ", DISTANCE
BEARING2 = GET_BEARING (home_lat,home_lon, Y_LAT_2, X_LON_2)
'PRINT "BEARING2 :" , BEARING2 LOCAL scaler , scaler2,scaler3 , scaler4 TYPE double
DISTANCE2 = GET_DISTANCE(Y_LAT_1, X_LON_1, Y_LAT_1, home_lon ) X_LON_2 = TILE_X_TO_LONG(tileXlon,zoom) Y_LAT_2 = TILE_Y_TO_LAT(tileYlat+1,zoom) scaler = 256 / DISTANCE scaler2 =scaler * DISTANCE2
DISTANCE3=GET_DISTANCE(Y_LAT_1,X_LON_1, Y_LAT_2,X_LON_2) scaler3 = 256 / DISTANCE3 DISTANCE4 = GET_DISTANCE(Y_LAT_1, X_LON_1,home_lat,X_LON_1 ) scaler4 =scaler3 * DISTANCE4
'printf("dist %f\n ",DISTANCE2) PRINT "N Down sq 256: ", (slippy_ypos+IDY)+scaler4) PRINT "W Right sq 256: " ,(slippy_xpos+IDX+scaler2) END SUB '======================================================= SUB TestInit()
LOCAL filename$ = OSMDIR$ TYPE STRING LOCAL filename2$ = OSMDIR$ TYPE STRING 'PRINT "INIT Position = " , home_lat , " : " , home_lon LOCAL tileXlon, tileYlat LOCAL tmp$ TYPE STRING tileYlat = LAT_TO_PIX(zoom,home_lat) tileXlon= LONG_TO_PIX(zoom,home_lon) PRINT "/",zoom,"/",tileYlat, "/",tileXlon END SUB '======================================================= home_lat = 54.48774 home_lon = -0.61498 TestInit() Test()
|
|
|
Post by alexfish on Dec 5, 2022 18:32:58 GMT 1
How would the above equate to a canvas Depends if not using maps per say then can start at zoom level 0 = 1 map make the scalers width & height to the canvas size : start with a square canvas IE change the 256 DISTANCE2 = GET_DISTANCE(Y_LAT_1, X_LON_1, Y_LAT_1, home_lon ) X_LON_2 = TILE_X_TO_LONG(tileXlon,zoom) Y_LAT_2 = TILE_Y_TO_LAT(tileYlat+1,zoom) scaler = 256 / DISTANCE scaler2 =scaler * DISTANCE2
DISTANCE3=GET_DISTANCE(Y_LAT_1,X_LON_1, Y_LAT_2,X_LON_2) scaler3 = 256 / DISTANCE3 DISTANCE4 = GET_DISTANCE(Y_LAT_1, X_LON_1,home_lat,X_LON_1 ) scaler4 =scaler3 * DISTANCE4
in real terms have not checked speed or whatever as you get to the poles hope you get the picture ADDED Center Tile ( bounding box) all bits are Arbitrary , can play with the over '================================== LOCAL zoom LOCAL canvasW,canvasH,Wcbbox,Hcbbox canvasW = 1000 canvasH = 800
Wcbbox = canvasW/2 Hcbbox = canvasH/2 tileY = 800 tileX = 600 LOCAL ptry , ptrx, tiles, over PRINT Wcbbox/256 , "x" ,Hcbbox/256 zoom = 5 over = 0 FOR X = tileX - (Wcbbox/256 + over ) TO tileX + (Wcbbox/256 + over) FOR Y = tileY - (Hcbbox/256 + over) TO tileY + (Hcbbox/256 + over) PRINT "/",zoom,"/",Y,"/",X,".png" PRINT "......................" PRINT "pos " , ptry , ":" , ptrx PRINT "......................" PRINT Y,":" ,X INCR ptry,256 INCR tiles NEXT ptry=0 PRINT "=======================================" INCR ptrx,256 NEXT
PRINT " tiles = ", tiles PRINT "my box x pos = " , Wcbbox-256/2 PRINT "my box y pos = " , Hcbbox-256/2 To center the gps position use the SCALER 2 & 4 for all other position then they are plotted where they need to be Added BBBOX example IF use gps change to double/float RECORD BB_MAPBOX LOCAL north LOCAL south LOCAL west LOCAL east LOCAL zoom '============= ' rest of bits here END RECORD BR Alex info from openstreetmap wiki.openstreetmap.org/wiki/Zoom_levels Level # Tiles Tile width (° of longitudes) m / pixel (on Equator) ~ Scale (on screen) 00 000 000 000 001 360.0000 156 412.000 1:500 million << one map 01 000 000 000 004 180.0000 078 206.000 1:250 million << four maps 02 000 000 000 016 090.0000 039 103.000 1:150 million << 16 maps
Possible best link wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_ScaleREAD NEXT POST
|
|
|
Post by alexfish on Dec 6, 2022 19:03:57 GMT 1
REFERENCE TO ABOVE POST
In Simplified Terms of the Canvas
IS ODD OR EVEN
here is a WINDOW/CANVAS EVEN/4units WIDE ODD/3units HEIGH
hug code
INCLUDE hug.bac
HUGOPTIONS("NOSCALING") win = WINDOW("test ",256*4,256*3) can = CANVAS(256*4,256*3) ATTACH (win,can,0,0)
FOR xt = 0 TO 256*5 STEP 256 FOR yt = 0 TO 256*3 STEP 256
SQUARE("#0000FF",xt-(256/2),yt,256,256,0) NEXT NEXT
DISPLAY
+ from that stand point also needed are the (Scaler values 2 and 4) to recenter as in gps terms your position
API wise tile lat lon is easy
home_lat = 54.48774 home_lon = -0.61498 tileYlat = LAT_TO_PIX(zoom,home_lat) tileXlon = LONG_TO_PIX(zoom,home_lon)
the scaler dist2 and 4 has been FUNCTIONED
FUNCTION GET_SCALER_POS(double lat,double lon,int zoom ,int option) TYPE double
option 0 returns N down else Return w:leftside of rect distance to the east:right Thus enabling any gps position to be plotted The distance between two gps coords is already in the lib
FUNCTION GET_DISTANCE (double lat1, double lon1, double lat2, double lon2) TYPE float BR Alex Thats a Wrap for Geo
UPDATED: Finding after Geo.bac testing ,Minimum ZOOM = 1 : 4 maps. Max Zoom for osm maps = 19
|
|
|
Post by rikky on Dec 7, 2022 16:01:47 GMT 1
Soo ... I'm very busy elsewhere, and I'm not rely interested in Gui's at the moment, so I nearly missed this one. Super handy. Thanks. My navigation software is already packed with your routines, so this one is one next. I have the Server improved to something that apparently never crashes, ever. And I'm working on the html chart now for the third time or so. If I have something decent I will report something. But don't expect too much for the next weeks or so.
|
|
|
Post by alexfish on Dec 8, 2022 13:41:02 GMT 1
Hi All Final bit for pure pixbuf LINE Simple Demo start pos 0,0 THEN TO xx2,yy2 ,in positive , if go minus = pop goes the weasel. SUB PUT_PIXEL_RGBA(long pixbuf,int x,int y,unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha)
LOCAL pixels,p TYPE unsigned char* LOCAL width,height,rowstride,n_channels
' check x y fits width & heigh before getting to here 'width = gdk_pixbuf_get_width (pixbuf) 'height = gdk_pixbuf_get_height (pixbuf)
rowstride = gdk_pixbuf_get_rowstride (pixbuf) n_channels = gdk_pixbuf_get_n_channels (pixbuf) pixels = gdk_pixbuf_get_pixels (pixbuf) ' // The pixel we wish to modify p = pixels + y * rowstride + x * n_channels
p[0] = red p[1] = green p[2] = blue p[3] = alpha
END SUB
HOME$ = GETENVIRON$("HOME") LOCAL xx1,xx2,yy1,yy2,dx,dy TYPE float 'Start pos LINE xx1 = 0 yy1= 0 'End pos LINE xx2 = 100 yy2 = 50 '================================================================= pixy = gdk_pixbuf_new(0,TRUE,8,xx2,yy2) dx = xx2 - xx1 dy = yy2 - yy1 FOR xt = xx1 TO xx2 yy = yy1+ dy * (xt-xx1) / dx PUT_PIXEL_RGBA(pixy, xt,yy, 255,0,0,255) NEXT
gdk_pixbuf_save (pixy,HOME$ & "/testall.png", "png", 0, NULL, NULL, NULL) g_object_unref(pixy) That's another Wrap & the final one. Update to lib: notify here when ready BR Alex Main Item :: rehash of event image : visit HEREImport Spec IMPORT "gtk_event_box_set_visible_window (long,int)" FROM GTK$ TYPE void ' ------------------ FUNCTION CANVAS_IMAGE_NEW(int hug_xsize, int hug_ysize) ' ------------------ LOCAL image, ebox image = gtk_image_new() ebox = gtk_event_box_new() gtk_event_box_set_visible_window(ebox,FALSE) ' add image to event box gtk_container_add(ebox, image) gtk_widget_set_events(ebox, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK) g_signal_connect_data(ebox, "button-press-event", hug_mouse_event, 20, 0, 0) g_signal_connect_data(ebox, "button-release-event", hug_mouse_event, 0, 0, 0) g_signal_connect_data(ebox, "motion-notify-event", hug_mouse_event, 0, 0, 0) g_signal_connect_data(ebox, "leave-notify-event", hug_mouse_event, 30, 0, 0) IF HUG_WIDGET_SHOW THEN gtk_widget_show_all(ebox) END IF hug_widget_xsize(STR$(ebox)) = hug_xsize hug_widget_ysize(STR$(ebox)) = hug_ysize hug_widget_s_widget(STR$(ebox)) = ebox hug_widget_signal(STR$(ebox)) = 4 hug_widget_type$(STR$(ebox)) = "image" hug_widget_font(STR$(ebox)) = image hug_widget_focus(STR$(ebox)) = image RETURN ebox END FUNCTION Handlers gtk_image_set_from_pixbuf (GtkImage* image,GdkPixbuf* pixbuf) gtk_image_get_pixbuf (GtkImage* image) gtk_image_clear (GtkImage* image)
G_WINDOW REMOVED ADDSUB SUB RESIZE_WIDGET(long hug_widget,int hug_xsize,int hug_ysize) gtk_widget_set_size_request(hug_widget,hug_xsize,hug_ysize) END SUB
|
|
|
Post by alexfish on Dec 9, 2022 21:46:07 GMT 1
Hi All includegtk.bac ready + final wrap
'file includegtk.bac DECLARE hug_widget_xpos ASSOC NUMBER DECLARE hug_widget_ypos ASSOC NUMBER
GTK$= HUGLIB$("gtk") '======================================================================= IMPORT "gtk_fixed_move(long,long,int,int)" FROM GTK$ TYPE void IMPORT "gtk_event_box_set_visible_window (long,int)" FROM GTK$ TYPE void IMPORT "gtk_image_set_from_pixbuf (long,long)" FROM GTK$ TYPE void IMPORT "gtk_image_get_pixbuf (long)" FROM GTK$ TYPE long IMPORT "gtk_image_clear (long)" FROM GTK$ TYPE void IMPORT "gtk_window_get_size(long, int*, int*)" FROM GTK$ TYPE void
'================================================== SUB RESIZEABLE(long hug_widget,int state) gtk_window_set_resizable(hug_widget, state) END SUB '================================================== SUB IMAGE_CLEAR(long hug_widget) LOCAL image image = hug_widget_font(STR$(hug_widget)) gtk_image_clear(image) END SUB '================================================== SUB IMAGE_UPDATE(long hug_widget,long pixbuf) LOCAL image image = hug_widget_font(STR$(hug_widget)) gtk_image_clear(image) gtk_image_set_from_pixbuf (image,pixbuf)
END SUB '================================================== FUNCTION IMAGE_GET_IMAGE_BUF(long hug_widget) TYPE long LOCAL image , pix image = hug_widget_font(STR$(hug_widget)) pix = gtk_image_get_pixbuf(image) RETURN pix END FUNCTION '================================================== FUNCTION CANVAS_IMAGE_NEW(int hug_xsize, int hug_ysize) ' ------------------ LOCAL image, ebox image = gtk_image_new() ebox = gtk_event_box_new() gtk_event_box_set_visible_window(ebox,FALSE) ' add image to event box gtk_container_add(ebox, image) gtk_widget_set_events(ebox, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK) g_signal_connect_data(ebox, "button-press-event", hug_mouse_event,20, 0, 0) g_signal_connect_data(ebox, "button-release-event",hug_mouse_event, 0, 0, 0) ' removed motion IF HUG_WIDGET_SHOW THEN gtk_widget_show_all(ebox) END IF
hug_widget_xsize(STR$(ebox)) = hug_xsize hug_widget_ysize(STR$(ebox)) = hug_ysize hug_widget_s_widget(STR$(ebox)) = ebox hug_widget_signal(STR$(ebox)) = 4 hug_widget_type$(STR$(ebox)) = "image" hug_widget_font(STR$(ebox)) = image hug_widget_focus(STR$(ebox)) = image RETURN ebox END FUNCTION '=================================================== SUB WIDGET_RESIZE(long hug_widget,int hug_xsize,int hug_ysize) gtk_widget_set_size_request(hug_widget,hug_xsize,hug_ysize) hug_widget_xsize(STR$(hug_widget)) = hug_xsize hug_widget_ysize(STR$(hug_widget)) = hug_ysize END SUB '=================================================== SUB WIDGET_SET_POS(long hug_window, long hug_widget, int hug_xpos, int hug_ypos) PRINT "moved" LOCAL layer layer = hug_widget_attach(STR$(hug_window)) gtk_fixed_move(layer,hug_widget,hug_xpos,hug_ypos) hug_widget_xpos(STR$(hug_widget)) = hug_xpos hug_widget_ypos(STR$(hug_widget)) = hug_ypos END SUB '=================================================== FUNCTION WINDOW_GET_SIZE(long hug_window,int state) LOCAL width,height TYPE int gtk_window_get_size (hug_window,& width,&height) IF (state) THEN RETURN height END IF RETURN width END FUNCTION '=================================================== FUNCTION WIDGET_GET_SIZE(long hug_widget,int state) IF (state) THEN RETURN hug_widget_ysize(STR$(hug_widget)) END IF RETURN hug_widget_xsize(STR$(hug_widget)) END FUNCTION '=================================================== FUNCTION WIDGET_GET_POS(long hug_widget,int state) IF (state) THEN RETURN hug_widget_ypos(STR$(hug_widget)) END IF RETURN hug_widget_xpos(STR$(hug_widget)) END FUNCTION
a bit of code
' HUGLIB$ needed for includegtk.bac INCLUDE "hug.bac",INIT,WINDOW,DISPLAY,BUTTON,ATTACH,CALLBACK,HUGLIB$ INCLUDE "includegtk.bac"
INIT
SUB BUTCLICK() LOCAL w,h,xp,yp w = WIDGET_GET_SIZE(but,0) h = WIDGET_GET_SIZE(but,1) xp = WIDGET_GET_POS(but,0) yp = WIDGET_GET_POS(but,1) PRINT "Button ", xp,":",yp PRINT "Button ", w,":",h PRINT WINDOW_GET_SIZE(win,0) PRINT WINDOW_GET_SIZE(win,1) END SUB
win = WINDOW("test ",600,400) RESIZEABLE(win,TRUE)
but = BUTTON("Click resize",100,30) ATTACH(win,but,3,3) ' register widgets pos & or move widget" WIDGET_SET_POS(win,but,60,3)
WIDGET_RESIZE(but,200,30) CALLBACK(but,BUTCLICK)
DISPLAY
Now sorting the cairo,pixbuf,couple of bit for the GDK + final wrap on imager
Not far away
BR Alex
|
|
|
Post by alexfish on Dec 9, 2022 23:42:53 GMT 1
Imager Addition ColorButton with Alpha this give rgb(string) + alpha value Hence matches API color methods Does not like its bits poked, hence the RATTACH IMPORT "gtk_color_button_new(void)" FROM GTK$ TYPE long IMPORT "gtk_color_button_set_use_alpha (long,int)" FROM GTK$ TYPE void
FUNCTION COLOR_BUTTON() LOCAL colorbut colorbut = gtk_color_button_new() gtk_color_button_set_use_alpha(colorbut,TRUE) IF HUG_WIDGET_SHOW THEN gtk_widget_show(colorbut)
WIDGET = colorbut
RETURN colorbut
END FUNCTION
SUB RATTACH (long hug_widget,long hug_child , int hug_xpos,int hug_ypos) LOCAL layer layer = hug_widget_attach(STR$(hug_widget)) gtk_fixed_put(layer, hug_child,hug_xpos,hug_ypos) END SUB + Addition of dec2hex string FUNCTION DEC2HEX$(char dec) TYPE STRING RETURN HEX$(dec) END FUNCTION BR Alex Picky Attachments:
|
|
|
Post by alexfish on Dec 10, 2022 2:36:58 GMT 1
How Close is the Getting Close The Imager is getting a ReWrite Method of Hug widgets becomes INCLUDE "hug.bac",INIT,HUGLIB$,WINDOW,DISPLAY,ATTACH
and is a must to avoid conflict with Hug Canvas drawing commands so things like CIRCLE = object example of code test FUNCTION CIRCLE(STRING color$, STRING alpha$, double hug_xsize, double hug_ysize) TYPE long LOCAL newpix LOCAL x,y,t,i,angle TYPE double newpix = gdk_pixbuf_new(0,TRUE,8,hug_xsize,hug_ysize)
FOR i = 1 TO 360 STEP .05 angle = 2 * PI * i / 360 x = (hug_xsize/2)*SIN(angle) y = (hug_ysize/2)*COS(angle) FOR t = (hug_xsize/2)-x TO (hug_xsize/2)+x PUT_PIXEL_RGBA(newpix,t, (hug_ysize/2)+y,DEC(MID$(color$,2,2)),DEC(MID$(color$,4,2)),DEC(MID$(color$,6,2)),DEC(alpha$) )
NEXT NEXT
RETURN newpix
END FUNCTION
LOCAL pixy pixy = CIRCLE("#FF0000","FF",50,50) win = WINDOW("test imager",300,300) RESIZEABLE(win,TRUE) can1 = CANVAS_IMAGE_NEW(50,50) ATTACH (win,can1,3,33) WIDGET_RESIZE(can1,50,50) WIDGET_SET_POS(win,can1,6,33) IMAGE_UPDATE(can1,pixy) g_object_unref(pixy) DISPLAY
Once the basic commands are in as complete then first post will be updated with the libs BR Alex Time for zzzzzzzd's Picky Attachments:
|
|
|
Post by alexfish on Dec 10, 2022 14:48:26 GMT 1
The Color as in like cairo
use BaCon RECORD
here example of using Color Button api gcol is a rip from BaCon gtk gui
import bits
IMPORT "gtk_color_button_new(void)" FROM GTK$ TYPE long IMPORT "gtk_color_button_set_use_alpha (long,int)" FROM GTK$ TYPE void IMPORT "gtk_color_button_get_alpha (long)" FROM GTK$ TYPE char IMPORT "gtk_color_selection_palette_to_string(long,int)" FROM GTK$ TYPE char* IMPORT "gtk_color_button_get_color(long,long)" FROM GTK$ TYPE void
RECORD RGBA LOCAL ALPHA$ LOCAL RGB$ END RECORD
LOCAL ptr2 TYPE STRING RGBA.ALPHA$ = DEC2HEX$(gtk_color_button_get_alpha (choose)) gdkcol = MEMORY(96) gtk_color_button_get_color(choose, gdkcol) ptr2 = gtk_color_selection_palette_to_string(gdkcol, 1) : RGBA.RGB$ = ptr2 FREE gdkcol
Other RGBA functions
RGBA_SET_NAME$
RGBA_SET_NAME$("yellow","FF") pixy = LINE (0,0,100,100) IMAGE_UPDATE(can2,pixy) g_object_unref(pixy)
And
SUB RGBA_SET_COLOR$(STRING hug_rgb$,STRING hug_alpha$) RGBA.ALPHA$ = hug_alpha$ RGBA.RGB$ = hug_rgb$ END SUB
BR Alex
|
|
|
Post by alexfish on Dec 11, 2022 19:40:18 GMT 1
Hi All Now drilling down on cairo had noted a previous problem with cairo data to pixbuf sitting here if use cairo rgb , colour get reversed , so having to write as bgr, api wise can only have rgb, no alpha , alpha crashes the surface, now look further more or less ready ,apart from confirming the above, see what happens if use alpha in the initial draw/composition Progress picky using GIcons as buttons and Cairo composite surface BR Alex Attachments:
|
|
|
Post by alexfish on Dec 12, 2022 1:27:28 GMT 1
Success pixbuff line then Pixpuff alpha circle Cairo text Cairo alpha Circle over TODO cairo Circle to surface size , need to reduce radius Still puzzled by the rgba in cairo , found that use BGRA works , if use straight cairo to say x11 or save to file then it has to be RGBA This is in the function cairo cairo_rgba(cr,(char)DEC(MID$(RGBA.RGB$,6,2)),(char)DEC(MID$(RGBA.RGB$,4,2)),(char)DEC(MID$(RGBA.RGB$,2,2)),DEC(RGBA.ALPHA$) )
pixpuf drawing function PUT_PIXEL_RGBA(newpix,xt, yy,DEC(MID$(RGBA.RGB$,2,2)),DEC(MID$(RGBA.RGB$,4,2)),DEC(MID$(RGBA.RGB$,6,2)),DEC(RGBA.ALPHA$) )
There again Ref to the surface used CAIRO_FORMAT_ARGB32 cairo_set_source_rgba
can also read HEREBR Alex Added: the image save as png note the blue and then the red in saved as png yes slightly different , altered the circle algo to fit surface size of further note the converted to pixbuf ,save the same as png = same as the window. Attachments:
|
|
|
Post by alexfish on Dec 12, 2022 13:28:24 GMT 1
Hi All further to the above & + final wrap since I continue , rename the function vars to avoid conflicts , + need to compare results in the ColorWheel some bits I did note there is that black pix, but only just notable on the outer radius of filled circle (possible 1 to 5% tint alpha wise) depending on color SUB cairo_rgba(long cr,char r,char g,char b,char a) LOCAL R,G,B,A TYPE double R = r/255.0 G = g/255.0 B = b/255.0 A = a/255.0 PRINT R , ":",G,":",B,":" ,A cairo_set_source_rgba(cr , R ,G ,B,A) END SUB Convert to Pixbuf FUNCTION CAIRO2PIXBUF(long csr) ' use to do this then remap pix by pix 'pbuf = gdk_pixbuf_get_from_drawable(NULL, pmap,gdk_colormap_get_system(), 0, 0, 0, 0, (int)image_w, (int)image_h) 'try LOCAL data TYPE unsigned char * data = cairo_image_surface_get_data (csr) LOCAL buf
buf = gdk_pixbuf_new_from_data(data, 0,TRUE,8,cairo_image_surface_get_width(csr), \ cairo_image_surface_get_height(csr),cairo_image_surface_get_stride (csr),0,0) RETURN buf END FUNCTION example of circle,reverse RGB, leave alpha as is SUB CR_CIRCLE(long hug_surface,int hug_xpos, int hug_ypos,double hug_xsize,double hug_ysize,int hug_fill) TYPE long LOCAL cr,radius
IF (hug_xsize < hug_ysize) THEN radius = hug_xsize/2 -4 ELSE radius = hug_ysize/2 -4 END IF cr = cairo_create (hug_surface) cairo_move_to (cr, (hug_xsize/2 + radius)+hug_xpos, (hug_ysize/2)+hug_ypos ) cairo_arc (cr, hug_xsize/2 ,hug_ysize/2, radius,0.0, 2 * M_PI); cairo_rgba(cr,(char)DEC(MID$(RGBA.RGB$,6,2)),(char)DEC(MID$(RGBA.RGB$,4,2)),(char)DEC(MID$(RGBA.RGB$,2,2)),DEC(RGBA.ALPHA$) )
IF hug_fill THEN cairo_fill_preserve (cr) END IF cairo_stroke (cr)
cairo_destroy(cr)
END SUB
ADDED ALPHA there is a big diff here , which is correct, Cairo looks good as in more vibrant, as vovchik would say "Sparkling". Suppose in Some arenas , 'not what its should be' , from where I sit at present It be a bonus or is the PUT_PIXEL method wrong , IE 'Pre multiply ? , will check direct unsigned int buffer Will leave as is for now and update if get a result on the pixbuf PUT. now need to look at another thread RE: Elementary . did some pre multiply there CHECKED IT, values do not change in pixbuf as against the PUT_PIXEL gdk_pixbuf_fill(pixy2,0x1A0000C3) on cairo the rgb changes , slightly Looking at the data The colour shift needs to happen on the get data stage Cancel that one had a fresh look : Final: leave the reversed RGB , this get the correct bits for pixbuf all colors and alpha max out at 195, leaving 1 at level 0 : = val+1 : ratio 255/195 :: 1.30769230769 Then later look at the bits, at least for now have cairo argb in the frame + the glass is only cracked and not broken + Use the below. api will be updated to this If get a fail in final version , the fallback plan is to save to file then reload using pixbuf By For Now BR Alex Final. the adjustments added Now have ranges upto 255, incr 1.3 , but in reality in this type of app. Final Bit+ pic alpha and cols 255 SUB FIX_PIXEL_RGBA(long pixbuf,int x,int y)
LOCAL pixels,p TYPE unsigned char* LOCAL width,height,rowstride,n_channels
width = gdk_pixbuf_get_width (pixbuf) height = gdk_pixbuf_get_height (pixbuf)
rowstride = gdk_pixbuf_get_rowstride (pixbuf) n_channels = gdk_pixbuf_get_n_channels (pixbuf) pixels = gdk_pixbuf_get_pixels (pixbuf)
p = pixels + y * rowstride + x * n_channels
p[0] = p[0] * (unsigned int)1.3 p[1] = p[1] * (unsigned int)1.3 p[2] = p[2] * (unsigned int)1.3 p[3] = p[3] * (unsigned int)1.3
END SUB Attachments:
|
|
|
Post by alexfish on Dec 12, 2022 23:06:46 GMT 1
The API still working on it , but most bits are in place , so just need to shorten to single or double where possible Double = Foo*_*Bar Exception at present is RGBA As it stands now , any surface or pixbufs are handled at the paint stage Hence user does not have to handle g_object_unref(pixbuf) & cairo_surface_flush LOCAL pixy ,cs
win = WINDOW("test imager",400,300)
can1 = CANVAS_IMAGE_NEW(200,200) ATTACH (win,can1,3,40) MOVE(win,can1,6,100)
'Pixbuf RGBA_SET_COLOR$("#FF0000","A6") pixy = CIRCLE(200,200,1) PAINT(can1,pixy)
can2 = CANVAS_IMAGE_NEW(300,300) ATTACH (win,can2,3,40) pixy = LINE (0,0,300,100) MOVE(win,can2,3,40) PAINT(can2,pixy)
'Cairo cs = CS_SURFACE(200,200)
RGBA_SET_NAME$("blue","66") CR_CIRCLE(cs,0,0,200,200,1)
RGBA_SET_COLOR$("#0000FF","FF") CR_TEXT(cs,"Welcome Navodani",4,80,"Monospace",20 ,SLANT_OBLIQUE,WEIGHT_BOLD)
pixy = CAIRO2PIXBUF(cs)
can3 = CANVAS_IMAGE_NEW(50,50) ATTACH (win,can3,3,100) MOVE(win,can3,0,25) PAINT(can3,pixy)
DISPLAY As can see the lower pix buf with cairo argb over the line , can still see the line with this type of composition, not perfect in number of steps but do have 1 to 255 and that is a first for me, In theory should be able to paint the resultant pixbuf into hug canvas,not test that one yet: tested method of bypassing the gdk_pixbuf_new_from_data by using pixbuf_new No multiplier LOCAL data2 , pixels TYPE unsigned char * data = cairo_image_surface_get_data (csr)
LOCAL wt,ht,strid wt = cairo_image_surface_get_width(csr) ht = cairo_image_surface_get_height(csr) PRINT wt,":", ht strid = cairo_image_surface_get_stride (csr) LOCAL pixy,poxy pixy = gdk_pixbuf_new(0,TRUE,8,wt,ht) data2 = cairo_image_surface_get_data (csr) pixels = gdk_pixbuf_get_pixels (pixy) LOCAL p, p2 TYPE unsigned char* FOR yt = 0 TO ht FOR xtt = 0 TO wt
p2 = pixels + yt * strid + xtt * 4 p = data2 + yt * strid + xtt * 4 p2[0]= p[0] p2[1]= p[1] p2[2] = p[2] p2[3] = p[3] NEXT NEXT VIOLA 100% correct , I think says he BR Alex One Step from Home Added:: When did the first step happen, Well , mm ,,mm tweedledum tweedledee mm mm fiddle sticks. May 8, 2015 at 12:14pmyoutube link tweedledeetweedledumAttachments:
|
|
|
Post by alexfish on Dec 13, 2022 0:03:53 GMT 1
And a Conversation with vovchik a few days later but in at least no how to get the endian , have some BaConised ENDIAN Code in one of RPI threads will extract and post on new thread and as a vovchik said it is a long long bit of code , resulted in this , a word of caution latest distro's do not have gtk2 devs :: if going to Install be aware of warning , may affect other apps : advice do not install , else use at own risk so avoid terminal use synaptic. SMILE IF YOU HAVE DONE THAT and to high-lite the problem this code rgb pixbuf pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 200, 200); default here in hug use rgba
#include <gtk/gtk.h>
// gcc test_cairo_gdk_pixbuf.c -o test_cairo_gdk_pixbuf -g -Wall `pkg-config --cflags --libs gtk+-2.0` // http://www.gtkforums.com/viewtopic.php?t=5204
typedef struct _Data Data; struct _Data { GtkWidget *box, *image, *entry; GdkPixbuf *pixbuf; };
static cairo_t *pixbuf_cairo_create(GdkPixbuf *pixbuf); static GdkPixbuf *pixbuf_cairo_destroy(cairo_t *cr, gboolean create_new_pixbuf); static void cb_new_image(GtkButton *button, Data *data); static void cb_update_image(GtkButton *button, Data *data);
/* Key for automated pixbuf updating and destruction */ static const cairo_user_data_key_t pixbuf_key;
/** * pixbuf_cairo_create: * @pixbuf: GdkPixbuf that you wish to wrap with cairo context * * This function will initialize new cairo context with contents of @pixbuf. You * can then draw using returned context. When finished drawing, you must call * pixbuf_cairo_destroy() or your pixbuf will not be updated with new contents! * * Return value: New cairo_t context. When you're done with it, call * pixbuf_cairo_destroy() to update your pixbuf and free memory. */
static cairo_t *pixbuf_cairo_create(GdkPixbuf *pixbuf) { gint width, /* Width of both pixbuf and surface */ height, /* Height of both pixbuf and surface */ p_stride, /* Pixbuf stride value */ p_n_channels, /* RGB -> 3, RGBA -> 4 */ s_stride; /* Surface stride value */ guchar *p_pixels, /* Pixbuf's pixel data */ *s_pixels; /* Surface's pixel data */ cairo_surface_t *surface; /* Temporary image surface */ cairo_t *cr; /* Final context */ g_object_ref(G_OBJECT(pixbuf)); /* Inspect input pixbuf and create compatible cairo surface */ g_object_get(G_OBJECT(pixbuf), "width", &width, "height", &height, "rowstride", &p_stride, "n-channels", &p_n_channels, "pixels", &p_pixels, NULL); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); s_stride = cairo_image_surface_get_stride(surface); s_pixels = cairo_image_surface_get_data(surface); /* Copy pixel data from pixbuf to surface */ while(height--) { gint i; guchar *p_iter = p_pixels, *s_iter = s_pixels; for(i = 0; i < width; i++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN /* Pixbuf: RGB(A) * Surface: BGRA */ if(p_n_channels == 3) { s_iter[0] = p_iter[2]; s_iter[1] = p_iter[1]; s_iter[2] = p_iter[0]; s_iter[3] = 0xff; } else /* p_n_channels == 4 */ { gdouble alpha_factor = p_iter[3] / (gdouble)0xff; s_iter[0] = (guchar)(p_iter[2] * alpha_factor + .5); s_iter[1] = (guchar)(p_iter[1] * alpha_factor + .5); s_iter[2] = (guchar)(p_iter[0] * alpha_factor + .5); s_iter[3] = p_iter[3]; } #elif G_BYTE_ORDER == G_BIG_ENDIAN /* Pixbuf: RGB(A) * Surface: ARGB */ if(p_n_channels == 3) { s_iter[3] = p_iter[2]; s_iter[2] = p_iter[1]; s_iter[1] = p_iter[0]; s_iter[0] = 0xff; } else /* p_n_channels == 4 */ { gdouble alpha_factor = p_iter[3] / (gdouble)0xff; s_iter[3] = (guchar)(p_iter[2] * alpha_factor + .5); s_iter[2] = (guchar)(p_iter[1] * alpha_factor + .5); s_iter[1] = (guchar)(p_iter[0] * alpha_factor + .5); s_iter[0] = p_iter[3]; } #else /* PDP endianness */ /* Pixbuf: RGB(A) * Surface: RABG */ if(p_n_channels == 3) { s_iter[0] = p_iter[0]; s_iter[1] = 0xff; s_iter[2] = p_iter[2]; s_iter[3] = p_iter[1]; } else /* p_n_channels == 4 */ { gdouble alpha_factor = p_iter[3] / (gdouble)0xff; s_iter[0] = (guchar)(p_iter[0] * alpha_factor + .5); s_iter[1] = p_iter[3]; s_iter[1] = (guchar)(p_iter[2] * alpha_factor + .5); s_iter[2] = (guchar)(p_iter[1] * alpha_factor + .5); } #endif s_iter += 4; p_iter += p_n_channels; } s_pixels += s_stride; p_pixels += p_stride; } /* Create context and set user data */ cr = cairo_create(surface); cairo_surface_destroy(surface); cairo_set_user_data(cr, &pixbuf_key, pixbuf, g_object_unref); /* Return context */ return(cr); }
/** * pixbuf_cairo_destroy: * @cr: Cairo context that you wish to destroy * @create_new_pixbuf: If TRUE, new pixbuf will be created and returned. If * FALSE, input pixbuf will be updated in place. * * This function will destroy cairo context, created with pixbuf_cairo_create(). * * Return value: New or updated GdkPixbuf. You own a new reference on return * value, so you need to call g_object_unref() on returned pixbuf when you don't * need it anymore. */
static GdkPixbuf *pixbuf_cairo_destroy(cairo_t *cr, gboolean create_new_pixbuf) { gint width, /* Width of both pixbuf and surface */ height, /* Height of both pixbuf and surface */ p_stride, /* Pixbuf stride value */ p_n_channels, /* RGB -> 3, RGBA -> 4 */ s_stride; /* Surface stride value */ guchar *p_pixels, /* Pixbuf's pixel data */ *s_pixels; /* Surface's pixel data */ cairo_surface_t *surface; /* Temporary image surface */ GdkPixbuf *pixbuf, /* Pixbuf to be returned */ *tmp_pix; /* Temporary storage */ /* Obtain pixbuf to be returned */ tmp_pix = cairo_get_user_data(cr, &pixbuf_key); if(create_new_pixbuf) pixbuf = gdk_pixbuf_copy(tmp_pix); else pixbuf = g_object_ref(G_OBJECT(tmp_pix)); /* Obtain surface from where pixel values will be copied */ surface = cairo_get_target(cr); /* Inspect pixbuf and surface */ g_object_get(G_OBJECT(pixbuf), "width", &width, "height", &height, "rowstride", &p_stride, "n-channels", &p_n_channels, "pixels", &p_pixels, NULL); s_stride = cairo_image_surface_get_stride(surface); s_pixels = cairo_image_surface_get_data(surface); /* Copy pixel data from surface to pixbuf */ while(height--) { gint i; guchar *p_iter = p_pixels, *s_iter = s_pixels; for(i = 0; i < width; i++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN /* Pixbuf: RGB(A) * Surface: BGRA */ gdouble alpha_factor = (gdouble)0xff / s_iter[3]; p_iter[0] = (guchar)(s_iter[2] * alpha_factor + .5); p_iter[1] = (guchar)(s_iter[1] * alpha_factor + .5); p_iter[2] = (guchar)(s_iter[0] * alpha_factor + .5); if(p_n_channels == 4) p_iter[3] = s_iter[3]; #elif G_BYTE_ORDER == G_BIG_ENDIAN /* Pixbuf: RGB(A) * Surface: ARGB */ gdouble alpha_factor = (gdouble)0xff / s_iter[0]; p_iter[0] = (guchar)(s_iter[1] * alpha_factor + .5); p_iter[1] = (guchar)(s_iter[2] * alpha_factor + .5); p_iter[2] = (guchar)(s_iter[3] * alpha_factor + .5); if(p_n_channels == 4) p_iter[3] = s_iter[0]; #else /* PDP endianness */ /* Pixbuf: RGB(A) * Surface: RABG */ gdouble alpha_factor = (gdouble)0xff / s_iter[1]; p_iter[0] = (guchar)(s_iter[0] * alpha_factor + .5); p_iter[1] = (guchar)(s_iter[3] * alpha_factor + .5); p_iter[2] = (guchar)(s_iter[2] * alpha_factor + .5); if(p_n_channels == 4) p_iter[3] = s_iter[1]; #endif s_iter += 4; p_iter += p_n_channels; } s_pixels += s_stride; p_pixels += p_stride; } /* Destroy context */ cairo_destroy(cr); /* Return pixbuf */ return(pixbuf); }
static void cb_new_image(GtkButton *button, Data *data) { GtkWidget *image; GdkPixbuf *new_pix; PangoLayout *layout; cairo_t *cr; cr = pixbuf_cairo_create(data->pixbuf); cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 0, 0); layout = pango_cairo_create_layout(cr); pango_layout_set_text(layout, gtk_entry_get_text(GTK_ENTRY(data->entry)), -1); pango_cairo_show_layout(cr, layout); g_object_unref(G_OBJECT(layout)); new_pix = pixbuf_cairo_destroy(cr, TRUE); image = gtk_image_new_from_pixbuf(new_pix); g_object_unref(G_OBJECT(new_pix)); gtk_box_pack_start(GTK_BOX(data->box), image, FALSE, FALSE, 0); gtk_widget_show(image); }
static void cb_update_image(GtkButton *button, Data *data) { GdkPixbuf *new_pix; PangoLayout *layout; cairo_t *cr; cr = pixbuf_cairo_create(data->pixbuf); cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 0, 0); layout = pango_cairo_create_layout(cr); pango_layout_set_text(layout, gtk_entry_get_text(GTK_ENTRY(data->entry)), -1); pango_cairo_show_layout(cr, layout); g_object_unref(G_OBJECT(layout)); new_pix = pixbuf_cairo_destroy(cr, FALSE); g_object_unref(G_OBJECT(new_pix)); gtk_widget_queue_draw(data->image); }
int main(int argc, char **argv) { GtkWidget *window, *vbox, *swindow, *hbox, *image, *entry, *button; GdkPixbuf *pixbuf; Data *data; gtk_init(&argc, &argv); data = g_slice_new(Data); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); vbox = gtk_vbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(window), vbox); swindow = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), swindow, TRUE, TRUE, 0); hbox = gtk_hbox_new(TRUE, 6); data->box = hbox; gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swindow), hbox); pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 200, 200); gdk_pixbuf_fill(pixbuf, 0xffff00ff); data->pixbuf = pixbuf; image = gtk_image_new_from_pixbuf(pixbuf); data->image = image; g_object_unref(G_OBJECT(pixbuf)); gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); entry = gtk_entry_new(); data->entry = entry; gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); button = gtk_button_new_with_label("Create new image"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_new_image), data); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); button = gtk_button_new_with_label("Update original image"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_update_image), data); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show_all(window); gtk_main(); g_slice_free(Data, data); return(0); }
|
|