Fresh IDE . Check-in [f2e6fc9d73]
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Undo/Redo operations work at least for delete. More tests needed of course.
Timelines: family | ancestors | descendants | both | NoCanvasGUI
Files: files | file ages | folders
SHA1:f2e6fc9d73c735f97987923aecd561ee1d411497
User & Date: johnfound 2019-05-02 08:08:38
Context
2019-05-02
09:36
The method TAsmEdit:SplitLine implemented. check-in: 8a219674f9 user: johnfound tags: NoCanvasGUI
08:08
Undo/Redo operations work at least for delete. More tests needed of course. check-in: f2e6fc9d73 user: johnfound tags: NoCanvasGUI
2019-05-01
20:45
Not finished work on Undo/Redo. check-in: 4b75c23dcb user: johnfound tags: NoCanvasGUI
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to freshlib/gui/TAsmEdit.asm.

38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
...
250
251
252
253
254
255
256





257
258
259
260
261
262
263
....
1183
1184
1185
1186
1187
1188
1189


1190
1191
1192
1193
1194
1195
1196
....
3178
3179
3180
3181
3182
3183
3184



3185
3186
3187
3188
3189
3190
3191
....
3204
3205
3206
3207
3208
3209
3210

3211
3212
3213
3214
3215
3216
3217
....
3231
3232
3233
3234
3235
3236
3237

3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248




3249
3250
3251
3252
3253
3254
3255
3256
3257
3258


















































































3259
3260
3261
3262
3263
3264
3265
....
3271
3272
3273
3274
3275
3276
3277


3278















3279



































3280
3281
3282

3283
3284
3285
3286

3287
3288

3289
3290
3291
3292
3293
3294
3295
3296
3297
3298

3299
3300

3301
3302
3303
3304

3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
....
3573
3574
3575
3576
3577
3578
3579


3580
3581
3582
3583
3584
3585
3586


; Operations for undo/redo:

chopInserted = 0
chopDeleted  = 1
chopChanged  = 2


struct TUndoInfo
  .pNext       dd ?       ; pointer to the next TUndoInfo structure in the chain.

  .caretPos    POINT
  .selStart    POINT
  .selEnd      POINT
  .operation   dd ?       ; change operation.

  .line        dd ?       ; the line number affected.
  .pText       dd ?       ; pointer to the previous TTextLine of the affected line for chopChanged and chopDeleted
ends



rstruct TTextLine
................................................................................
  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y
  method .EventMouseMove, .x, .y, .kbdState

endobj









method TAsmEdit.EventMouseMove   ;, .x, .y, .kbdState
begin
        pushad
        mov     esi, [.self]
................................................................................
        exec    esi, TAsmEdit:RectChanged2, 0
        exec    esi, TAsmEdit:UpdateCaretPos

        exec    esi, TAsmEdit:SelChangeBegin
        exec    esi, TAsmEdit:SelStartHere
        exec    esi, TAsmEdit:SelEndHere
        exec    esi, TAsmEdit:SelChangeEnd


        jmp     .finish

.endselect:
        cmp     [esi+TAsmEdit._selCmd], 0
        je      .finish

        exec    esi, TAsmEdit:SelEndHere
................................................................................
        jc      .finish

        mov     edi, eax

        mov     [edi+TUndoInfo.pNext], edx
        mov     [edi+TUndoInfo.operation], ecx




        mov     [esi+TAsmEdit._pUndo], edi

        mov     ecx, [esi+TAsmEdit._caretPos.x]
        mov     edx, [esi+TAsmEdit._caretPos.y]

        mov     [edi+TUndoInfo.line], ebx
        mov     [edi+TUndoInfo.caretPos.x], ecx
................................................................................
        mov     edx, [esi+TAsmEdit._lines]
        shl     ebx, 2

        pos2ofs ebx, edx
        stdcall TextDup, [edx+ebx]

        mov     [edi+TUndoInfo.pText], eax


; now free all redo records, because every new stored undo point invalidates the whole redo list.

.clean_redo:

        mov     ecx, [esi+TAsmEdit._pRedo]
        and     [esi+TAsmEdit._pRedo], 0
................................................................................
        popad
        return
endp



method TAsmEdit.Undo

begin
        pushad

        mov     esi, [.self]
        mov     ebx, [esi+TAsmEdit._lines]

        mov     edi, [esi+TAsmEdit._pUndo]

        test    edi, edi
        jz      .finish         ; nothing to undo.





        mov     edx, [edi+TUndoInfo.pNext]
        mov     [esi+TAsmEdit._pUndo], edx           ; remove from the UNDO list.

        mov     edx, [esi+TAsmEdit._pRedo]
        mov     [edi+TUndoInfo.pNext], edx
        mov     [esi+TAsmEdit._pRedo], edi           ; insert in the REDO list.

; from here is common for undo and redo

.common_undo_redo:



















































































        push    [edi+TUndoInfo.caretPos.x] [esi+TAsmEdit._caretPos.x]
        pop     [edi+TUndoInfo.caretPos.x] [esi+TAsmEdit._caretPos.x] ; xchg caret_x

        push    [edi+TUndoInfo.caretPos.y] [esi+TAsmEdit._caretPos.y]
        pop     [edi+TUndoInfo.caretPos.y] [esi+TAsmEdit._caretPos.y] ; xchg caret_y

................................................................................

        push    [edi+TUndoInfo.selEnd.x] [esi+TAsmEdit._selEnd.x]
        pop     [edi+TUndoInfo.selEnd.x] [esi+TAsmEdit._selEnd.x] ; xchg selEnd_x

        push    [edi+TUndoInfo.selEnd.y] [esi+TAsmEdit._selEnd.y]
        pop     [edi+TUndoInfo.selEnd.y] [esi+TAsmEdit._selEnd.y] ; xchg selEnd_y



















        mov     eax, [edi+TUndoInfo.line]



































        shl     eax, 2          ; in bytes
        pos2ofs eax, ebx


        pushd   [edi+TUndoInfo.pText] [ebx+eax]
        popd    [edi+TUndoInfo.pText] [ebx+eax]      ; xchg TTextLine structures of the line.

        mov     ecx, [edi+TUndoInfo.pText]

        stdcall FreeMem, [ecx+TTextLine.syn_array]
        and     [ecx+TTextLine.syn_array], 0


        mov     ecx, [ebx+eax]
        and     [ecx+TTextLine.syn_array], 0

; fix the horizontal scrollbar size.

        stdcall IncCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx

        mov     ecx, [edi+TUndoInfo.pText]

        stdcall DecCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx



        exec    esi, TAsmEdit:ScrollToCaretY
        exec    esi, TAsmEdit:ScrollToCaretX


        and     [esi+TAsmEdit._img_txt_valid], 0
        and     [esi+TAsmEdit._img_margin_valid], 0
        exec    esi, TAsmEdit:RectChanged2, 0

        exec    esi, TAsmEdit:UpdateCaretPos
        exec    esi, TAsmEdit:UpdateScrollBar

.finish:
        popad
        return
endp



method TAsmEdit.Redo
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [esi+TAsmEdit._lines]

        mov     edi, [esi+TAsmEdit._pRedo]

        test    edi, edi
        jz      methods.TAsmEdit.Undo.finish

        mov     edx, [edi+TUndoInfo.pNext]
        mov     [esi+TAsmEdit._pRedo], edx           ; remove from the REDO list.

        mov     edx, [esi+TAsmEdit._pUndo]
        mov     [edi+TUndoInfo.pNext], edx
        mov     [esi+TAsmEdit._pUndo], edi           ; insert in the UNDO list.

        jmp     methods.TAsmEdit.Undo.common_undo_redo
endp



; Text editing methods




................................................................................


method TAsmEdit.DeleteSelection
.rect RECT
.list dd ?
begin
        pushad



        exec    [.self], TAsmEdit:_AddSelRectanglesAbs, 0
        mov     [.list], edx

        lea     edi, [edx+TArray.array]
        mov     ecx, [edx+TArray.count]
        test    ecx, ecx







>








>







 







>
>
>
>
>







 







>
>







 







>
>
>







 







>







 







>




<
<





>
>
>
>







|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>




>


>










>


>

<
<
|
>

<
<
<
<
<
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
....
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
....
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
....
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
....
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255


3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
....
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456


3457
3458
3459








3460
3461
3462
3463
3464
3465






















3466
3467
3468
3469
3470
3471
3472
....
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712


; Operations for undo/redo:

chopInserted = 0
chopDeleted  = 1
chopChanged  = 2


struct TUndoInfo
  .pNext       dd ?       ; pointer to the next TUndoInfo structure in the chain.

  .caretPos    POINT
  .selStart    POINT
  .selEnd      POINT
  .operation   dd ?       ; change operation.
  .group       dd ?       ;
  .line        dd ?       ; the line number affected.
  .pText       dd ?       ; pointer to the previous TTextLine of the affected line for chopChanged and chopDeleted
ends



rstruct TTextLine
................................................................................
  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y
  method .EventMouseMove, .x, .y, .kbdState

endobj


uglobal
  AsmEditUndoGroup dd ?
endg




method TAsmEdit.EventMouseMove   ;, .x, .y, .kbdState
begin
        pushad
        mov     esi, [.self]
................................................................................
        exec    esi, TAsmEdit:RectChanged2, 0
        exec    esi, TAsmEdit:UpdateCaretPos

        exec    esi, TAsmEdit:SelChangeBegin
        exec    esi, TAsmEdit:SelStartHere
        exec    esi, TAsmEdit:SelEndHere
        exec    esi, TAsmEdit:SelChangeEnd

        inc     [AsmEditUndoGroup]
        jmp     .finish

.endselect:
        cmp     [esi+TAsmEdit._selCmd], 0
        je      .finish

        exec    esi, TAsmEdit:SelEndHere
................................................................................
        jc      .finish

        mov     edi, eax

        mov     [edi+TUndoInfo.pNext], edx
        mov     [edi+TUndoInfo.operation], ecx

        mov     eax, [AsmEditUndoGroup]
        mov     [edi+TUndoInfo.group], eax

        mov     [esi+TAsmEdit._pUndo], edi

        mov     ecx, [esi+TAsmEdit._caretPos.x]
        mov     edx, [esi+TAsmEdit._caretPos.y]

        mov     [edi+TUndoInfo.line], ebx
        mov     [edi+TUndoInfo.caretPos.x], ecx
................................................................................
        mov     edx, [esi+TAsmEdit._lines]
        shl     ebx, 2

        pos2ofs ebx, edx
        stdcall TextDup, [edx+ebx]

        mov     [edi+TUndoInfo.pText], eax
        mov     [eax+TTextLine.syn_array], 0    ; don't copy syntax array pointer!

; now free all redo records, because every new stored undo point invalidates the whole redo list.

.clean_redo:

        mov     ecx, [esi+TAsmEdit._pRedo]
        and     [esi+TAsmEdit._pRedo], 0
................................................................................
        popad
        return
endp



method TAsmEdit.Undo
.group dd ?
begin
        pushad

        mov     esi, [.self]


        mov     edi, [esi+TAsmEdit._pUndo]

        test    edi, edi
        jz      .finish         ; nothing to undo.

        mov     eax, [edi+TUndoInfo.group]
        mov     [.group], eax

.loop:
        mov     edx, [edi+TUndoInfo.pNext]
        mov     [esi+TAsmEdit._pUndo], edx           ; remove from the UNDO list.

        mov     edx, [esi+TAsmEdit._pRedo]
        mov     [edi+TUndoInfo.pNext], edx
        mov     [esi+TAsmEdit._pRedo], edi           ; insert in the REDO list.

        call    __ApplyUndo

        mov     edi, [esi+TAsmEdit._pUndo]
        test    edi, edi
        jz      .refresh

        mov     eax, [edi+TUndoInfo.group]
        cmp     eax, [.group]
        je      .loop

.refresh:
        exec    esi, TAsmEdit:ScrollToCaretY
        exec    esi, TAsmEdit:ScrollToCaretX

        and     [esi+TAsmEdit._img_txt_valid], 0
        and     [esi+TAsmEdit._img_margin_valid], 0
        exec    esi, TAsmEdit:RectChanged2, 0

        exec    esi, TAsmEdit:UpdateCaretPos
        exec    esi, TAsmEdit:UpdateScrollBar

.finish:
        popad
        return
endp



method TAsmEdit.Redo
.group dd ?
begin
        pushad

        mov     esi, [.self]
        mov     ebx, [esi+TAsmEdit._lines]

        mov     edi, [esi+TAsmEdit._pRedo]

        test    edi, edi
        jz      .finish

        mov     eax, [edi+TUndoInfo.group]
        mov     [.group], eax

.loop:
        mov     edx, [edi+TUndoInfo.pNext]
        mov     [esi+TAsmEdit._pRedo], edx           ; remove from the REDO list.

        mov     edx, [esi+TAsmEdit._pUndo]
        mov     [edi+TUndoInfo.pNext], edx
        mov     [esi+TAsmEdit._pUndo], edi           ; insert in the UNDO list.

        call    __ApplyUndo

        mov     edi, [esi+TAsmEdit._pRedo]
        test    edi, edi
        jz      .refresh

        mov     eax, [edi+TUndoInfo.group]
        cmp     eax, [.group]
        je      .loop

.refresh:
        exec    esi, TAsmEdit:ScrollToCaretY
        exec    esi, TAsmEdit:ScrollToCaretX

        and     [esi+TAsmEdit._img_txt_valid], 0
        and     [esi+TAsmEdit._img_margin_valid], 0
        exec    esi, TAsmEdit:RectChanged2, 0

        exec    esi, TAsmEdit:UpdateCaretPos
        exec    esi, TAsmEdit:UpdateScrollBar

.finish:
        popad
        return
endp


; esi - pointer to TAsmEdit
; edi - pointer to TUndoInfo

proc __ApplyUndo
begin
        pushad

        push    [edi+TUndoInfo.caretPos.x] [esi+TAsmEdit._caretPos.x]
        pop     [edi+TUndoInfo.caretPos.x] [esi+TAsmEdit._caretPos.x] ; xchg caret_x

        push    [edi+TUndoInfo.caretPos.y] [esi+TAsmEdit._caretPos.y]
        pop     [edi+TUndoInfo.caretPos.y] [esi+TAsmEdit._caretPos.y] ; xchg caret_y

................................................................................

        push    [edi+TUndoInfo.selEnd.x] [esi+TAsmEdit._selEnd.x]
        pop     [edi+TUndoInfo.selEnd.x] [esi+TAsmEdit._selEnd.x] ; xchg selEnd_x

        push    [edi+TUndoInfo.selEnd.y] [esi+TAsmEdit._selEnd.y]
        pop     [edi+TUndoInfo.selEnd.y] [esi+TAsmEdit._selEnd.y] ; xchg selEnd_y

        mov     ebx, [esi+TAsmEdit._lines]
        mov     eax, [edi+TUndoInfo.operation]

        cmp     eax, chopChanged
        je      .op_changed

        cmp     eax, chopDeleted
        je      .op_deleted

        cmp     eax, chopInserted
        je      .op_inserted

        int3           ; INVALID OPERATION
        jmp     .finish

.op_inserted:
        mov     [edi+TUndoInfo.operation], chopDeleted

        mov     eax, [edi+TUndoInfo.line]
        shl     eax, 2
        stdcall TextMoveGap, ebx, eax

        mov     eax, [ebx+TText.GapEnd]
        mov     ecx, [ebx+eax]

        mov     [edi+TUndoInfo.pText], ecx

        stdcall FreeMem, [ecx+TTextLine.syn_array]
        and     [ecx+TTextLine.syn_array], 0
        add     [ebx+TText.GapEnd], 4

        stdcall DecCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx

        jmp     .finish

.op_deleted:

        mov     [edi+TUndoInfo.operation], chopInserted

        mov     eax, [edi+TUndoInfo.line]
        shl     eax, 2
        stdcall TextMoveGap, ebx, eax
        stdcall TextSetGapSize, ebx, 4
        mov     [esi+TAsmEdit._lines], edx
        mov     ebx, edx
        mov     eax, [ebx+TText.GapBegin]
        and     dword [ebx+eax], 0
        add     [ebx+TText.GapBegin], 4
        jmp     .restore_txt


.op_changed:
        mov     eax, [edi+TUndoInfo.line]
        shl     eax, 2          ; in bytes
        pos2ofs eax, ebx

.restore_txt:
        pushd   [edi+TUndoInfo.pText] [ebx+eax]
        popd    [edi+TUndoInfo.pText] [ebx+eax]      ; xchg TTextLine structures of the line.

        mov     ecx, [edi+TUndoInfo.pText]
        jecxz   @f
        stdcall FreeMem, [ecx+TTextLine.syn_array]
        and     [ecx+TTextLine.syn_array], 0
@@:

        mov     ecx, [ebx+eax]
        and     [ecx+TTextLine.syn_array], 0

; fix the horizontal scrollbar size.

        stdcall IncCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx

        mov     ecx, [edi+TUndoInfo.pText]
        jecxz   @f
        stdcall DecCount, [esi+TAsmEdit._line_widths], [ecx+TTextLine.ch_len]
        mov     [esi+TAsmEdit._line_widths], edx
@@:



.finish:
;        OutputValue "Operation after: ", [edi+TUndoInfo.operation], 10, -1









        popad
        return
endp



























; Text editing methods




................................................................................


method TAsmEdit.DeleteSelection
.rect RECT
.list dd ?
begin
        pushad

        inc     [AsmEditUndoGroup]

        exec    [.self], TAsmEdit:_AddSelRectanglesAbs, 0
        mov     [.list], edx

        lea     edi, [edx+TArray.array]
        mov     ecx, [edx+TArray.count]
        test    ecx, ecx