?? cellwidget.c
字號:
g_object_unref(layout); } /* Insertion arrows */ if (!invalid && inserting && (current_cell == i || current_cell == i + 1)) { double width, stem, height; cairo_set_source_gdk_color(cairo, &color_select, 1.); width = CELL_BORDER; stem = CELL_BORDER / 2; height = CELL_BORDER; if ((!right_to_left && current_cell == i) || (right_to_left && current_cell == i + 1)) { /* Top right arrow */ cairo_move_to(cairo, x, y + 1); cairo_line_to(cairo, x + stem, y + 1); cairo_line_to(cairo, x + stem, y + height); cairo_line_to(cairo, x + width, y + height); cairo_line_to(cairo, x, y + height * 2); cairo_close_path(cairo); cairo_fill(cairo); /* Bottom right arrow */ cairo_move_to(cairo, x, y + cell_height - 1); cairo_line_to(cairo, x + stem, y + cell_height - 1); cairo_line_to(cairo, x + stem, y + cell_height - height); cairo_line_to(cairo, x + width, y + cell_height - height); cairo_line_to(cairo, x, y + cell_height - height * 2); cairo_close_path(cairo); cairo_fill(cairo); } else if ((!right_to_left && current_cell == i + 1) || (right_to_left && current_cell == i)) { double ox; ox = i % cell_cols == cell_cols - 1 ? 0. : 1.; /* Top left arrow */ cairo_move_to(cairo, x + cell_width + ox, y + 1); cairo_line_to(cairo, x + cell_width - stem + ox, y + 1); cairo_line_to(cairo, x + cell_width - stem + ox, y + height); cairo_line_to(cairo, x + cell_width - width + ox, y + height); cairo_line_to(cairo, x + cell_width + ox, y + height * 2); cairo_close_path(cairo); cairo_fill(cairo); /* Bottom left arrow */ cairo_move_to(cairo, x + cell_width + ox, y + cell_height - 1); cairo_line_to(cairo, x + cell_width - stem + ox, y + cell_height - 1); cairo_line_to(cairo, x + cell_width - stem + ox, y + cell_height - height); cairo_line_to(cairo, x + cell_width - width + ox, y + cell_height - height); cairo_line_to(cairo, x + cell_width + ox, y + cell_height - height * 2); cairo_close_path(cairo); cairo_fill(cairo); } } gtk_widget_queue_draw_area(drawing_area, x, y, cell_width, cell_height); pc->flags &= ~CELL_DIRTY; /* This cell may have dirtied the on-screen keyboard */ if (show_keys && x < key_widget->x + key_widget->width && y < key_widget->y + key_widget->height && x + cell_width > key_widget->x && y + cell_height > key_widget->y) keys_dirty = TRUE;}static void render_dirty(void)/* Render cells marked dirty */{ int i; for (i = cell_row_view * cell_cols; i < cell_rows * cell_cols; i++) if (cells[i].flags & CELL_DIRTY) render_cell(i); if (show_keys && keys_dirty) { key_widget_render(key_widget); keys_dirty = FALSE; }}void cell_widget_render(void)/* Render the cells */{ int i, cols, rows, width, height; if (!cairo || !pixmap || !pixmap_gc) return; /* On-screen keyboard eats up some cells on the end */ cols = cell_cols; if (show_keys) cols -= KEY_WIDGET_COLS; /* Render cells */ for (i = cell_row_view * cols; i < cell_rows * cols; i++) render_cell(i); /* Draw border */ rows = cell_rows < cell_rows_pref ? cell_rows : cell_rows_pref; width = cell_width * cols + 1; height = cell_height * rows + 1; gdk_gc_set_rgb_fg_color(pixmap_gc, &color_bg_dark); if (!right_to_left) gdk_draw_rectangle(pixmap, pixmap_gc, FALSE, 0, 0, width, height); else gdk_draw_rectangle(pixmap, pixmap_gc, FALSE, drawing_area->allocation.width - width - 1, 0, width, height); /* Fill extra space to the right */ gdk_gc_set_rgb_fg_color(pixmap_gc, &color_bg); if (!right_to_left) gdk_draw_rectangle(pixmap, pixmap_gc, TRUE, width + 1, 0, drawing_area->allocation.width - width, height + 1); else gdk_draw_rectangle(pixmap, pixmap_gc, TRUE, 0, 0, drawing_area->allocation.width - width - 1, height + 1); /* Fill extra space below */ gdk_draw_rectangle(pixmap, pixmap_gc, TRUE, 0, height + 1, drawing_area->allocation.width, drawing_area->allocation.height - height + 1); /* Render the on-screen keyboard */ if (show_keys) { key_widget_render(key_widget); keys_dirty = FALSE; } /* Dirty the entire drawing area */ gtk_widget_queue_draw(drawing_area);}static void clear_cell(int i){ Cell *cell; cell = cells + i; cell->flags = 0; if (cell->ch || i == current_cell) { if (i == current_cell) input = NULL; cell->flags |= CELL_DIRTY; } clear_sample(&cell->sample); cell->ch = 0; cell->alts[0] = NULL;}static void pad_cell(int cell){ int i; /* Turn any blank cells behind the cell into spaces */ for (i = cell - 1; i >= 0 && !cells[i].ch; i--) { cells[i].ch = ' '; cells[i].flags |= CELL_DIRTY; }}static void free_cells(void)/* Free sample data */{ int i; if (!cells) return; for (i = 0; i < cell_rows * cell_cols; i++) clear_cell(i); g_free(cells); cells = NULL; input = NULL;}static void wrap_cells(int new_rows, int new_cols)/* Word wrap cells */{ Cell *new_cells; int i, j, size, row, col, break_i = -1, break_j = -1; /* Allocate and clear the new grid */ if (new_rows < 1) new_rows = 1; size = new_rows * new_cols * sizeof (Cell); new_cells = g_malloc0(size); for (i = 0, j = 0, row = 0, col = 0; i < cell_rows * cell_cols; i++) { if (!cells[i].ch) continue; /* Break at non-alphanumeric characters */ if (!g_unichar_isalnum(cells[i].ch)) { break_i = i; break_j = j; } if (col >= new_cols) { /* If we need to, allocate room for the new row */ if (++row >= new_rows) { size = ++new_rows * new_cols * sizeof (Cell); new_cells = g_realloc(new_cells, size); memset(new_cells + (new_rows - 1) * new_cols, 0, new_cols * sizeof (Cell)); } /* Move any hanging words down to the next row */ size = i - break_i - 1; if (size >= 0 && size < i - 1) { memset(new_cells + break_j + 1, 0, sizeof (Cell) * size); i = break_i + 1; break_i = -1; } col = 0; if (!cells[i].ch) continue; } new_cells[j++] = cells[i]; col++; } /* If we have filled the last row, we need to add a new row */ if (col >= new_cols && row >= new_rows - 1) { size = ++new_rows * new_cols * sizeof (Cell); new_cells = g_realloc(new_cells, size); memset(new_cells + (new_rows - 1) * new_cols, 0, new_cols * sizeof (Cell)); } /* Only free the cell array, NOT the samples as we have copied the Sample data over to the new cell array */ g_free(cells); cells = new_cells; /* Scroll the grid */ if (new_rows > cell_rows && new_rows > cell_rows_pref) cell_row_view += new_rows - cell_rows; /* Do not let the row view look too far down */ if (cell_row_view + cell_rows_pref > new_rows) { cell_row_view = new_rows - cell_rows_pref; if (cell_row_view < 0) cell_row_view = 0; } cell_rows = new_rows; cell_cols = new_cols;}static int set_size_request(int force)/* Resize the drawing area if necessary */{ int new_w, new_h, rows, resized; new_w = cell_cols * cell_width + 2; rows = cell_rows; if (rows > cell_rows_pref) rows = cell_rows_pref; new_h = rows * cell_height + 2; resized = new_w != drawing_area->allocation.width || new_h != drawing_area->allocation.height || force; if (!resized) return FALSE; gtk_widget_set_size_request(drawing_area, new_w, new_h); return TRUE;}static int pack_cells(int new_rows, int new_cols)/* Pack and position cells, resize widget and window when necessary. Returns TRUE if the widget was resized in the process and can expect a configure event in the near future. */{ int i, rows, range, new_range; /* Must have at least one row */ if (new_rows < 1) new_rows = 1; /* Word wrapping will perform its own memory allocation */ if (!training && cells) wrap_cells(new_rows, new_cols); else if (!cells || new_rows != cell_rows || new_cols != cell_cols) { /* Find minimum number of rows necessary */ if (cells) { for (i = cell_rows * cell_cols - 1; i > 0; i--) if (cells[i].ch) break; rows = i / new_cols + 1; if (new_rows < rows) new_rows = rows; new_range = new_rows * new_cols; /* If we have shrunk the grid, clear cells outside */ range = cell_rows * cell_cols; for (i = new_range; i < range; i++) clear_cell(i); } else { range = 0; new_range = new_rows * new_cols; } /* Allocate enough room, clear any new cells */ cells = g_realloc(cells, new_rows * new_cols * sizeof (Cell)); if (new_range > range) memset(cells + range, 0, (new_range - range) * sizeof (Cell)); cell_rows = new_rows; cell_cols = new_cols; } dirty_all(); /* Update the scrollbar */ if (cell_rows <= cell_rows_pref) { cell_row_view = 0; gtk_widget_hide(scrollbar); } else { GtkObject *adjustment; if (cell_row_view > cell_rows - cell_rows_pref) cell_row_view = cell_rows - cell_rows_pref; if (cell_row_view < 0) cell_row_view = 0; adjustment = gtk_adjustment_new(cell_row_view, 0, cell_rows, 1, cell_rows_pref, cell_rows_pref); gtk_range_set_adjustment(GTK_RANGE(scrollbar), GTK_ADJUSTMENT(adjustment)); gtk_widget_show(scrollbar); } return set_size_request(FALSE);}static void stop_timeout(void){ if (!timeout_source) return; g_source_remove(timeout_source); timeout_source = 0;}static void finish_cell(int cell){ stop_timeout(); if (cell < 0 || cell >= cell_rows * cell_cols || !input || input->len < 1) return; cells[cell].flags |= CELL_DIRTY; /* Train on the input */ if (training) train_sample(&cells[cell].sample, TRUE); /* Recognize input */ else if (input && input->strokes[0] && input->strokes[0]->len) { Cell *pc = cells + cell; int i; /* Track stats */ if (pc->ch && pc->ch != ' ') rewrites++; inputs++;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -