tstc.c
Go to the documentation of this file.
1 // cwchessboard -- A GTK+ chessboard widget
2 //
3 //! @file tstc.c An example of how to use the GTK+ widget with C code.
4 //
5 // Copyright (C) 2008, by
6 //
7 // Carlo Wood, Run on IRC <carlo@alinoe.com>
8 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
9 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 // CwChessboard usage example in C code.
24 
25 #include <gtk/gtk.h>
26 #include "CwChessboard.h"
27 
28 static void destroy_event(gchar* response)
29 {
30  gtk_main_quit();
31 }
32 
33 static gint handle = -1;
34 static gint arrow_begin_col;
35 static gint arrow_begin_row;
36 
37 static inline gboolean is_inside_board(gint col, gint row)
38 {
39  return !((col | row) & ~0x7);
40 }
41 
42 gboolean button_press_event(GtkWidget* widget, GdkEventButton* event)
43 {
44  CwChessboard* chessboard = CW_CHESSBOARD(widget);
45 
46  if (event->button == 1)
47  {
48  handle = -1;
49  // Find the square under the mouse, if any.
50  gint col = cw_chessboard_x2col(chessboard, event->x);
51  gint row = cw_chessboard_y2row(chessboard, event->y);
52  if (is_inside_board(col, row))
53  {
54  CwChessboardCode code = cw_chessboard_get_square(chessboard,col, row);
55  if (code > 1) // The least significant bit reflects the color of the piece.
56  // A code <= 1 means an empty square.
57  {
58  // Make the square empty.
59  cw_chessboard_set_square(chessboard, col, row, empty_square);
60  // Put the piece under the mouse pointer.
61  double hsside = 0.5 * chessboard->sside;
62  double fraction = hsside - (gint)hsside;
63  handle = cw_chessboard_add_floating_piece(chessboard, code,
64  event->x - fraction, event->y - fraction, TRUE);
65  }
66  }
67  }
68  else if (event->button == 2)
69  {
70  gint col = cw_chessboard_x2col(chessboard, event->x);
71  gint row = cw_chessboard_y2row(chessboard, event->y);
72  if (is_inside_board(col, row))
73  {
74  cw_chessboard_show_cursor(chessboard);
75  cw_chessboard_set_marker_color(chessboard, col, row, 1);
76  arrow_begin_col = col;
77  arrow_begin_row = row;
78  }
79  }
80  else if (event->button == 3)
81  cw_chessboard_show_cursor(chessboard);
82 
83  return (handle != -1);
84 }
85 
86 gboolean button_release_event(GtkWidget* widget, GdkEventButton* event)
87 {
88  CwChessboard* chessboard = CW_CHESSBOARD(widget);
89  if (event->button == 1)
90  {
91  if (handle != -1)
92  {
93  // Find the square under the mouse, if any.
94  gint col = cw_chessboard_x2col(chessboard, event->x);
95  gint row = cw_chessboard_y2row(chessboard, event->y);
96  if (is_inside_board(col, row))
97  {
98  // Put the piece on the new square.
99  cw_chessboard_set_square(chessboard, col, row, cw_chessboard_get_floating_piece(chessboard, handle));
100  }
101  // Remove the piece under the mouse pointer.
102  cw_chessboard_remove_floating_piece(chessboard, handle);
103  handle = -1;
104  return TRUE;
105  }
106  }
107  else if (event->button == 2)
108  {
109  GdkColor color = { 0, 0, 0, 65535 };
110  gint col = cw_chessboard_x2col(chessboard, event->x);
111  gint row = cw_chessboard_y2row(chessboard, event->y);
112  cw_chessboard_hide_cursor(chessboard);
113  cw_chessboard_set_marker_color(chessboard, arrow_begin_col, arrow_begin_row, 0);
114  if ((arrow_begin_col != col || arrow_begin_row != row)&&
115  is_inside_board(arrow_begin_col, arrow_begin_row)&&
116  is_inside_board(col, row))
117  cw_chessboard_add_arrow(chessboard, arrow_begin_col, arrow_begin_row, col, row,& color);
118  }
119  else if (event->button == 3)
120  cw_chessboard_hide_cursor(chessboard);
121  return FALSE;
122 }
123 
124 static void setup_menu(GtkWidget* vbox)
125 {
126  // Create File menu.
127  GtkWidget* file_menu = gtk_menu_new();
128 
129  // File menu items.
130  GtkWidget* quit_item = gtk_menu_item_new_with_label("Quit");
131 
132  // Add them to the menu.
133  gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit_item);
134 
135  // We can attach the Quit menu item to our exit function.
136  g_signal_connect_swapped(G_OBJECT(quit_item), "activate", G_CALLBACK(destroy_event), (gpointer) "file.quit");
137 
138  // We do need to show menu items.
139  gtk_widget_show(quit_item);
140 
141  GtkWidget* menu_bar = gtk_menu_bar_new();
142  gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 2);
143  gtk_widget_show(menu_bar);
144 
145  GtkWidget* file_item = gtk_menu_item_new_with_label("File");
146  gtk_widget_show(file_item);
147 
148  gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu);
149  gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);
150 }
151 
152 int main(int argc, char* argv[])
153 {
154  if (!gtk_init_check(&argc,& argv))
155  {
156  printf("gtk_init_check failed\n");
157  return 1;
158  }
159 
160  // Create the chessboard widget.
161  GtkWidget* chessboard_widget = cw_chessboard_new();
162  CwChessboard* chessboard = CW_CHESSBOARD(chessboard_widget);
163 
164  // Allocate some colors.
165  CwChessboardColorHandle light = cw_chessboard_allocate_color_handle_rgb(chessboard, 1.0, 1.0, 0.6);
166  CwChessboardColorHandle dark = cw_chessboard_allocate_color_handle_rgb(chessboard, 0.8, 0.93, 0.47);
167  CwChessboardColorHandle red = cw_chessboard_allocate_color_handle_rgb(chessboard, 1.0, 0.0, 0.0);
168  CwChessboardColorHandle yellow = cw_chessboard_allocate_color_handle_rgb(chessboard, 1.0, 1.0, 0.0);
169 
170  // Highlight column 'e'.
171  for (int row = 1; row < 7; ++row)
172  cw_chessboard_set_background_color(chessboard, 4, row, (row & 1) ? light : dark);
173 
174  // Set up position.
175  cw_chessboard_set_square(chessboard, 1, 0, empty_square);
176  cw_chessboard_set_square(chessboard, 3, 0, empty_square);
177  cw_chessboard_set_square(chessboard, 6, 0, empty_square);
178  cw_chessboard_set_square(chessboard, 3, 1, empty_square);
179  cw_chessboard_set_square(chessboard, 4, 1, empty_square);
180  cw_chessboard_set_square(chessboard, 2, 2, white_knight);
181  cw_chessboard_set_square(chessboard, 2, 3, white_knight);
182  cw_chessboard_set_square(chessboard, 3, 3, white_pawn);
183  cw_chessboard_set_square(chessboard, 5, 2, white_queen);
184  cw_chessboard_set_square(chessboard, 2, 1, black_bishop);
185  cw_chessboard_set_square(chessboard, 2, 5, black_pawn);
186  cw_chessboard_set_square(chessboard, 5, 5, black_knight);
187  cw_chessboard_set_square(chessboard, 3, 6, black_knight);
188  cw_chessboard_set_square(chessboard, 1, 7, empty_square);
189  cw_chessboard_set_square(chessboard, 2, 7, empty_square);
190  cw_chessboard_set_square(chessboard, 2, 6, empty_square);
191  cw_chessboard_set_square(chessboard, 6, 7, empty_square);
192 
193  // Set a few markers.
194  cw_chessboard_set_marker_thickness(chessboard, 0.03);
195  cw_chessboard_set_marker_color(chessboard, 4, 7, red);
196  cw_chessboard_set_marker_color(chessboard, 2, 1, red);
197  cw_chessboard_set_marker_color(chessboard, 4, 6, yellow);
198 
199  // Draw a few arrows.
200  GdkColor green = { 0, 0, 32000, 0 };
201  cw_chessboard_add_arrow(chessboard, 5, 2, 4, 1,& green);
202  GdkColor red2 = { 0, 65535, 0, 0 };
203  cw_chessboard_add_arrow(chessboard, 2, 3, 3, 5,& red2);
204 
205  // Create the main window.
206  GtkWidget* main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
207 
208  // Set initial size.
209  gtk_window_set_default_size(GTK_WINDOW(main_window), 500, 532);
210 
211  // A vbox to put a menu and chessboard in.
212  GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
213  gtk_container_add(GTK_CONTAINER(main_window), vbox);
214  gtk_widget_show(vbox);
215 
216  // Set up the menu.
217  setup_menu(vbox);
218 
219  // Add the chessboard to the vbox.
220  gtk_container_add(GTK_CONTAINER(vbox), chessboard_widget);
221 
222  // Show the chessboard.
223  gtk_widget_show(chessboard_widget);
224 
225  // Install handler for mouse movement.
226  g_signal_connect(G_OBJECT(chessboard), "button-press-event", G_CALLBACK(button_press_event), NULL);
227  g_signal_connect(G_OBJECT(chessboard), "button-release-event", G_CALLBACK(button_release_event), NULL);
228 
229  // Install handler for destroy event.
230  g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(destroy_event), NULL);
231 
232  // Draw the main window.
233  gtk_widget_show(main_window);
234 
235  // Start main loop.
236  gtk_main();
237 }
void cw_chessboard_set_square(CwChessboard* chessboard, gint col, gint row, CwChessboardCode code)
CwChessboardCode const empty_square
gint const sside
Square side in pixels (read only).
Definition: CwChessboard.h:110
uint16_t CwChessboardCode
A code to specify a chess piece.
CWCHESSBOARD_INLINE gint cw_chessboard_x2col(CwChessboard* chessboard, gdouble x)
CWCHESSBOARD_INLINE gint cw_chessboard_y2row(CwChessboard* chessboard, gdouble y)
CwChessboardCode const white_pawn
This file contains the declaration of the GTK+ widget CwChessboard.
CwChessboardColorHandle cw_chessboard_allocate_color_handle_rgb(CwChessboard* chessboard, gdouble red, gdouble green, gdouble blue)
A GTK+ chessboard widget.
Definition: CwChessboard.h:101
CwChessboardCode const white_queen
CwChessboardCode cw_chessboard_get_floating_piece(CwChessboard* chessboard, gint handle)
void cw_chessboard_set_marker_thickness(CwChessboard* chessboard, gdouble thickness)
CwChessboardCode cw_chessboard_get_square(CwChessboard* chessboard, gint col, gint row)
CwChessboardCode const black_pawn
void cw_chessboard_hide_cursor(CwChessboard* chessboard)
CwChessboardCode const black_bishop
unsigned char CwChessboardColorHandle
A color handle used for background markers.
Definition: CwChessboard.h:79
CwChessboardCode const black_knight
gpointer cw_chessboard_add_arrow(CwChessboard* chessboard, gint begin_col, gint begin_row, gint end_col, gint end_row, GdkColor const* color)
CwChessboardCode const white_knight
gint cw_chessboard_add_floating_piece(CwChessboard* chessboard, CwChessboardCode code, gdouble x, gdouble y, gboolean pointer_device)
void cw_chessboard_set_marker_color(CwChessboard* chessboard, gint col, gint row, CwChessboardColorHandle mahandle)
GtkWidget * cw_chessboard_new(void)
void cw_chessboard_show_cursor(CwChessboard* chessboard)
void cw_chessboard_set_background_color(CwChessboard* chessboard, gint col, gint row, CwChessboardColorHandle bghandle)
void cw_chessboard_remove_floating_piece(CwChessboard* chessboard, gint handle)

Copyright © 2006 - 2010 Carlo Wood.  All rights reserved.