"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/extensions/gtk_edit_element/gtk_edit_impl.h" (25 Sep 2009, 13008 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2   Copyright 2008 Google Inc.
    3 
    4   Licensed under the Apache License, Version 2.0 (the "License");
    5   you may not use this file except in compliance with the License.
    6   You may obtain a copy of the License at
    7 
    8        http://www.apache.org/licenses/LICENSE-2.0
    9 
   10   Unless required by applicable law or agreed to in writing, software
   11   distributed under the License is distributed on an "AS IS" BASIS,
   12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13   See the License for the specific language governing permissions and
   14   limitations under the License.
   15 */
   16 
   17 #ifndef  GGADGET_GTK_EDIT_IMPL_H__
   18 #define  GGADGET_GTK_EDIT_IMPL_H__
   19 
   20 #include <functional>
   21 #include <string>
   22 #include <stack>
   23 #include <vector>
   24 #include <gtk/gtk.h>
   25 #include <cairo.h>
   26 
   27 #include <ggadget/common.h>
   28 #include <ggadget/math_utils.h>
   29 #include <ggadget/clip_region.h>
   30 #include <ggadget/canvas_interface.h>
   31 
   32 namespace ggadget {
   33 
   34 class Texture;
   35 class MainLoopInterface;
   36 
   37 namespace gtk {
   38 
   39 class CairoCanvas;
   40 class CairoGraphics;
   41 class GtkEditElement;
   42 
   43 /** GtkEditImpl is the gtk implementation of EditElement */
   44 class GtkEditImpl {
   45 
   46  public:
   47   GtkEditImpl(GtkEditElement *owner,
   48               MainLoopInterface *main_loop,
   49               int width, int height);
   50   ~GtkEditImpl();
   51 
   52   void Draw(CanvasInterface *canvas);
   53   EventResult OnMouseEvent(const MouseEvent &event);
   54   EventResult OnKeyEvent(const KeyboardEvent &event);
   55   void FocusIn();
   56   void FocusOut();
   57   void SetWidth(int width);
   58   int GetWidth();
   59   void SetHeight(int height);
   60   int GetHeight();
   61   void GetSizeRequest(int *width, int *height);
   62   void SetBold(bool bold);
   63   bool IsBold();
   64   void SetItalic(bool italic);
   65   bool IsItalic();
   66   void SetStrikeout(bool strikeout);
   67   bool IsStrikeout();
   68   void SetUnderline(bool underline);
   69   bool IsUnderline();
   70   void SetMultiline(bool multiline);
   71   bool IsMultiline();
   72   void SetWordWrap(bool wrap);
   73   bool IsWordWrap();
   74   void SetReadOnly(bool readonly);
   75   bool IsReadOnly();
   76   void SetText(const char *text);
   77   std::string GetText();
   78   void SetBackground(Texture *background);
   79   const Texture *GetBackground();
   80   void SetTextColor(const Color &color);
   81   Color GetTextColor();
   82   void SetFontFamily(const char *font);
   83   std::string GetFontFamily();
   84   void OnFontSizeChange();
   85   void SetPasswordChar(const char *c);
   86   std::string GetPasswordChar();
   87   bool IsScrollBarRequired();
   88   void GetScrollBarInfo(int *range, int *line_step,
   89                         int *page_step, int *cur_pos);
   90   void ScrollTo(int position);
   91   void MarkRedraw();
   92   /** Select text between start and end. */
   93   void Select(int start, int end);
   94   /** Select all text */
   95   void SelectAll();
   96 
   97   CanvasInterface::Alignment GetAlign() const;
   98   void SetAlign(CanvasInterface::Alignment align);
   99 
  100   CanvasInterface::VAlignment GetVAlign() const;
  101   void SetVAlign(CanvasInterface::VAlignment valign);
  102 
  103  private:
  104   /**
  105    * Enum used to specify different motion types.
  106    */
  107   enum MovementStep {
  108     VISUALLY,
  109     WORDS,
  110     DISPLAY_LINES,
  111     DISPLAY_LINE_ENDS,
  112     PAGES,
  113     BUFFER
  114   };
  115 
  116   enum AdjustScrollPolicy {
  117     NO_SCROLL,
  118     CENTER_CURSOR,
  119     MINIMAL_ADJUST
  120   };
  121 
  122   void QueueDraw();
  123   /** Remove the cached layout. */
  124   void ResetLayout();
  125   /**
  126    * Create pango layout on-demand. If the layout is not changed, return the
  127    * cached one.
  128    */
  129   PangoLayout* EnsureLayout();
  130   /** Create a new layout containning current edit content */
  131   PangoLayout* CreateLayout();
  132 
  133   /** Adjust the scroll information */
  134   void AdjustScroll(AdjustScrollPolicy policy);
  135   /**
  136    * Send out a request to refresh all informations of the edit control
  137    * and queue a draw request.
  138    * If @c relayout is true then the layout will be regenerated.
  139    * */
  140   void QueueRefresh(bool relayout, AdjustScrollPolicy policy);
  141   /** Reset the input method context */
  142   void ResetImContext();
  143   /** Reset preedit text */
  144   void ResetPreedit();
  145   /** Create a new im context according to current visibility setting */
  146   void InitImContext();
  147   /** Set the visibility of the edit control */
  148   void SetVisibility(bool visible);
  149 
  150   /** Check if the cursor should be blinking */
  151   bool IsCursorBlinking();
  152   /** Send out a request to blink the cursor if necessary */
  153   void QueueCursorBlink();
  154   /** Timer callback to blink the cursor */
  155   bool CursorBlinkCallback(int timer_id);
  156   void ShowCursor();
  157   void HideCursor();
  158 
  159   /** Draw the Cursor to the canvas */
  160   void DrawCursor(CanvasInterface *canvas);
  161 
  162   /** Draw the text to the canvas */
  163   void DrawText(CanvasInterface *canvas);
  164 
  165   void GetCursorRects(Rectangle *strong, Rectangle *weak);
  166 
  167   void UpdateCursorRegion();
  168 
  169   void UpdateSelectionRegion();
  170 
  171   void UpdateContentRegion();
  172 
  173   /** Move cursor */
  174   void MoveCursor(MovementStep step, int count, bool extend_selection);
  175   /** Move cursor visually, meaning left or right */
  176   int MoveVisually(int current_pos, int count);
  177   /** Move cursor logically, meaning towards head or end of the text. */
  178   int MoveLogically(int current_pos, int count);
  179   /** Move cursor in words */
  180   int MoveWords(int current_pos, int count);
  181   /** Move cursor in display lines */
  182   int MoveDisplayLines(int current_pos, int count);
  183   /** Move cursor in pages */
  184   int MovePages(int current_pos, int count);
  185   /** Move cursor to the beginning or end of a display line */
  186   int MoveLineEnds(int current_pos, int count);
  187 
  188   /** Set the current cursor offset, in number of characters. */
  189   void SetCursor(int cursor);
  190   /** Get the most reasonable character offset according to the pixel
  191    * coordinate in the layout */
  192   int XYToTextIndex(int x, int y);
  193   /** Get the offset range that is currently selected,in number of characters.*/
  194   bool GetSelectionBounds(int *start, int *end);
  195   /** Set the offest range that should be selected, in number of characters. */
  196   void SetSelectionBounds(int selection_bound, int cursor);
  197 
  198   /** Convert index in text_ into index in layout text. */
  199   int TextIndexToLayoutIndex(int text_index, bool consider_preedit_cursor);
  200 
  201   /** Convert index in layout text into index in text_. */
  202   int LayoutIndexToTextIndex(int layout_index);
  203 
  204   /** Get char length at index, in number of bytes. */
  205   int GetCharLength(int index);
  206 
  207   /** Get previous char length before index, in number of bytes. */
  208   int GetPrevCharLength(int index);
  209 
  210   /** Insert text at current caret position */
  211   void EnterText(const char *str);
  212   /** Delete text in a specified range, in number of characters. */
  213   void DeleteText(int start, int end);
  214 
  215   /** Select the current word under cursor */
  216   void SelectWord();
  217   /** Select the current display line under cursor */
  218   void SelectLine();
  219   /** Delete the text that is currently selected */
  220   void DeleteSelection();
  221 
  222   /** Cut the current selected text to the clipboard */
  223   void CutClipboard();
  224   /** Copy the current selected text to the clipboard */
  225   void CopyClipboard();
  226   /** Paste the text in the clipboard to current offset */
  227   void PasteClipboard();
  228   /** Delete a character before the offset of the cursor */
  229   void BackSpace();
  230   /** Delete a character at the offset of the cursor */
  231   void Delete();
  232   /** Switch between the overwrite mode and the insert mode*/
  233   void ToggleOverwrite();
  234 
  235   /** Gets the color of selection background. */
  236   Color GetSelectionBackgroundColor();
  237   /** Gets the color of selection text. */
  238   Color GetSelectionTextColor();
  239 
  240   /**
  241    * Gets the gtk widget used by the gadget host and the cursor location
  242    * for gtk im context. relative to the widget coordinate.
  243    */
  244   GtkWidget *GetWidgetAndCursorLocation(GdkRectangle *cur);
  245 
  246   /**
  247    * Gets the cursor location in pango layout. The unit is pixel.
  248    */
  249   void GetCursorLocationInLayout(PangoRectangle *strong, PangoRectangle *weak);
  250 
  251   /**
  252    * Updates the cursor location of input method context.
  253    */
  254   void UpdateIMCursorLocation();
  255 
  256   /** Callback function for IM "commit" signal */
  257   static void CommitCallback(GtkIMContext *context,
  258                              const char *str, void *gg);
  259   /** Callback function for IM "retrieve-surrounding" signal */
  260   static gboolean RetrieveSurroundingCallback(GtkIMContext *context,
  261                                               void *gg);
  262   /** Callback function for IM "delete-surrounding" signal */
  263   static gboolean DeleteSurroundingCallback(GtkIMContext *context, int offset,
  264                                             int n_chars, void *gg);
  265   /** Callback function for IM "preedit-start" signal */
  266   static void PreeditStartCallback(GtkIMContext *context, void *gg);
  267   /** Callback function for IM "preedit-changed" signal */
  268   static void PreeditChangedCallback(GtkIMContext *context, void *gg);
  269   /** Callback function for IM "preedit-end" signal */
  270   static void PreeditEndCallback(GtkIMContext *context, void *gg);
  271   /**
  272    * Callback for gtk_clipboard_request_text function.
  273    * This function performs real paste.
  274    */
  275   static void PasteCallback(GtkClipboard *clipboard,
  276                             const gchar *str, void *gg);
  277 
  278  private:
  279   /** Owner of this gtk edit implementation object. */
  280   GtkEditElement *owner_;
  281   /** Main loop object */
  282   MainLoopInterface *main_loop_;
  283   /** Graphics object, must be CairoGraphics */
  284   const GraphicsInterface *graphics_;
  285 
  286   /** Gtk InputMethod Context */
  287   GtkIMContext *im_context_;
  288 
  289   /** The cached Pango Layout */
  290   PangoLayout *cached_layout_;
  291 
  292   /** The text content of the edit control */
  293   std::string text_;
  294   /** The preedit text of the edit control */
  295   std::string preedit_;
  296   /** Attribute list of the preedit text */
  297   PangoAttrList *preedit_attrs_;
  298   /**
  299    *  The character that should be displayed in invisible mode.
  300    *  If this is empty, then the edit control is visible
  301    */
  302   std::string password_char_;
  303 
  304   /** Last time of mouse double click event. */
  305   uint64_t last_dblclick_time_;
  306 
  307   /** Canvas width */
  308   int width_;
  309   /** Canvas height */
  310   int height_;
  311 
  312   /** The current cursor position in number of bytes. */
  313   int cursor_;
  314   /**
  315    * The preedit cursor position within the preedit string,
  316    * in number of bytes.
  317    */
  318   int preedit_cursor_;
  319   /**
  320    * The current selection bound in number of bytes,
  321    * range between cursor_ and selection_bound_ are selected.
  322    */
  323   int selection_bound_;
  324 
  325   /** X offset of current scroll, in pixels */
  326   int scroll_offset_x_;
  327   /** Y offset of current scroll, in pixels */
  328   int scroll_offset_y_;
  329   /** Timer id of cursor blink callback */
  330   int cursor_blink_timer_;
  331   /**
  332    * Indicates the status of cursor blinking,
  333    * 0 means hide cursor
  334    * otherwise means show cursor.
  335    * The maximum value would be 2, and decrased by one in each cursor blink
  336    * callback, then there would be 2/3 visible time and 1/3 invisible time.
  337    */
  338   int cursor_blink_status_;
  339 
  340   /** Whether the text is visible, decided by password_char_ */
  341   bool visible_;
  342   /** Whether the edit control is focused */
  343   bool focused_;
  344   /** Whether the input method should be reset */
  345   bool need_im_reset_;
  346   /** Whether the keyboard in overwrite mode */
  347   bool overwrite_;
  348   /** Whether the button click should select words */
  349   bool select_words_;
  350   /** Whether the button click should select lines */
  351   bool select_lines_;
  352   /** Whether the left button is pressed */
  353   bool button_;
  354   /** Whether the text should be bold */
  355   bool bold_;
  356   /** Whether the text should be underlined */
  357   bool underline_;
  358   /** Whether the text should be struck-out */
  359   bool strikeout_;
  360   /** Whether the text should be italic */
  361   bool italic_;
  362   /** Whether the text could be shown in multilines */
  363   bool multiline_;
  364   /** Whether the text should be wrapped */
  365   bool wrap_;
  366   /** whether the cursor should be displayed */
  367   bool cursor_visible_;
  368   /** whether the edit control is readonly */
  369   bool readonly_;
  370   /**
  371    * Indicates if the content of the edit control has been modified
  372    * since last draw
  373    */
  374   bool content_modified_;
  375 
  376   /** Indicates if the selection region has been changed since last draw. */
  377   bool selection_changed_;
  378 
  379   /** Indicates if the cursor position has been moved since last draw. */
  380   bool cursor_moved_;
  381 
  382   /** The font family of the text */
  383   std::string font_family_;
  384   /** The font size of the text */
  385   double font_size_;
  386   /** The background texture of the edit control */
  387   Texture *background_;
  388   /** The text color of the edit control */
  389   Color text_color_;
  390 
  391   CanvasInterface::Alignment align_;
  392 
  393   CanvasInterface::VAlignment valign_;
  394 
  395   /**
  396    * Cursor index in layout, which shall be reset to -1 when resetting
  397    * layout or moving cursor so that it'll be recalculated.
  398    */
  399   int cursor_index_in_layout_;
  400 
  401   PangoRectangle strong_cursor_pos_;
  402   PangoRectangle weak_cursor_pos_;
  403 
  404   ClipRegion last_selection_region_;
  405   ClipRegion selection_region_;
  406   ClipRegion last_cursor_region_;
  407   ClipRegion cursor_region_;
  408   ClipRegion last_content_region_;
  409   ClipRegion content_region_;
  410 
  411   DISALLOW_EVIL_CONSTRUCTORS(GtkEditImpl);
  412 };  // class GtkEditImpl
  413 
  414 } // namespace gtk
  415 } // namespace ggadget
  416 
  417 #endif   // GGADGET_GTK_EDIT_IMPL_H__