GUI for Logical Analyser

Share your advanced PureBasic knowledge/code with the community.
peterb
User
User
Posts: 60
Joined: Sun Oct 02, 2005 8:55 am
Location: Czech Republic
Contact:

GUI for Logical Analyser

Post by peterb »

Hi, here is code for GUI for logical analyser. I had planned to create GUI + hardware, but i don't have a time to create hardware. You may create your own hardware, or add plugin and use with existing hardware.

It's optimized for fast speed views and large data blocks.

left mouse click - zoom in
right mouse click - zoom out
left mouse drag - move left / right
right mouse drag - zoom selected block
ctrl + left mouse - mark 1
ctr + right mouse - mark 2

Enjoy this :-)


Code: Select all



EnableExplicit


;{ COLORS

  #grey000          = 0
  #grey030          = 1973790
  #grey050          = 3289650
  #grey060          = 3947580
  #grey080          = 5263440
  #grey100          = 6579300
  #grey120          = 7895160
  #grey140          = 9211020
  #grey160          = 10526880
  #grey200          = 13158600
  #grey240          = 15790320
  #grey255          = 16777215
  #bck_color        = 3947580
  #pulse_color      = 65525
  #pulse_color_dark = 30840
  #move_line        = 65535

;}


;{ ENUMERATION

Enumeration

  #main_window

  #Image_0
  #Image_1
  #Image_2
  #logo_img_gadget
  #M1
  #M2
  #Image_Tools
  
  #Scroll

  #pin1 = 80
  #pin2
  #pin3
  #pin4
  #pin5
  #pin6
  #pin7
  #pin8

  #pin1_active = 90
  #pin2_active
  #pin3_active
  #pin4_active
  #pin5_active
  #pin6_active
  #pin7_active
  #pin8_active

  #s_bit_1 = 100
  #s_bit_2
  #s_bit_3
  #s_bit_4
  #s_bit_5
  #s_bit_6
  #s_bit_7
  #s_bit_8
  
  #e_bit_1
  #e_bit_2
  #e_bit_3
  #e_bit_4
  #e_bit_5
  #e_bit_6
  #e_bit_7
  #e_bit_8

  #info_width_header = 200
  #info_period_header
  #info_byte_header
  #info_width
  #info_period
  #info_byte
  #info_byte_nl

  #img_pin_numbers
  #img_data
  #img_data_clear
  #img_data_temp
  #img_info_bar
  #logo
  #img_tools
  #img_tools_clear

  #verdana_font08
  #verdana_font10
  #verdana_font12
  #verdana_font20

  #zoom_in
  #zoom_out
  #mouse_over
  #mouse_down

  #first_tool = 1
  
  #tool_delete_from_mark
  #tool_delete_from_mark_to_mark
  #tool_delete_to_mark

  #tool_io
  #tool_test_signal
  
  #tool_settings

  #tool_jump_to_start = 13
  #tool_jump_to_end

  #tool_plus
  #tool_minus

  #tool_show_all

  #tool_one
  #tool_show_from_mark_to_mark
  #tool_two

  #tool_reset = 24

  #last_tool = 24

  #info_cycle_from
  #info_cycle
  #info_cycle_to

  #button_get_data

EndEnumeration

;}


;{ STRUCTURES

  Structure ANALYZED_DATA
    pin.b
    state.b
    cycle_from.l
    cycle_to.l
    next_id.l
  EndStructure

  Structure VIEWED_DATA
    pin.b
    cycle_from.l
    cycle_to.l
    cycle_from_position.w
    cycle_to_position.w
  EndStructure

  Structure MYPLUG
    Lib.l
    Name.s
    Author.s
    Path.s
    Description.s
    Version.s
    Exit.l
    Func_Config.l
    Func_GetData.l

  EndStructure

;}


;{ LOAD FONTS

  Global fnt_v08 = LoadFont ( #verdana_font08, "Verdana", 8,  #PB_Font_HighQuality )
  Global fnt_v10 = LoadFont ( #verdana_font10, "Verdana", 10, #PB_Font_HighQuality )
  Global fnt_v12 = LoadFont ( #verdana_font12, "Verdana", 12, #PB_Font_HighQuality )
  Global fnt_v20 = LoadFont ( #verdana_font20, "Verdana", 20, #PB_Font_HighQuality )

;}


;{ GLOBALS

  #BS_FLAT = $8000 

  Define.l Event
  Define.l EventWindow
  Define.l EventGadget
  Define.l EventType
  Define.l EventMenu
  Define.l loop
  Define.l new_scroll_position
  Define.l page_length
  Define.l scroll_position
  Define.l x
  Define.l y
  Define.l c

  Global main_window_hwnd
  Global view_rect.RECT
  Global tool_rect.RECT
    
  Global move_state                = #False
  Global view_state                = #False
  Global select_state              = #False
  
  Global point.POINT

  Global info_text_show            = #False

  Global drag_view                 = 0
  Global drag_start                = 0
  Global drag_pos                  = 0

  Global select_view               = 0
  Global select_start              = 0
  Global select_pos                = 0
  
  Global view_posx                 = 0
  Global view_posy                 = 0

  Global data_size                 = 0
  Global data_size_m1              = 0

  Global cycle_start               = 0
  Global cycle_end                 = 0
  Global cycle_length              = 0
  Global pixels_per_cycle.f        = 0
  Global half_pixels_per_cycle.f   = 0

  Global mark_1_pos                = -1
  Global mark_2_pos                = -1
  Global mark_2_val                = 0
  Global mark_1_val                = 0
  
  Global *data_buffer              = 0
  Global infobar_frame.f           = 0
  
  Global info_text_show            = #False
  
  Global tool_button_id            = 0
  Global active_tool_id            = 0
  Global active_tool_state         = #Null
  Global is_tools_clear            = #True

  Global buffer_length             = 131072
  Global *view_mask_data 

  Global last_show_pulse_pin
  Global last_show_pulse_from
  Global last_show_pulse_to

  Global last_open_path.s          = ""
  Global last_save_path.s          = ""

  Global time_tick.f               = 0

  Global PluginLib

  Global Dim is_pin_active.b   ( 8 )
  Global Dim infobar.l         ( 8, 700 )
  Global Dim first_pin_index.l ( 0 )

  Global NewList an_data.ANALYZED_DATA()
  Global NewList vi_data.VIEWED_DATA()
  Global NewList LoadedPlugins.MYPLUG()

;}

Declare GenerateData     ( size, precision )
Declare ClearVariables   ( )
Declare AnalyzeData      ( post_analyze = #False )
Declare UpdateScrollBar  ( )
Declare RedrawInfobar    ( )
Declare RedrawData       ( )
Declare SetMarkPos       ( mark_id, px )
Declare ShowPulse        ( pin, p_from, p_to, p_from_next = 0, p_to_next = 0 )
Declare CheckPinActive   ( )
Declare ZoomView         ( type, position )
Declare MoveView         ( px, move, type )
Declare SelectView       ( px, move, type )
Declare ClearView        ( )
Declare CheckViewArea    ( px, py )
Declare ImageViewProc    ( hwnd, msg, wParam, lParam )
Declare.l WinCallback      ( hwnd, msg, wparam, lparam )
Declare GadgetColor      ( gadget, back_color, front_color )
Declare OpenMainWindow   ( )


;{ SET DEFAULT

  For loop = 0 To 7
    is_pin_active( loop ) = 1

  Next
  
  *view_mask_data = AllocateMemory ( buffer_length )
  
;}


Procedure.s FormatTimeString ( cycles, time.f )

  Protected tf.f

  If time > 0
  
    tf = cycles * time
    
    If tf > 1000
      tf = tf / 1000
      
      ProcedureReturn " ( " + StrF ( tf, 1 ) + " ms ) "
      
    Else
      ProcedureReturn " ( " + StrF ( tf, 1 ) + " us ) "
    
    EndIf
    
  
  Else
    ProcedureReturn ""
  
  EndIf
  
EndProcedure 


Procedure CorrectCycles ( )

  Protected cl, temp

  cl = cycle_end - cycle_start

  If cl >= data_size_m1 - 6
    cycle_start = 0
    cycle_end   = data_size_m1
    
  Else
  
    If cl < 6
      cl = ( 6 - cl ) / 2
      cycle_start = cycle_start - cl
      cycle_end   = cycle_end   + cl

    EndIf
  
    If cycle_start < 0
      cycle_end   = cycle_end - cycle_start
      cycle_start = 0
      
      If cycle_end > data_size_m1 : cycle_end = data_size_m1 : EndIf
  
    ElseIf cycle_end > data_size_m1
      cycle_start = cycle_start - ( cycle_end - data_size_m1 )
      cycle_end   = data_size_m1
      
      If cycle_start < 0 : cycle_start = 0 : EndIf

    EndIf
  EndIf

  cycle_length          = cycle_end        - cycle_start
  pixels_per_cycle      = 700              / cycle_length
  half_pixels_per_cycle = pixels_per_cycle / 2
  
EndProcedure


Procedure DrawAnalyze ( )

  Protected max_cycle, next_an_data_id, cycle_count, counter

  max_cycle       = data_size_m1
  next_an_data_id = 0
  cycle_count     = 0

  ResetList ( an_data() )

  While NextElement ( an_data() )

    If next_an_data_id = 0
      next_an_data_id = an_data()\next_id

    EndIf
    
    If cycle_count = 100
      If an_data()\cycle_to < max_cycle
        max_cycle = an_data()\cycle_to
      
      EndIf

      If next_an_data_id > 0
        SelectElement ( an_data(), next_an_data_id )
        next_an_data_id = 0

      EndIf
      
      cycle_count = 0

    Else
      cycle_count + 1

    EndIf    
    
  Wend

  cycle_start = 0
  cycle_end   = max_cycle

EndProcedure


Procedure GenerateData ( size, precision )
  
  Protected c, d
  Protected value.b = 0

  If precision < 0 : precision = 1 : EndIf
  If precision > 6 : precision = 6 : EndIf

  data_size    = 0
  data_size_m1 = 0
  time_tick    = 0

  If *data_buffer
    *data_buffer = ReAllocateMemory ( *data_buffer, size )
  
  Else
    *data_buffer = AllocateMemory ( size )
  
  EndIf
  
  If *data_buffer

    data_size    = size
    data_size_m1 = size - 1
    c            = 0
    
    Repeat
      For d = 0 To precision - 1
        If c + d < data_size_m1
          PokeB ( *data_buffer + c + d, value )
        
        EndIf

      Next
      
      If value = 255 : value = 0 : Else : value + 1 : EndIf
      
      c + precision
    
    Until c >= data_size_m1
   
  EndIf

EndProcedure


Procedure GenerateRandomData ( size )

  Protected c, d, length

  If *data_buffer
    ReAllocateMemory ( *data_buffer, size )
  
  Else
    *data_buffer = AllocateMemory ( size )
  
  EndIf

  time_tick    = 0
  data_size    = 0
  data_size_m1 = 0

  If *data_buffer

    data_size    = size
    data_size_m1 = size - 1

    c = 0
    
    Repeat
    
      length = Random (  20 )

      If c + length > data_size_m1
        length = data_size_m1 - c
        
      EndIf
    
      For d = 0 To length
        PokeB ( *data_buffer + c + d, Random ( 255 ) )
        
      Next      
    
      c + length
    Until c >= data_size_m1
    
  EndIf

EndProcedure


Procedure AnalyzeData ( post_analyze = #False )

  Protected mask.b, pin, mem_pos, change_pulse, px, m
  Protected previous_state.b,  previous_level, lindex, pin_6_last_index

  Protected start_time, end_time

  mark_1_pos  = -1
  mark_2_pos  = -1
  mark_2_val  = 0
  mark_1_val  = 0
  cycle_start = 0
  cycle_end   = 0
  
  ReDim first_pin_index ( 0 )

  For m = 0 To buffer_length - 1 : PokeB ( *view_mask_data + m, -1 ) : Next
  
  infobar_frame = 0
  If data_size : infobar_frame = data_size / 700 : EndIf
  
  For pin = 0 To 7
    For px = 1 To 699
        infobar ( pin, px ) = 0

    Next
  Next
    
  ClearList ( an_data() )
  
  If data_size
  
    For pin = 0 To 7
  
      mask           = 1 << pin
      previous_state = PeekB ( *data_buffer ) & mask
      change_pulse   = 0

      For mem_pos = 1 To data_size_m1

        If previous_state = PeekB ( *data_buffer + mem_pos ) & mask : Continue : EndIf

        px = change_pulse / infobar_frame
        infobar ( pin, px ) + 1

        AddElement ( an_data() )
        an_data()\pin        = pin
        an_data()\state      = previous_state
        an_data()\cycle_from = change_pulse
        an_data()\cycle_to   = mem_pos - 1

        change_pulse         = mem_pos
        previous_state       = PeekB ( *data_buffer + mem_pos ) & mask
       
      Next

      AddElement ( an_data() )

      an_data()\pin        = pin
      an_data()\state      = previous_state
      an_data()\cycle_from = change_pulse
      an_data()\cycle_to   = mem_pos - 1

      If pin = 6 : pin_6_last_index = ListIndex ( an_data () ) : EndIf

    Next
  
  EndIf

  If post_analyze = #True
  
    Protected Dim po_data.l ( data_size )
    ReDim first_pin_index ( data_size )

    If ArraySize ( po_data () )

      SelectElement ( an_data(), pin_6_last_index )
      
      Repeat

        lindex            = ListIndex ( an_data() )
        an_data()\next_id = po_data ( an_data()\cycle_from )
        
        For mem_pos = an_data()\cycle_from To an_data()\cycle_to
          po_data ( mem_pos ) = lindex
    
        Next
      Until PreviousElement ( an_data() ) = 0
   
    EndIf
  
    ResetList ( an_data() )
    
    ForEach an_data()
      
      If an_data()\pin <> 0 : Break : EndIf
    
      lindex = ListIndex ( an_data() )
      
      For mem_pos = an_data()\cycle_from To an_data()\cycle_to
        first_pin_index ( mem_pos ) = lindex
 
      Next
    Next
  
  EndIf

  cycle_start = 0
  cycle_end   = data_size_m1

EndProcedure


Procedure UpdateScrollBar ( )

  Protected pixel_pc.f, x_start, x_lenght, dc

  SetGadgetAttribute ( #Scroll, #PB_ScrollBar_PageLength, cycle_length  )
  SetGadgetAttribute ( #Scroll, #PB_ScrollBar_Maximum,    data_size_m1  )
  SetGadgetAttribute ( #Scroll, #PB_ScrollBar_Minimum,    0             )
  SetGadgetState     ( #Scroll, cycle_start )

  pixel_pc = 700         / data_size
  x_start  = cycle_start * pixel_pc
  x_lenght = cycle_end   * pixel_pc - x_start
    
  If x_lenght = 0 : x_lenght = 1 : EndIf

  If StartDrawing ( ImageOutput ( #img_info_bar ) )
    Box (       0, 0,      700, 3, #bck_color   )
    Box ( x_start, 0, x_lenght, 3, #pulse_color )
    StopDrawing ( )

  EndIf
  
  SetGadgetState ( #Image_2, ImageID ( #img_info_bar ) )
  
EndProcedure 


Procedure RedrawInfobar ( )

  Protected pin, px, frame_maximum_value, frame_div.f, value, dc

  If infobar_frame > 0

    For pin = 0 To 7
      For px = 1 To 699
        value = infobar ( pin, px )
        If frame_maximum_value < value : frame_maximum_value = value : EndIf

      Next
    Next

  EndIf
  
  frame_maximum_value + 1

  frame_div = 99 / frame_maximum_value
  
  dc = StartDrawing ( ImageOutput ( #img_info_bar ) )
  If dc
 
    Box ( 0, 3, 700, 12, #grey140 )
    Box ( 1, 5, 698,  9, #grey030 )

    For pin = 0 To 7
      For px = 1 To 698
  
        value = infobar ( pin, px )

        If value > 0
          value = 155 + ( value * frame_div )
            
          SetPixel_ ( dc, px, pin + 6, value << 8 )

        EndIf

      Next
    Next
    
    StopDrawing ()
  EndIf

  SetGadgetState ( #Image_2, ImageID ( #img_info_bar ) )

EndProcedure

Procedure RedrawHeader ( )

  Protected c, nd, ce, x, y, pos, dc, color, text.s, level, cp2, cm2
  Protected d = 1
  Protected n = 1

  Protected Dim header.l ( 700, 2 )

  Dim PolygonArray.l ( 5 )

  For c = 1 To 17
    nd = d * n

    Select d
      Case 1  : d = 5
      Case 5  : d = 25
      Case 25 : d = 50
      Case 50 : d = 1  : n = n * 100
    
    EndSelect
    
    If cycle_length / nd > 13 : Continue : EndIf

    ce = cycle_end
    Repeat 
      x   = ( ce / nd         ) * nd
      pos = ( x - cycle_start ) * pixels_per_cycle + half_pixels_per_cycle
             
      If pos > 5 And pos < 695
        header ( pos, 1 ) + 1
        header ( pos, 2 ) = x

      EndIf
      ce - nd
    Until ce < cycle_start

  Next

  dc = StartDrawing ( ImageOutput ( #img_data_temp ) )
  If dc

    DrawingMode  ( #PB_2DDrawing_Transparent  )
    DrawingFont  ( FontID ( #verdana_font08 ) )

    PolygonArray ( 1 ) = 41
    PolygonArray ( 3 ) = 41
    PolygonArray ( 5 ) = 47

    For c = 0 To 699
    
      level = header ( c, 1 )

      If level = 0 : Continue : EndIf

      text  = Str ( header ( c, 2 ) )
      x     = c - ( TextWidth ( text ) >> 1 )
      y     = 15
      color = #grey240
      
      If level = 1
        y + 10 : color = #grey160

      ElseIf level = 2
        y +  5 : color = #grey200

      EndIf

      FrontColor   ( color )
      
      DrawText     ( x, y, text )
  
      PolygonArray ( 0 ) = c - 2
      PolygonArray ( 2 ) = c + 2
      PolygonArray ( 4 ) = c
     
      Polygon_     ( dc, @PolygonArray(), 3 )
      
      For d = 50 To 306 Step 32
        
        LineXY ( c, d, c, d + 2, #grey200 )

      Next

    Next
  
    SetGadgetText ( #info_cycle_from, Str ( cycle_start ) )
    SetGadgetText ( #info_cycle, "In View: " + Str ( cycle_end - cycle_start ) + "     Data size: " + Str ( data_size ) )
    SetGadgetText ( #info_cycle_to,   Str ( cycle_end   ) )
    
    StopDrawing ()
    
  EndIf

EndProcedure


Procedure RedrawData ( )

  Protected mem, c, ce, x, y, dc, color, mark_pos, active_pen, inactive_pen, pen
  Protected text.s, text_cycle_start.s, text_cycle_end.s
  Protected last_pos_from, last_active_pin, last_line_color
  Protected mem_pos, next_an_data_id
  Protected c_from, c_to, c_pin, state
  Protected pos_from, pos_to, pos_len, pin, center_y, counter, index, lindex, cycle_start_m1
  Protected level_high, level_low, level, *DLONG.LONG
    
  CorrectCycles ( )

  If cycle_start = 0 And cycle_end = 0 : ProcedureReturn 0 : EndIf

  For mem = *view_mask_data To *view_mask_data + buffer_length - 1 : PokeB ( mem, -1 ) : Next
  
  ClearList    ( vi_data() )
  CopyImage    ( #img_data_clear, #img_data_temp )
  RedrawHeader ( )

  cycle_start_m1 = cycle_start - 1

  dc = StartDrawing ( ImageOutput ( #img_data_temp ) )
  If dc

    last_pos_from   = -1
    last_active_pin = -1
    last_line_color = -1
    mem_pos         = *view_mask_data

    next_an_data_id = 0

    If ArraySize ( first_pin_index () ) > cycle_start And cycle_start > 0
      index = first_pin_index ( cycle_start ) - 2
      If index < 0
        ResetList ( an_data() )

      Else 
        SelectElement ( an_data(), index )

      EndIf
      
    Else  
      ResetList ( an_data() )
    
    EndIf    
    
    active_pen   = CreatePen_ ( #PS_SOLID, 1, #grey255 )
    inactive_pen = CreatePen_ ( #PS_SOLID, 1, #grey080 )
    
    While NextElement ( an_data() )

      c_from   = an_data()\cycle_from
      c_to     = an_data()\cycle_to
      c_pin    = an_data()\pin

      pos_from = ( c_from - cycle_start    ) * pixels_per_cycle
      pos_to   = ( c_to   - cycle_start_m1 ) * pixels_per_cycle
      pos_len  = pos_to - pos_from

      If last_pos_from = pos_from And pos_len = 0 : Continue : EndIf

      If c_from > cycle_end 
        If c_pin = 7 : Break : EndIf
        
        If next_an_data_id > 0
          SelectElement ( an_data(), next_an_data_id - 1 )
          next_an_data_id = 0

        EndIf
        Continue

      EndIf

      If next_an_data_id = 0 : next_an_data_id = an_data()\next_id : EndIf

      If last_active_pin <> c_pin

        If is_pin_active ( c_pin ) : pen = active_pen : Else : pen = inactive_pen : EndIf

        SelectObject_( dc, pen )
        
        last_active_pin = c_pin
        mem_pos         = *view_mask_data + c_pin << 12

        center_y        = 66 + ( c_pin << 5 )
        level_high      = center_y - 9
        level_low       = center_y + 10
      
      EndIf

      FrontColor ( RGB ( 0,0,0 ) )

      If an_data()\state
        MoveToEx_ ( dc, pos_from, level_low, #Null )
        LineTo_   ( dc, pos_from, level_high       )
        level = level_high

      Else
        MoveToEx_ ( dc, pos_from, level_high, #Null )
        LineTo_   ( dc, pos_from, level_low         )
        level = level_low

      EndIf

      If pos_len
        LineTo_   ( dc, pos_to,  level )

        If pos_len > 1
          If pos_from < 0   : pos_from = 0   : EndIf
          If pos_to   > 700 : pos_to   = 700 : EndIf
  
          AddElement ( vi_data() )
          With vi_data()
            \pin                 = c_pin
            \cycle_from          = c_from
            \cycle_to            = c_to
            \cycle_from_position = pos_from
            \cycle_to_position   = pos_to          

          EndWith

          lindex = ListIndex ( vi_data() )

          For mem = mem_pos + pos_from << 2 To mem_pos + pos_to << 2 Step 4
            *DLONG.LONG = mem   
            *DLONG\l    = lindex

          Next
        EndIf

      EndIf

      last_pos_from = pos_from

    Wend  

    LineXY ( 0, 0, 0, 306, #bck_color )

    DrawingFont ( FontID ( #verdana_font08 ) )

    For c = 1 To 2
      Select c
        Case 1
          mark_pos = mark_1_pos
          color    = #Red
          text     = "M1"
        
        Case 2
          mark_pos = mark_2_pos
          color    = #Blue
          text     = "M2"

      EndSelect

      If mark_pos > -1
        mark_pos = ( mark_pos - cycle_start ) * pixels_per_cycle + half_pixels_per_cycle

        If mark_pos >= 0 And mark_pos < 700
          LineXY   ( mark_pos, 50, mark_pos, 306, color )
          DrawText ( mark_pos - ( TextWidth ( text ) >> 1 ), 5, text, #grey000, color )

        EndIf

      EndIf
    Next
  
    DeleteObject_( active_pen   )
    DeleteObject_( inactive_pen )
  
    StopDrawing ()
  EndIf


  CopyImage      ( #img_data_temp, #img_data             )
  SetGadgetState ( #Image_1,       ImageID ( #img_data ) )

  UpdateScrollBar ()

EndProcedure


Procedure SetMarkBits ( id, mark_val )

  Protected mask, bit_from, bit_to, c

  mask = 1
  
  If id = 1
    bit_from = #s_bit_1
    bit_to   = #s_bit_8
  
  Else
    bit_from = #e_bit_1
    bit_to   = #e_bit_8
  
  EndIf
  
  For c = bit_from To bit_to
    
    If mark_val & mask
      SetGadgetText ( c, "1" )
    
    Else
      SetGadgetText ( c, "0" )
      
    EndIf

    mask << 1
    
  Next

EndProcedure


Procedure SetMarkPos ( mark_id, px )

  Protected cycle_under_mouse, mask, c

  cycle_under_mouse = Round ( cycle_start + ( px / pixels_per_cycle ), #PB_Round_Down )

  Select mark_id

    Case 1
      mark_1_pos = cycle_under_mouse
      mark_1_val = PeekB ( *data_buffer + mark_1_pos )
      
    Case 2
      mark_2_pos = cycle_under_mouse
      mark_2_val = PeekB ( *data_buffer + mark_2_pos )
    
  EndSelect 

  SetMarkBits ( 1, mark_1_val )
  SetMarkBits ( 2, mark_2_val )

  RedrawData ( )


EndProcedure


Procedure ResetView ()

  Protected loop
  
  For loop = 0 To 7
    is_pin_active( loop ) = 1

  Next

  mark_1_pos = -1
  mark_2_pos = -1
  mark_2_val = 0
  mark_1_val = 0

  SetMarkBits ( 1, 0 )
  SetMarkBits ( 2, 0 )

  DrawAnalyze ()
  RedrawData ( )

EndProcedure


Procedure ShowPulse ( pin, p_from, p_to, p_from_next = 0, p_to_next = 0 ) ; OK

  Protected p_from_s2, p_to_e1, center_y

  CopyImage ( #img_data_temp, #img_data )
  
  If p_to - p_from > 1

    If StartDrawing ( ImageOutput ( #img_data ) )

      If is_pin_active ( pin )
        FrontColor ( #pulse_color      )
      
      Else
        FrontColor ( #pulse_color_dark )
      
      EndIf
      
      center_y    = 66 + ( pin << 5 )
      p_from_s2   = p_from   + 2
      p_to_e1     = p_to     - 1

      LineXY ( p_from + 1, center_y, p_to, center_y )

      If p_from      >   0 : LineXY ( p_from      + 3, center_y - 2, p_from    + 3, center_y + 2 ) : Else : p_from_s2 - 1 : EndIf
      If p_to        < 699 : LineXY ( p_to        - 2, center_y - 2, p_to      - 2, center_y + 2 ) : Else : p_to_e1   + 1 : EndIf
      If p_from_next       : LineXY ( p_from_next + 2, center_y,     p_to_next - 1, center_y     ) : EndIf
      If p_to_next   < 699 : LineXY ( p_to_next   - 3, center_y - 1, p_to_next - 3, center_y + 1 ) : EndIf

      LineXY ( p_from_s2, center_y + 1, p_to_e1, center_y + 1 )
      LineXY ( p_from_s2, center_y - 1, p_to_e1, center_y - 1 )

      view_state = #True
    
      StopDrawing ()
    EndIf
  EndIf
  
  SetGadgetState ( #Image_1, ImageID ( #img_data ) )

EndProcedure


Procedure CheckPinActive ( )

  Protected c, state, changed = #False
  
  For c = 0 To 7
    state = GetGadgetState ( #pin1_active + c )
    
    If is_pin_active ( c ) <> state
      changed = #True
      
    EndIf
    is_pin_active ( c ) = state
  
  Next

  If changed = #True : RedrawData ( ) : EndIf

  SetActiveGadget ( #Image_1 )

EndProcedure


Procedure ZoomView ( type, position ) ; OK

  Protected old_cycle_start, old_cycle_end, zoom_factor.f, from_pos_to_start, from_pos_to_end

  If cycle_end > 0

    If type = #zoom_in 

      If cycle_length <= 6
        RedrawData ( )
        ProcedureReturn #False
        
      EndIf
      zoom_factor = 0.2
    
    Else
      zoom_factor = -0.25
    
    EndIf
  
    old_cycle_start   = cycle_start
    old_cycle_end     = cycle_end
  
    from_pos_to_start = position / pixels_per_cycle
    from_pos_to_end   = cycle_end   - ( cycle_start + from_pos_to_start )
    cycle_start       = cycle_start + ( from_pos_to_start * zoom_factor )
    cycle_end         = cycle_end   - ( from_pos_to_end   * zoom_factor )
    
    CorrectCycles ( ) 
  
    If old_cycle_start <> cycle_start Or old_cycle_end <> cycle_end
      RedrawData ( )
    
    EndIf
  EndIf
  
EndProcedure


Procedure MoveView ( px, move, type ) ; OK

  Protected px_move, cycle_move, move_state, x, x_from, x_to, move_text.s, new_start, new_end

  view_state          = #False
  px_move             = px - move

  cycle_move  = ( px / pixels_per_cycle ) - ( px_move / pixels_per_cycle )
  
  If type = 0
    move_state = #True

    If px_move < px : Swap px_move, px  : EndIf

    x_from     = px     + 1
    x_to       = x_from + ( px_move - x_from )

    If move    > 0  : Swap x_from, x_to : EndIf
   
    CopyImage ( #img_data_temp, #img_data )
    
    If StartDrawing ( ImageOutput ( #img_data ) )
      FrontColor ( #move_line )
      LineXY     ( x_from, 50, x_from, 306 )
     
      For x = x_to - 1 To x_to + 1
        LineXY ( x, 50, x, 306 )
      
      Next
      
      StopDrawing ()
    EndIf
      
    SetGadgetState ( #Image_1, ImageID ( #img_data ) )
    
    new_start = cycle_start - cycle_move
    new_end   = cycle_end   - cycle_move

    If new_start < 0
      new_start = 0
      new_end   = cycle_end
    
    EndIf
    
    If new_end > data_size_m1
      new_start = data_size_m1 - ( cycle_end - cycle_start )
      new_end   = data_size_m1

    EndIf

    move_text = "MOVE:   "
    
    If cycle_move > 0
      move_text + "- "
      

    Else
      move_text + "+ "
      cycle_move = 0 - cycle_move
     
    EndIf
    move_text + Str ( cycle_move ) + "     New start: " + Str ( new_start ) + "     New end: " + Str ( new_end )
    
    SetGadgetText ( #info_cycle, move_text )
  
  Else

    cycle_start = cycle_start - cycle_move
    cycle_end   = cycle_end   - cycle_move
    move_state  = #False
    
    RedrawData    ( )

  EndIf

EndProcedure


Procedure SelectView ( px, move, type )

  Protected px_move, dc, cl, x_from, x_width, new_start, new_end
  
  view_state  = #False
  px_move     = px - move
  
  If type = 0
    select_state  = #True

    CopyImage ( #img_data_temp, #img_data )
    
    dc = StartDrawing ( ImageOutput ( #img_data ) )
    If dc
      
      If px_move > px : Swap px_move, px : EndIf

      x_from  = px      + 1
      x_width = px_move - x_from

      PatBlt_    ( dc, x_from, 50, x_width, 256, #DSTINVERT ) 

      LineXY     ( px_move, 50, px_move, 306, #move_line )
      LineXY     ( px,      50, px,      306, #move_line )
      
      StopDrawing ()
    EndIf
      
    SetGadgetState ( #Image_1, ImageID ( #img_data ) )

    Swap px_move, px
    new_start = cycle_start + ( px      / pixels_per_cycle )
    new_end   = cycle_start + ( px_move / pixels_per_cycle )
    
    SetGadgetText ( #info_cycle, "ZOOM:   New start: " + Str ( new_start ) + "     New end: " + Str ( new_end ) + "     Length: " + Str ( new_end - new_start ) )
  
  Else
    cycle_end   = cycle_start + ( px_move / pixels_per_cycle )
    cycle_start = cycle_start + ( px      / pixels_per_cycle )
    
    If cycle_end < cycle_start : Swap cycle_end, cycle_start : EndIf
  
    RedrawData ()
  
  EndIf

EndProcedure


Procedure ClearView  ( )

  CopyImage      ( #img_data_temp, #img_data       )
  SetGadgetState ( #Image_1, ImageID ( #img_data ) )

  view_state   = #False
  move_state   = #False
  select_state = #False
  
  SetGadgetText ( #info_width,  "#" )
  SetGadgetText ( #info_period, "#" )
  
EndProcedure


Procedure CheckViewArea ( px, py )

  Protected pin,                vd_pin,             vi_index,           vi_index_next
  Protected from_pos,           from_pos_next,      to_pos,             to_pos_next
  Protected vd_cycle_from,      vd_cycle_from_m1,   vd_cycle_to,        vd_cycle_to_next
  Protected cycle_under_mouse,  cumv,               offset,             text.s
  Protected time_width_string.s, time_period_string.s

  If *data_buffer

    pin      = py >> 5
    vd_pin   = -1
    vi_index = -1
    
    cycle_under_mouse = Round ( cycle_start + ( px / pixels_per_cycle ), #PB_Round_Down )
   
    If cycle_under_mouse <= data_size_m1 And cycle_under_mouse >= 0
      cumv = PeekB ( *data_buffer + cycle_under_mouse ) & $FF
  
      SetGadgetText ( #info_byte,        "b " + RSet ( Bin ( cumv ), 8, "0" ) )
      SetGadgetText ( #info_byte_nl, " ( 0x" + RSet ( Hex ( cumv ), 2, "0" ) + ", " + Str ( cumv ) + " )" )
  
      info_text_show = #True
  
    EndIf
  
    offset = pin << 12 + px << 2
    If offset >= 0 And offset <= buffer_length
      vi_index = PeekL ( *view_mask_data + offset )
  
    EndIf

    If vi_index > -1
  
      SelectElement ( vi_data(), vi_index )
      With vi_data()
        vd_pin        = \pin
        from_pos      = \cycle_from_position
        to_pos        = \cycle_to_position - 1
        vd_cycle_from = \cycle_from
        vd_cycle_to   = \cycle_to

      EndWith 

      If vd_pin = pin And from_pos <= px And px <= to_pos
  
        ; byl vybran novy puls            
        If last_show_pulse_pin <> vd_pin Or from_pos <> last_show_pulse_from
      
          NextElement ( vi_data() ) 
    
          If vi_data()\pin   = pin
            from_pos_next    = vi_data()\cycle_from_position
            to_pos_next      = vi_data()\cycle_to_position
            vd_cycle_to_next = vi_data()\cycle_to
            vi_index_next    = ListIndex ( vi_data() )
    
          EndIf

          time_width_string.s = FormatTimeString ( vd_cycle_to - vd_cycle_from + 1, time_tick ) 

          SetGadgetText ( #info_width, Str ( vd_cycle_to - vd_cycle_from + 1 ) + time_width_string )

          If vi_index_next = 0 Or vi_index = vi_index_next Or from_pos_next > to_pos + 1
            SetGadgetText ( #info_period, "#"     )
            ShowPulse     ( pin, from_pos, to_pos )

          Else
            time_period_string.s = FormatTimeString ( vd_cycle_to_next - vd_cycle_from + 1, time_tick ) 

            SetGadgetText ( #info_period, Str ( vd_cycle_to_next - vd_cycle_from + 1 ) + time_period_string )
            ShowPulse     ( pin, from_pos, to_pos, from_pos_next, to_pos_next )
            
          EndIf
  
          last_show_pulse_pin  = vd_pin
          last_show_pulse_from = from_pos
        EndIf
      EndIf
  
    Else
      last_show_pulse_pin = -1
  
      If view_state = #True Or move_state = #True Or select_state = #True
        ClearView ()

      EndIf
      
    EndIf
  EndIf    

EndProcedure


Procedure ImageViewProc ( hwnd, msg, wParam, lParam )
  
  Protected ctrl, shift

  ctrl  = ( wParam & $FFFF ) & $0008
  shift = ( wParam & $FFFF ) & $0004

  Select msg
    Case #WM_LBUTTONDOWN
      If ctrl ; control
        SetMarkPos ( 1, view_posx )

      Else
        drag_view  = view_posx

      EndIf

    Case #WM_LBUTTONUP
      If Not ctrl
        If drag_start = 1
          MoveView ( view_posx, drag_pos, 1 )
          drag_start = 0
          
        Else
          ZoomView ( #zoom_in, view_posx    )
        
        EndIf
      EndIf
      

    Case #WM_RBUTTONDOWN
      If ctrl ; control
        SetMarkPos ( 2, view_posx )

      Else
        select_view = view_posx
      EndIf
      
    Case #WM_RBUTTONUP
      If Not ctrl
        If select_start = 1
          SelectView ( view_posx, select_pos, 1 )
          select_start = 0
          
        Else
          ZoomView ( #zoom_out, view_posx    )
          
        EndIf
      EndIf

    Case #WM_MOUSEMOVE
      view_posx  = lParam & $FFFF
      view_posy  = ( ( lParam >> 16 ) & $FFFF ) - 50

      If ctrl
        drag_start = 0
        select_start = 0

      Else 
        If wParam & #MK_LBUTTON
          drag_pos = view_posx - drag_view
          If drag_pos > 3 Or drag_pos < -3
            drag_start = 1
            MoveView ( view_posx, drag_pos, 0 )
  
          Else  
            drag_start = 0
            
          EndIf
  
        ElseIf wParam & #MK_RBUTTON 
          select_pos = view_posx - select_view
          If select_pos > 3 Or select_pos < -3
            select_start = 1
            SelectView ( view_posx, select_pos, 0 )
  
          Else
            select_start = 0
  
          EndIf
  
        Else
          CheckViewArea ( view_posx, view_posy )
  
        EndIf
      EndIf
  EndSelect
  
  ProcedureReturn CallWindowProc_( GetProp_( hwnd, "oldproc" ), hwnd, msg, wParam, lParam )

EndProcedure


Procedure AddToolTips ( gadget_id, x, y, width, height, tooltip_text.s ) ; OK

  Protected hwndParent, hwndTT, g_hInst, ti.TOOLINFO

  hwndParent = GadgetID ( #Image_Tools )

  hwndTT     = CreateWindowEx_( #WS_EX_TOPMOST, #TOOLTIPS_CLASS, #Null, #WS_POPUP | #TTS_NOPREFIX | #TTS_ALWAYSTIP, #CW_USEDEFAULT, #CW_USEDEFAULT, #CW_USEDEFAULT, #CW_USEDEFAULT, hwndParent, #Null, @g_hInst, #Null );

  SetWindowPos_ ( hwndTT, #HWND_TOPMOST, 0, 0, 0, 0, #SWP_NOMOVE | #SWP_NOSIZE | #SWP_NOACTIVATE )

  ti\cbSize      = SizeOf ( TOOLINFO )
  ti\uFlags      = #TTF_SUBCLASS
  ti\hwnd        = hwndParent
  ti\hinst       = g_hInst
    
  ti\RECT\left   = x
  ti\RECT\top    = y
  ti\RECT\right  = x + width
  ti\RECT\bottom = y + height
    
  ti\lpszText    = @tooltip_text

  SendMessage_ ( hwndTT, #TTM_ADDTOOL, 0, @ti )	
  
EndProcedure


Procedure ChangeToolButtonState ( tid, state ) ; OK

  Protected x, y, x1, y1, x18, y18, dc, temp

  active_tool_id    = tid
  active_tool_state = state
  is_tools_clear    = #False

  CopyImage ( #img_tools_clear, #img_tools )

  dc = StartDrawing ( ImageOutput ( #img_tools ) )
  If dc
    tid - 1
    
    x = 3 + ( tid % 12 ) * 25
    y = 3 + ( tid / 12 ) * 25

    PatBlt_ ( dc, x, y, 20, 20, #DSTINVERT )

    If state = #mouse_down

      x1  = x + 1
      y1  = y + 1
      x18 = x + 18
      y18 = y + 18

      FrontColor ( #grey100     )

      MoveToEx_  ( dc,  x1,  y1, #Null )
      LineTo_    ( dc, x18,  y1 )
      LineTo_    ( dc, x18, y18 )
      LineTo_    ( dc,  x1, y18 )
      LineTo_    ( dc,  x1,  y1 )

    EndIf
        
    StopDrawing ()
  EndIf

  SetGadgetState ( #Image_Tools, ImageID ( #img_tools ) )

EndProcedure


Procedure SetCenter ( cycle )

  Protected cl

  cl          = ( cycle_length ) >> 1
  cycle_start = cycle - cl
  cycle_end   = cycle + cl

  CorrectCycles ()
  
  cl          = cycle - cycle_start
  
  If cycle_end - cycle > cl
    cycle_end   = cycle + ( cycle - cycle_start )
  
  ElseIf cl > cycle_end - cycle_start
    cycle_start = cycle - ( cycle_end - cycle )
  
  EndIf
  
  RedrawData ( )
  
EndProcedure


Procedure ToolOperations ( tool_id, type )

  Protected distance

  If type = 0
  
    Debug "do: " + Str ( tool_id )
  
    Select tool_id
        Case #tool_plus  : ZoomView ( #zoom_in,  350 )
        Case #tool_minus : ZoomView ( #zoom_out, 350 )
        
        Case #tool_show_from_mark_to_mark
            If mark_1_pos > -1 And mark_2_pos > -1

              If mark_1_pos > mark_2_pos
                cycle_start = mark_2_pos
                cycle_end   = mark_1_pos

              Else
                cycle_end   = mark_2_pos
                cycle_start = mark_1_pos

              EndIf

              If cycle_end - cycle_start > 40 : distance = 4 : Else : distance = 2 : EndIf
              
              cycle_start = cycle_start - distance
              cycle_end   = cycle_end   + distance
              
              RedrawData ()
              
            Else
              Debug "nektera ze znacek nebyla vlozena"
              
            EndIf
        
        Case #tool_jump_to_start
          cycle_end   = cycle_end - cycle_start
          cycle_start = 0
          RedrawData ()
          
        Case #tool_jump_to_end
          cycle_start = cycle_start + ( data_size_m1 - cycle_end )
          cycle_end   = data_size_m1
          RedrawData ()
        
        Case #tool_delete_from_mark
        Case #tool_delete_from_mark_to_mark
        Case #tool_delete_to_mark

        Case #tool_one : If mark_1_pos > -1 : SetCenter ( mark_1_pos ) : EndIf
        Case #tool_two : If mark_2_pos > -1 : SetCenter ( mark_2_pos ) : EndIf

        Case #tool_io

        Case #tool_test_signal
          ResetView     ( )
          GenerateData  ( 655350, 4 )
          AnalyzeData   ( #True )
          DrawAnalyze   ( )
          RedrawData    ( )
          RedrawInfobar ( )

        Case #tool_reset
          ResetView ( )

        Case #tool_settings
        
        Case #tool_show_all
          cycle_start = 0
          cycle_end   = data_size_m1
          RedrawData ()
      
    EndSelect
  
  Else
    Debug "set: " + Str ( tool_id )
  
  
  EndIf

EndProcedure


Procedure ClearToolButtons () ; OK
  
  CopyImage      ( #img_tools_clear, #img_tools         )
  SetGadgetState ( #Image_Tools, ImageID ( #img_tools ) )
  is_tools_clear = #True
  
EndProcedure


Procedure ToolViewProc ( hwnd, msg, wParam, lParam ) ; OK

  Protected ctrl, tools_posx, tools_posy

  ctrl = ( wParam & $FFFF ) & $0008

  Select msg
    Case #WM_LBUTTONDOWN
      ChangeToolButtonState ( tool_button_id, #mouse_down )
      ToolOperations        ( tool_button_id, 0 )

    Case #WM_RBUTTONDOWN
      ToolOperations        ( tool_button_id, 1 )
      
    Case #WM_MOUSEMOVE
      tools_posx  = lParam & $FFFF
      tools_posy  = ( lParam >> 16 ) & $FFFF
      
      If tools_posx < 300
        tool_button_id = 12 * ( tools_posy / 25 ) + tools_posx / 25 + 1
        ChangeToolButtonState ( tool_button_id, #mouse_over )
      
      ElseIf is_tools_clear = #False
        tool_button_id = 0
        ClearToolButtons ( )

      EndIf

  EndSelect

  ProcedureReturn CallWindowProc_( GetProp_( hwnd, "oldproc" ), hwnd, msg, wParam, lParam )

EndProcedure


Procedure.l WinCallback   ( hwnd, msg, wparam, lparam )

  Protected pnt.POINT, px, py, state
  Protected result = #PB_ProcessPureBasicEvents

  Select msg
    Case #WM_MOUSEWHEEL

      GetCursorPos_   ( @pnt ) 
      ScreenToClient_ ( main_window_hwnd, @pnt )

      If PtInRect_ ( @view_rect, pnt\x | pnt\y << 32) 

        state = #zoom_in
        If wparam < 0 : state = #zoom_out : EndIf
        ZoomView ( state, pnt\x - view_rect\left )

      EndIf
    
    Case #WM_RBUTTONUP
      If select_state = #True
        KillTimer_ ( main_window_hwnd, 0 )
        SelectView ( view_posx, select_pos, 1 )
        select_state = #False
        
      EndIf
      
    Case #WM_LBUTTONUP
      If move_state = #True
        KillTimer_ ( main_window_hwnd, 0 )
        MoveView   ( view_posx, drag_pos, 1 )
        move_state = #False
        
      EndIf  
    
  EndSelect
  
  ProcedureReturn result

EndProcedure 


Procedure AddTips ( gadget, x, y, text.s )
  
  AddToolTips ( gadget, x, y, 25, 25, text )

EndProcedure


Procedure AddToolbarTips ()
 
  Protected gadget_id, c, tooltip_text.s, skip, x, y

  gadget_id = GadgetID ( #Image_Tools )
  
  x = 5
  y = 5
    
  For c = #first_tool To #last_tool
  
    skip           = #False

    Select c
      Case #tool_plus                      : tooltip_text = "Zoom IN"
      Case #tool_minus                     : tooltip_text = "Zoom OUT"
      Case #tool_show_from_mark_to_mark    : tooltip_text = "Show from Mark to Mark"
      Case #tool_jump_to_start             : tooltip_text = "Jump to Start"
      Case #tool_jump_to_end               : tooltip_text = "Jump to End"
      Case #tool_delete_from_mark          : tooltip_text = "NA"
      Case #tool_delete_from_mark_to_mark  : tooltip_text = "NA"
      Case #tool_delete_to_mark            : tooltip_text = "NA"
      Case #tool_one                       : tooltip_text = "Show Mark 1"
      Case #tool_two                       : tooltip_text = "Show Mark 2"
      Case #tool_io                        : tooltip_text = "NA"
      Case #tool_test_signal               : tooltip_text = "NA"
      Case #tool_reset                     : tooltip_text = "Reset View"
      Case #tool_settings                  : tooltip_text = "NA"
      Case #tool_show_all                  : tooltip_text = "Show All"
      Default 
        skip = #True
          
    EndSelect
  
    If skip = #False
      AddToolTips ( gadget_id, x, y, 25, 25, tooltip_text )

    EndIf
            
    x = x + 25
    If x = 305
      x = 5
      y = 30
    EndIf
  Next


EndProcedure


Procedure NewImage ( image_id, width, height, background_color, font = 0 )
  
  Protected dc

  If CreateImage ( image_id, width, height, #PB_Image_DisplayFormat )
    dc = StartDrawing ( ImageOutput ( image_id ) )
    
    If dc
      Box ( 0, 0, width, height, background_color )
      StopDrawing ()

    EndIf
    
    dc = StartDrawing ( ImageOutput ( image_id ) )
    
    If dc
      If font
        DrawingFont ( FontID ( font ) )
        DrawingMode ( #PB_2DDrawing_Transparent )
      EndIf
      
      ProcedureReturn dc

    EndIf
  EndIf
  
  ProcedureReturn 0

EndProcedure


Procedure DrawPinDelimiters ( offset, width ) 

  Protected y, y1

  For y = offset To offset + 224 Step 32
    y1 = y
    LineXY ( 0, y1, width, y1, #grey140 ) : y1 + 1
    LineXY ( 0, y1, width, y1, #grey100 ) : y1 + 1
    LineXY ( 0, y1, width, y1, #grey080 )

  Next

EndProcedure


Procedure CreateGraphics ( )

  Protected text.s, pin, c, color, d, dc, x, y, x1, x2, y1, y2, x_3, x_4, x_25, skip, py, px, line.w

  If NewImage ( #img_pin_numbers, 30, 256, #grey030, #verdana_font10 ) 
  
    DrawPinDelimiters ( 0, 30    )
    FrontColor        ( #grey255 )
  
    For pin = 0 To 7
      text  = Str  ( pin + 1 )
      DrawText ( 15 - ( TextWidth  ( text ) >> 1 ), ( pin << 5 ) + 15 - ( TextHeight ( text ) >> 1 ), text )
                  
    Next
 
    StopDrawing ()
  EndIf

  If NewImage ( #img_data_clear, 700, 306, #bck_color, #verdana_font10 ) 
    Box               (  0,  50, 700, 306, #grey030 )
    DrawPinDelimiters ( 50, 700 )
    StopDrawing       ( )

  EndIf
  
  If NewImage ( #img_info_bar, 700, 15, #bck_color ) 
    Box               ( 0, 3, 700, 12,  #grey140 )
    Box               ( 1, 5, 698, 9,   #grey030 )
    StopDrawing       ( )

  EndIf

  CopyImage ( #img_data_clear, #img_data_temp )
  
  CopyImage ( #img_data_clear, #img_data      )
  
  If NewImage ( #logo, 300, 50, #bck_color, #verdana_font20 )
 
    text = "Fresh Logic Analyzer"

    FrontColor  ( #grey000 )
    
    x = ( 300 - TextWidth  ( text ) ) >> 1
    y = ( 50  - TextHeight ( text ) ) >> 1

    For x1 = x - 2 To x + 2 Step 2
      For y1 = y - 2 To y + 2 Step 2
        DrawText ( x1, y1, text )

      Next
    Next
    
    DrawText    ( x, y, text, #grey140 )
    StopDrawing ( )

  EndIf

  dc = NewImage ( #img_tools, 301, 51, #grey080 )
  
  If dc
    Box    ( 1,  1, 299, 49, #grey060 )
    LineXY ( 4, 25, 296, 25, #grey080 )
  
    For y = 3 To 28 Step 25
      For x = 3 To 278 Step 25
        Box    ( x,      y,     20,     20,     #grey100 )
        Box    ( x + 1,  y + 1, 18,     18,     #grey050 )
        LineXY ( x + 21, y,     x + 21, y + 19, #grey080 )

      Next
    Next
   
    x = 5 : y = 7
      
    For c = #first_tool To #last_tool
    
      skip = #False
  
      Select c
        Case #tool_plus                     : Restore ico_plus
        Case #tool_minus                    : Restore ico_minus
        Case #tool_show_from_mark_to_mark   : Restore ico_show_from_mark_to_mark
        Case #tool_jump_to_start            : Restore ico_jump_to_start
        Case #tool_jump_to_end              : Restore ico_jump_to_end
;         Case #tool_delete_from_mark         : Restore ico_delete_from_mark
;         Case #tool_delete_from_mark_to_mark : Restore ico_delete_from_mark_to_mark
;         Case #tool_delete_to_mark           : Restore ico_delete_to_mark
        Case #tool_one                      : Restore ico_one
        Case #tool_two                      : Restore ico_two
;         Case #tool_io                       : Restore ico_io 
        Case #tool_test_signal              : Restore ico_test_signal
        Case #tool_reset                    : Restore ico_reset
;         Case #tool_settings                 : Restore ico_settings
        Case #tool_show_all                 : Restore ico_show_all
        Default : skip = #True
            
      EndSelect
    
      If skip = #False
        For py = y To y + 11
    
          Read.w line

          d = 15
          For px = x To x + 15 
  
            If line & ( 1 << d )
              SetPixel_ ( dc, px, py, #grey200 )

            Else
              SetPixel_ ( dc, px, py, #grey050 )

            EndIf
            d - 1
     
          Next
        Next
  
      EndIf
              
      x = x + 25
      If x = 305
        x = 5
        y = 32
      EndIf
    Next

    StopDrawing ()
  EndIf

  CopyImage ( #img_tools, #img_tools_clear )

EndProcedure


Procedure ClearMoveAndSelect( )
  
  select_state = #False
  move_state   = #False
  drag_start   = 0

  KillTimer_( main_window_hwnd, 0 )
  
  ClearView ()
  
EndProcedure


Procedure TextGadgetColored ( gadget, x, y, width, height, text.s, flags, back_color = #bck_color, front_color = #grey240 )

  TextGadget     ( gadget, x, y, width, height, text, flags )
  SetGadgetColor ( gadget, #PB_Gadget_BackColor,  back_color  )
  SetGadgetColor ( gadget, #PB_Gadget_FrontColor, front_color )
  
EndProcedure


Procedure About ()


EndProcedure


Procedure OpenDataFile ()


EndProcedure


Procedure OpenMainWindow ( )

  Protected c, d, dc, pin, text.s, x, y, x1, y1, x2, y2, hwnd, gadget_id

  CreateGraphics ( )

  If OpenWindow ( #main_window, 12, 71, 925, 450, "Fresh Logic Analyzer", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget )

    SetWindowColor    ( #main_window, #bck_color ) 
   
    ButtonGadget      ( #button_get_data,     15,  15,  60,  50, "Get Data", #BS_FLAT )
   
    ImageGadget       ( #Image_Tools,        215,  15, 330,  51, ImageID ( #img_tools ) )
    ImageGadget       ( #logo_img_gadget,    620,   0, 300,  50, ImageID ( #logo ) )
    ImageGadget       ( #Image_0,             10, 125,  35, 326, ImageID ( #img_pin_numbers ) )
    ImageGadget       ( #Image_1,            215,  75, 700, 306, ImageID ( #img_data        ) )
    ImageGadget       ( #Image_2,            215, 425, 700, 256, ImageID ( #img_info_bar    ) )

    ScrollBarGadget   ( #Scroll,             215, 405, 700,  15, 0, 100, 10 )
    
    TextGadgetColored ( #info_width_header,   15, 385,  40,  15, "Width:" , 0 )
    TextGadgetColored ( #info_period_header,  15, 400,  40,  15, "Period:", 0 )
    TextGadgetColored ( #info_byte_header,    15, 415,  40,  15, "Byte:"  , 0 )
    TextGadgetColored ( #info_width,          65, 385, 110,  15, "#"      , 0 )
    TextGadgetColored ( #info_period,         65, 400, 110,  15, "#"      , 0 )
    TextGadgetColored ( #info_byte,           65, 415, 110,  15, "#"      , 0 )
    TextGadgetColored ( #info_byte_nl,        65, 430, 100,  15, "#"      , 0 )

    TextGadgetColored ( #info_cycle_from,    220, 385, 100,  16, ""       , 0 )
    TextGadgetColored ( #info_cycle,         365, 385, 400,  16, ""       , #PB_Text_Center )
    TextGadgetColored ( #info_cycle_to,      810, 385, 100,  16, ""       , #PB_Text_Right  )

    TextGadgetColored ( #M1, 166, 105, 20, 14, "M1", #PB_Text_Center, #Red,  #grey000 )
    TextGadgetColored ( #M2, 190, 105, 20, 14, "M2", #PB_Text_Center, #Blue, #grey000 )

    y = 134 : x = 166

    For c = #s_bit_1 To #e_bit_8
      TextGadgetColored ( c, x, y, 20, 16, "0", #PB_Text_Center ) : y + 32
      If c = #s_bit_8 : y = 134 : x = 190 : EndIf

    Next

    y = 129
    For c = 0 To 7
      x1 = #pin1_active + c

      StringGadget   ( #pin1 + c,  50, y, 80, 25, "pin " + Str ( c + 1 ) )
      SpinGadget     ( x1,        135, y, 25, 25, 0, 1, #PB_Spin_Numeric )
      SetGadgetState ( x1, 1 )
      y + 32

    Next

    hwnd = GadgetID ( #Image_Tools )
    SetProp_( hwnd, "oldproc", SetWindowLong_( hwnd, #GWL_WNDPROC, @ToolViewProc()  ) )

    hwnd = GadgetID ( #Image_1 )
    SetProp_( hwnd, "oldproc", SetWindowLong_( hwnd, #GWL_WNDPROC, @ImageViewProc() ) )

    AddToolbarTips  ( )

    main_window_hwnd = WindowID ( #main_window )

    view_rect\left   = GadgetX  ( #Image_1 )
    view_rect\top    = GadgetY  ( #Image_1 ) + 50
    view_rect\right  = view_rect\left        + 700
    view_rect\bottom = view_rect\top         + 256

    tool_rect\left   = GadgetX  ( #Image_Tools )
    tool_rect\top    = GadgetY  ( #Image_Tools )
    tool_rect\right  = tool_rect\left        + 400
    tool_rect\bottom = tool_rect\top         + 51

    SetWindowCallback ( @WinCallback() )
   
  Else
    End

  EndIf

EndProcedure

OpenMainWindow ()



; ==============================================================================


;{ --- EVENT LOOP ---

Repeat
  Event = WaitWindowEvent()

  GetCursorPos_   ( @point.POINT             ) 
  ScreenToClient_ ( main_window_hwnd, @point ) 

  If is_tools_clear = #False And Not PtInRect_( @tool_rect, point\x | point\y << 32 )
    active_tool_id    = 0
    active_tool_state = #Null
    ClearToolButtons ()

  EndIf

  If Not PtInRect_( @view_rect, point\x | point\y << 32 )
    
    If select_state = #True Or move_state = #True
      SetTimer_( main_window_hwnd, 0, 3000, @ClearMoveAndSelect() )
    
    EndIf 
    
    If view_state = #True
      ClearView ()
      drag_start = 0

    EndIf

    If info_text_show = #True
      For c = #info_width To #info_byte_nl : SetGadgetText ( c, "#" ) : Next
      info_text_show = #False

    EndIf

  EndIf

  Select Event
    Case #PB_Event_Gadget

      Select EventGadget()
        
        Case #pin1 To #pin8
;           CheckPinNames ()
          
        Case #pin1_active To #pin8_active
          CheckPinActive ()
        
        Case #Scroll
          new_scroll_position = GetGadgetState     ( #Scroll )
          page_length         = GetGadgetAttribute ( #Scroll, #PB_ScrollBar_PageLength )
          
          If new_scroll_position <> scroll_position
            cycle_start     = new_scroll_position
            cycle_end       = cycle_start + page_length
            scroll_position = new_scroll_position
            RedrawData ()
            
          EndIf
        
        Case #button_get_data
          Debug "#button_get_data"
          GenerateData ( 1024 * 1024, 6 )
          AnalyzeData   ( #True )
          DrawAnalyze   ( )
          RedrawData    ( )
          RedrawInfobar ( )
        
      EndSelect

    Case #WM_TIMER

    Case #PB_Event_CloseWindow
      If EventWindow() = #main_window
        CloseWindow ( #main_window )
        Break

      EndIf
  
 
  EndSelect
  
ForEver

;}



If fnt_v08 : FreeFont ( #verdana_font08 ) : EndIf
If fnt_v10 : FreeFont ( #verdana_font10 ) : EndIf
If fnt_v12 : FreeFont ( #verdana_font12 ) : EndIf
If fnt_v20 : FreeFont ( #verdana_font20 ) : EndIf

End

; --------------------------------------------------------------------------


DataSection

  ;{ ico data
  ico_plus:
    Data.w %0000111111110000
    Data.w %0001000000001000
    Data.w %0010000110000100
    Data.w %0010000110000100
    Data.w %0010000110000100
    Data.w %0010111111110100
    Data.w %0010111111110100
    Data.w %0010000110000100
    Data.w %0010000110000100
    Data.w %0010000110000100
    Data.w %0001000000001000
    Data.w %0000111111110000
    
  ico_minus:
    Data.w %0000111111110000
    Data.w %0001000000001000
    Data.w %0010000000000100
    Data.w %0010000000000100
    Data.w %0010000000000100
    Data.w %0010111111110100
    Data.w %0010111111110100
    Data.w %0010000000000100
    Data.w %0010000000000100
    Data.w %0010000000000100
    Data.w %0001000000001000
    Data.w %0000111111110000
 
    
  ico_show_from_mark_to_mark:
    Data.w %0000000000000000
    Data.w %0011000000001100
    Data.w %0011000000001100
    Data.w %0011000000001100
    Data.w %0011011100101100
    Data.w %0011010100101100
    Data.w %0011010100101100
    Data.w %0011010111101100
    Data.w %0011000000001100
    Data.w %0011000000001100
    Data.w %0011000000001100
    Data.w %0000000000000000

  ico_jump_to_start:
    Data.w %0000000000000000
    Data.w %0011000000011100
    Data.w %0011000000111100
    Data.w %0011000001101100
    Data.w %0011000011001100
    Data.w %0011000110001100
    Data.w %0011000110001100
    Data.w %0011000011001100
    Data.w %0011000001101100
    Data.w %0011000000111100
    Data.w %0011000000011100
    Data.w %0000000000000000

  
  ico_jump_to_end:
    Data.w %0000000000000000
    Data.w %0011100000001100
    Data.w %0011110000001100
    Data.w %0011011000001100
    Data.w %0011001100001100
    Data.w %0011000110001100
    Data.w %0011000110001100
    Data.w %0011001100001100
    Data.w %0011011000001100
    Data.w %0011110000001100
    Data.w %0011100000001100
    Data.w %0000000000000000

  ico_delete_from_mark:
    Data.w %0000000000000000
    Data.w %0011000000000000
    Data.w %0011001000001000
    Data.w %0011001100011000
    Data.w %0011000110110000
    Data.w %0011000011100000
    Data.w %0011000011100000
    Data.w %0011000110110000
    Data.w %0011001100011000
    Data.w %0011001000001000
    Data.w %0011000000000000
    Data.w %0000000000000000

  
  ico_delete_from_mark_to_mark:
    Data.w %0000000000000000
    Data.w %0011000000001100
    Data.w %0011010000101100
    Data.w %0011011001101100
    Data.w %0011001111001100
    Data.w %0011000110001100
    Data.w %0011000110001100
    Data.w %0011001111001100
    Data.w %0011011001101100
    Data.w %0011010000101100
    Data.w %0011000000001100
    Data.w %0000000000000000

  ico_delete_to_mark:
    Data.w %0000000000000000
    Data.w %0000000000001100
    Data.w %0001000001001100
    Data.w %0001100011001100
    Data.w %0000110110001100
    Data.w %0000011100001100
    Data.w %0000011100001100
    Data.w %0000110110001100
    Data.w %0001100011001100
    Data.w %0001000001001100
    Data.w %0000000000001100
    Data.w %0000000000000000

  ico_one:
    Data.w %0000000000000000
    Data.w %0000000110000000
    Data.w %0000001110000000
    Data.w %0000011110000000
    Data.w %0000000110000000
    Data.w %0000000110000000
    Data.w %0000000110000000
    Data.w %0000000110000000
    Data.w %0000000110000000
    Data.w %0000001111000000
    Data.w %0000001111000000
    Data.w %0000000000000000

  ico_two:
    Data.w %0000000000000000
    Data.w %0000001111000000
    Data.w %0000011111100000
    Data.w %0000011001100000
    Data.w %0000000001100000
    Data.w %0000000001100000
    Data.w %0000000011000000
    Data.w %0000000111000000
    Data.w %0000001110000000
    Data.w %0000011111100000
    Data.w %0000011111100000
    Data.w %0000000000000000

  ico_io:
    Data.w %0000010101010000
    Data.w %0000010101010000
    Data.w %0011000000000000
    Data.w %0000011111101100
    Data.w %0011010000100000
    Data.w %0000011111101100
    Data.w %0011011111100000
    Data.w %0000010000101100
    Data.w %0011011111100000
    Data.w %0000000000001100
    Data.w %0000101010100000
    Data.w %0000101010100000

  ico_test_signal:
    Data.w %0010111011101100
    Data.w %0010101010101000
    Data.w %0011101110111000
    Data.w %0000000000000000
    Data.w %0011111001111100
    Data.w %0010001001000100
    Data.w %0010001111000100
    Data.w %0000000000000000
    Data.w %0011111110000100
    Data.w %0010000010000100
    Data.w %0010000011111100
    Data.w %0000000000000000


  ico_reset:
    Data.w %0000000000000000
    Data.w %0001111001111000
    Data.w %0001000000001000
    Data.w %0001011111101000
    Data.w %0001010000101000
    Data.w %0000010110100000
    Data.w %0000010110100000
    Data.w %0001010000101000
    Data.w %0001011111101000
    Data.w %0001000000001000
    Data.w %0001111001111000
    Data.w %0000000000000000

  ico_settings:
    Data.w %0000000000000000
    Data.w %0001111111111000
    Data.w %0001111111111000
    Data.w %0001000000001000
    Data.w %0001000000001000
    Data.w %0001010111101000
    Data.w %0001000000001000
    Data.w %0001010111101000
    Data.w %0001000000001000
    Data.w %0001000000001000
    Data.w %0001111111111000
    Data.w %0000000000000000

  ico_show_all:
    Data.w %0000000000000000
    Data.w %0000000000000000
    Data.w %0000000110000000
    Data.w %0000100110010000
    Data.w %0001100000011000
    Data.w %0011100110011100
    Data.w %0011100110011100
    Data.w %0001100000011000
    Data.w %0000100110010000
    Data.w %0000000110000000
    Data.w %0000000000000000
    Data.w %0000000000000000


  ;}

EndDataSection


User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: GUI for Logical Analyser

Post by fsw »

This is pretty cool stuff.

Thank you for sharing your code with us.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: GUI for Logical Analyser

Post by rsts »

That has a very cool look :D

I'll have to study this some.

Thanks for sharing.
JCV
Enthusiast
Enthusiast
Posts: 580
Joined: Fri Jun 30, 2006 4:30 pm
Location: Philippines

Re: GUI for Logical Analyser

Post by JCV »

nice interface. Thanks for sharing.

[Registered PB User since 2006]
[PureBasic 6.20][SpiderBasic 2.2]
[RP4 x64][Win 11 x64][Ubuntu x64]
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GUI for Logical Analyser

Post by Kwai chang caine »

Splendid.. :shock:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply