⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text_widget.txt

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 TXT
📖 第 1 页 / 共 2 页
字号:
true, LINE_PARAMS_ITERATE heap-allocates the LineParams and does notfree them.  Otherwise, no storage is permanently allocated.  ITERshould return TRUE when it wishes to continue no longer.There are currently two uses of LINE_PARAMS_ITERATE:* Compute the total buffer height for setting the parameters of the  scroll bars.  This is done in SET_VERTICAL_SCROLL each time the  window is resized.  When horizontal scrolling is added, depending on  the policy chosen, the max line width can be computed here as well.* Computing geometry of some pixel height worth of lines.  This is  done in FETCH_LINES, FETCH_LINES_BACKWARD, FETCH_LINES_FORWARD, etc.The GtkText structure contains a cache of the LineParams data for allvisible lines:  GList *current_line;  GList *line_start_cache;  guint first_line_start_index;  guint first_cut_pixels;  guint first_onscreen_hor_pixel;  guint first_onscreen_ver_pixel;LINE_START_CACHE is a doubly linked list of LineParams.  CURRENT_LINEis a transient piece of data which is set in varoius places such asthe mouse click code.  Generally, it is the line on which the cursorproperty mark CURSOR_MARK is on.  LINE_START_CACHE points to the firstvisible line and may contain PREV pointers if the cached data ofoffscreen lines is kept around.  I haven't come up with a policy.  Thecache can keep more lines than are visible if desired, but the resultis that inserts and deletes will then become slower as the entirecache has to be "corrected".  Right now it doesn't delete from thecache (it should).  As a result, scrolling through the whole bufferonce will fill the cache with an entry for each line, and subsequentmodifications will be slower than they shouldbe. FIRST_LINE_START_INDEX is the index of the *REAL* line start ofthe first line.  That is, if the first visible line is a continuedline, this is the index of the real line start (preceded by anewline).  FIRST_CUT_PIXELS is the number of pixels which are notdrawn on the first visible line.  If FIRST_CUT_PIXELS is zero, thewhole line is visible.  FIRST_ONSCREEN_HOR_PIXEL is not used.FIRST_ONSCREEN_VER_PIXEL is the absolute pixel which starts thevisible region.  This is used for setting the vertical scroll bar.Other miscellaneous things in the GtkText structure:Gtk specific things:  GtkWidget widget;  GdkWindow *text_area;  GtkAdjustment *hadj;  GtkAdjustment *vadj;  GdkGC *gc;  GdkPixmap* line_wrap_bitmap;  GdkPixmap* line_arrow_bitmap;These are pretty self explanatory, especially if you know Gtk.LINE_WRAP_BITMAP and LINE_ARROW_BITMAP are two bitmaps used toindicate that a line wraps and is continued offscreen, respectively.Some flags:  guint has_cursor : 1;  guint is_editable : 1;  guint line_wrap : 1;  guint freeze : 1;  guint has_selection : 1;  guint own_selection : 1;HAS_CURSOR is true iff the cursor is visible.  IS_EDITABLE is true iffthe user is allowed to modify the buffer.  If IS_EDITABLE is false,HAS_CURSOR is guaranteed to be false.  If IS_EDITABLE is true,HAS_CURSOR starts out false and is set to true the first time the userclicks in the window.  LINE_WRAP is where the line-wrap policy isset.  True means wrap lines, false means continue lines offscreen,horizontally.The text properties list:  GList *text_properties;  GList *text_properties_end;A scratch area used for constructing a contiguous piece of the bufferwhich may otherwise span the gap.  It is not strictly neccesarybut simplifies the drawing code because it does not need to deal withthe gap.  guchar* scratch_buffer;  guint   scratch_buffer_len;The last vertical scrollbar position.  Currently this looks the sameas FIRST_ONSCREEN_VER_PIXEL.  I can't remember why I have two values.Perhaps someone should clean this up.  gint last_ver_value;The cursor:  gint            cursor_pos_x;  gint            cursor_pos_y;  GtkPropertyMark cursor_mark;  gchar           cursor_char;  gchar           cursor_char_offset;  gint            cursor_virtual_x;  gint            cursor_drawn_level;CURSOR_POS_X and CURSOR_POS_Y are the screen coordinates of thecursor.  CURSOR_MARK is the buffer position.  CURSOR_CHAR isTEXT_INDEX (TEXT, CURSOR_MARK.INDEX) if a drawable character, or 0 ifit is whitespace, which is treated specially.  CURSOR_CHAR_OFFSET isthe pixel offset above the base of the line at which it should bedrawn.  Note that the base of the line is not the "baseline" in thetraditional font metric sense.  A line (LineParams) isFONT_ASCENT+FONT_DESCENT high (use the macro LINE_HEIGHT).  The"baseline" is FONT_DESCENT below the base of the line.  I think thisrequires a drawing.0                      AAAAAAA1                      AAAAAAA2                     AAAAAAAAA3                     AAAAAAAAA4                    AAAAA AAAAA5                    AAAAA AAAAA6                   AAAAA   AAAAA7                  AAAAA     AAAAA8                  AAAAA     AAAAA9                 AAAAAAAAAAAAAAAAA10                AAAAAAAAAAAAAAAAA11               AAAAA         AAAAA12               AAAAA         AAAAA13              AAAAAA         AAAAAA14______________AAAAA___________AAAAA__________________________________151617181920This line is 20 pixels high, has FONT_ASCENT=14, FONT_DESCENT=6.  It's"base" is at y=20.  Characters are drawn at y=14.  The LINE_STARTmacro returns the pixel height.  The LINE_CONTAINS macro is true ifthe line contains a certain buffer index.  The LINE_STARTS_AT macro istrue if the line starts at a certain buffer index.  TheLINE_START_PIXEL is the pixel offset the line should be drawn at,according the the tab continuation of the previous line.Exposure and drawing:Exposure is handled from the EXPOSE_TEXT function.  It assumes thatthe LINE_START_CACHE and all it's parameters are accurate and simplyexposes any line which is in the exposure region.  It calls theCLEAR_AREA function to clear the background and/or lay down a pixmapbackground.  The text widget has a scrollable pixmap background, whichis implemented in CLEAR_AREA.  CLEAR_AREA does the math to figure outhow to tile the pixmap itself so that it can scroll the text with acopy area call.  If the CURSOR argument to EXPOSE_TEXT is true, italso draws the cursor.The function DRAW_LINE draws a single line, doing all the tab andcolor computations neccesary.  The function DRAW_LINE_WRAP draws theline wrap bitmap at the end of the line if it wraps.  TEXT_EXPOSE willexpand the cached line data list if it has to by callingFETCH_LINES_FORWARD.  The functions DRAW_CURSOR and UNDRAW_CURSOR drawand undraw the cursor.  They count the number of draws and undraws sothat the cursor may be undrawn even if the cursor is already undrawnand the re-draw will not occur too early.  This is useful in handlingscrolling.Handling of the cursor is a little messed up, I should add.  It has tobe undrawn and drawn at various places.  Something better needs to bedone about this, because it currently doesn't do the right thing incertain places.  I can't remember where very well.  Look for the callsto DRAW_CURSOR and UNDRAW_CURSOR.RECOMPUTE_GEOMETRY is called when the geometry of the window changesor when it is first drawn.  This is probably not done right.  Mybiggest weakness in writing this code is that I've never written awidget before so I got most of the event handling stuff wrong as faras Gtk is concerned.  Fortunatly, most of the code is unrelated andsimply an exercise in data structure manipulation.Scrolling:Scrolling is fairly straighforward.  It looks at the top line, andadvances it pixel by pixel until the FIRST_CUT_PIXELS equals the lineheight and then advances the LINE_START_CACHE.  When it runs out oflines it fetches more.  The function SCROLL_INT is used to scroll frominside the code, it calls the appropriate functions and handlesupdating the scroll bars.  It dispatches a change event which causesGtk to call the correct scroll action, which then enters SCROLL_UP orSCROLL_DOWN.  Careful with the cursor during these changes.Insertion, deletion:There's some confusion right now over what to do with the cursor whenit's offscreen due to scrolling.  This is a policy decision.  I don'tknow what's best.  Spencer criticized me for forcing it to stayonscreen.  It shouldn't be hard to make stuff work with the cursoroffscreen.Currently I've got functions to do insertion and deletion of a singlecharacter.  It's fairly complicated.  In order to do efficient pastinginto the buffer, or write code that modifies the buffer while thebuffer is drawn, it needs to do multiple characters at at time.  Thisis the hardest part of what remains.  Currently, gtk_text_insert doesnot reexpose the modified lines.  It needs to.  Pete did this wrong atone point and I disabled modification completely, I don't know whatthe current state of things are.  The functionsINSERT_CHAR_LINE_EXPOSE and DELETE_CHAR_LINE_EXPOSE do the work.Here's pseudo code for insert.  Delete is quite similar.  insert character into the buffer  update the text property list  move the point  undraw the cursor  correct all LineParams cache entries after the insertion point  compute the new height of the modified line  compare with the old height of the modified line  remove the old LineParams from the cache  insert the new LineParams into the cache  if the lines are of different height, do a copy area to move the    area below the insertion down  expose the current line  update the cursor mark  redraw the cursorWhat needs to be done:Horizintal scrolling, robustness, testing, selection handling.  If youwant to work in the text widget pay attention to the debuggingfacilities I've written at the end of gtktext.c.  I'm sorry I waitedso long to try and pass this off.  I'm super busy with school andwork, and when I have free time my highest priority is another versionof PRCS.Feel free to ask me questions.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -