-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNotes.txt
More file actions
347 lines (255 loc) · 10.8 KB
/
Notes.txt
File metadata and controls
347 lines (255 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
## -*-mode: Outline; fill-prefix: " ";-*-
* Image widget manipulation
** Goals
-- Primarily a navigational tool. Thus for the initial implementation,
I'm not going to worry about getting information back out of it.
(Obviously a worry long-term, but remember interaction; not clear
how to provide a good general interface.)
-- Key attributes:
* Drag scrolling
* Mouse wheel zooming
* Different inputs for image:
* Function that computes data on the fly (maybe
lowest level interface?)
* Single image (large?)
* Multiple tiled image (for intermediate sizes) a la
google maps. I wish I understood google maps
interface.
This suggests that it should be able to output a tiled save
of a large image. Tricky.
* Coordinate display
* Scaled coordinate display (low priority; may not be usable
for ATITD maps, but maybe)
* May compute a range of images around the current image to
handle scrolls, pans, and zooms quickly.
** Plan +
X-- Read in and display a large image file
X-- Allow scrolling via scroll bars.
X-- Figure out how to adapt to resize events in the top level window
X-- Add scrolling via drag
X-- Add coordinate display for mouse in base image terms. Have put in
event handling and callback functions into the interface, but
haven't mapped the coordinates yet. Don't forget about the
problems you had with canvasx/y; they may not be important, but you
should work it out. Probably you should write a quick summary of
all the different coordinate systems and the relationship between
them.
-- Add zooming. This is foundering because the canvas can't handle
too big an image (I think). Going back to doing scrolling and
image re-creation myself; that allows for infinite images anyway
(well, with less tweaking).
-- Add ability to use widget from outside to pick a point in image
terms.
-- Add ability from outside to use widget to choose a rectangle in
image terms.
** Questions
-- Any way to make the init method private, or more generally catch it
when someone tries to create a class directly? (I'm aiming for the
java static method as factory pattern)
** Source notes
*** Trying to understand grid geometry manager
-- Some important files
~/utils/tk8.4.19/generic/tkGrid.c
-- Call graph for ArrangeGrid() (tkGrid.c)
ArrangeGrid
masterPtr = clientData # Set widget being laid out
# Set abort pointer to abort outer layout of this widget, and set
# us up to notice the same thing
Tcl_Preseve(masterPtr) # ??
SetGridSize(masterPtr)
height = ResolveConstraints(masterPtr, COLUMN, 0)
width = ResolveConstraints(masterPtr, ROW, 0)
width += <left & right internal border widths for this widget)
height += <top & bottominternal border heights for this widget)
# Raise width and height to min requested width/height
# if width or height don't match requested width/height
# and the don't propagate flag is *not* set
Tk_GeometryRequest(masterPtr->tkwin, width, height)
# If width or height > 1
mastPtr->flags |= REQUESTED_RELAYOUT
Tcl_DoWhenIdle(ArrangeGrid, masterPtr)
# Reset abort pointer
Tcl_Release(masterPtr)
# else (effectively; there's return above)
# Comemnt says to do weight adjustment if currently requested
# layout size doesn't match parent's window size, which is
# reverse of how I read the above logic???
realWidth = # inside of master
realHeight = # inside of master
GridMaster::startX = AdjustOffsets(realWidth, columns, GridMaster::columnPtr)
GridMaster::startY = AdjustOffsets(realHeight, columns, GridMaster::rowPtr)
GridMaster::startX += <internal_border_left>
GridMaster::startY += <internal_border_top>
# For each slave while we haven't been aborted
# Set col, row for slave
# Set x,y to offsets within grid of this cell
# Set widght, height to width of this cell
# Set x,y to offsets within master space of this cell
# Put window where it belongs.
# If slave a child of ours
# Deal with width/height < 0. Otherwise
# If changing where we're putting slave
Tk_MoveResizeWindow
# Check for aborting
# If Master is mapped
Tk_MapWindow(slave)
# else (not a child of ours)
# Deal with width/height < 0. Otherwise
Tk_MaintainGeometry(slave, master, x, y, width, height)
# Reset abort pointer
Tcl_Release(masterPtr)
ResolveConstraints
# Comment says this resolves all of the row and column boundaries
if (slotType == COLUMN)
(contraintCount, slotCount, slotPtr) =
GridMaster::(columnMax, columnEnd, columnPtr)
else
(contraintCount, slotCount, slotPtr) =
GridMaster::(rowMax, rowEnd, rowPtr)
layoutPtr = <an array of GridLayout large enough to handle the grid+1>
# -1 entry in layout pointer is fake to allow simple computations
layoutPtr->minOffset = 0
layoutPtr->maxOffset = 0
layoutPtr++
# For all constrained slots
layoutPtr[slot].(minSize, weight, uniform, pad, binNextPtr) =
slotPtr[slot].(minSize, weight, uniform, pad, NULL)
# For all remaining slots (after the constrained ones)
layoutPtr[slot].(minSize, weight, uniform, pad, binNextPtr) =
(0, 0, NULL, 0, NULL)
# XXX: Stopping here; this is a long function, and I'm not sure I
# care about the subtleties.
#
# The basic algorithm is: Get what the slaves all want along this
# axis, and create a grid layout that matches. Size from children
# is determined by Tk_ReqWidth + pad + ipad + doubleBw (twice last
# known border width)
# Multiple passes are made over the array to deterine actual size
# based on weight
AdjustOffsets
# Says "adjusts the size of the layout to fit int he space provided,
# distributing extra space according to the weights."
# If weights are zero and extra space, center layout in parent
# If weights are zero, and less space, clip bottom/right
# Add extra space in proportion to the slot weights
# Handle shrinking
Tk_moveResizeWindow
tk_StubsPtr->tk_mvoeResizeWindow
# OR (looks like X version)
XMoveResizeWindow()
TkDoConfigureNotify()
# When a scrollbar receives a configure event, it calls
# TkpComputeScrollbarGeometry. This function is platform specific;
# the one I care about is in ~/utils/tk8.4.19/macosx/tkMacOSXScrlbr.c.
** Todo +
== Convert to self-scroll:
* Make refresh image just grab what's needed and put at 0,0
* Write own scroll functions
*
== Create a description of all interfaces in file (including methods
on ImageWidget) and group them by nature.
== May want to go over mouse move event handling and see how to break
it out more simply. You may well want code separation between
figuring out what the meaning of what the user is doing, and
executing what you want to do in response to that meaning. That
could be made clean.
== Holding the mouse down but leaving and re-entering isn't noticed;
not the best UI.
== Create (and use) transformation function that includes zoom?
== Gotta figure out how to expand gfunc_* interface to properly handle
bounded/unbounded images (returning errors if bad & etc.)
== Reconsider devision to make xview an action rather than an event.
X== There's going to be a lot of duplication between xview_* and
yview_*; refactor? Yep. I think this is done,but I could
eliminate the last little bit with lambda. Nope.
== Should mapping funciton enforce limits? Would make xview/yview
simpler; maybe other places.
** Functions
gfunc_for_image
*** Debugging. Use dbg_ prefix
printCoords -> dbg_print_coords
display_args(*args): -> dbg_display_args
display_event(event): -> dbg_display_event
display_tag_and_size(tag, event): -> dbg_display_tag_and_size
*** Mathematical transform. Use name (noun) describing output
coord_dsq -> distance_squared
mapnum -> mapped_number
*** Widget creation
IWFromFile
IWFromImage
__init__
*** Receiving events. Use ev_<eventname>
buttonPress -> ev_Button_1
mouseMove -> ev_Motion
buttonRelease -> ev_ButtonRelease_1
leaveCanvas -> ev_Leave
mouseWheel -> ev_MouseWheel
Variables just used at this level will be evv_<varname>
*** Event Meanings. Use <name>_action
__drag -> drag_action
-> click_action
-> zoom_action
*** Canvas report of movement
hset
vset
*** General recreateion routines. Just make be refresh.
refresh
reconfigure: Just called for resize
* RFB Protocol Endpoint
** TOC
* Imports
* Keysyms
* class ProtocolEndpoint
* Methods: read, write
* class RFBEndpoint
* class variables for protocol formats
* Exceptions (all class X(Exception): pass)
* Startup methods: __handshake, __initialize, __setup
* User operations: show
* Client message sends (w/ some variants)
* Server message handling:
* List of handlers
* Read a server message (inc helper functions)
* Wait for buffer update
** Cleanup
X-- Create a TOC of the file, and a TOC of the class.
-- Move exceptions out of classes when appropriate? Why are they
class associated rather than module associated?
-- Should you push any entities up to the module level so that you
don't have to do self. for them? Candidates would be the constants
and the functions. Pushing the functions up might give some
advantage in namespace hiding, too. Hmm. Yep, this could work
(can define module namespace by listing public interface in the
__all__ variable (sequence of strings)). Questions:
* Keysyms. Want at top level, under a structure class.
* Base protocol object (relation to final; inherit or delegate?)
* Protocol functions. The thing is, protocol functions need a
socket, so there's no syntactic benefit to not making them
part of an class.
* Screen interaction: Public interface on object.
-- Think about try/finally blocks around closing socket and what state
to leave class in.
-- Think about which encodings to support and how to write the file so
that what you're doing is clear.
-- I want a way to separate the protocol handling methods out from
the functionality methods. In some sense, there should be a class
that *just* implements the protocol, and then a wrapper or
inheritor that implements everything else.
-- Separate file for keysyms?
-- Go over exceptions and regularize (and make sure that "self." is
used)
-- Go over variables and make sure self. is used.
-- Go over debugging printing:
* Right levels?
* All the way up the stack?
* Redirect ok?
-- Look at methods on class; reorganize
** Todo
-- Confirm that failure of an import statement leaves the namespace
clean.
-- Debug: Try to import the darn thing until it works. Do this inside
of emacs, with a python shell around and a keyboard macro that does
the import for you.
-- Think about how your Keysym number hack effects how you want to
manage keysyms. I'd like people to be able to send ascii codes
easily; can they just assume that mapping? Probably.