docs: def draw_panel(cb, pool, params, plane):
      """
      Draws the application's main panel, displaying the current Mandelbrot view.
  
      :param cb: Cursebox instance.
      :type cb: cursebox.Cursebox
      :param params: Current application parameters.
      :type params: params.Params
      :param plane: Plane containing the current Mandelbrot values.
      :type plane: plane.Plane
      """
      w = cb.width - MENU_WIDTH - 1
      h = cb.height - 1
  
      params.plane_w = w
      params.plane_h = h
      params.resize(w, h)
  
      palette = PALETTES[params.palette][1]
      if params.reverse_palette:
          palette = palette[::-1]
  
      # draw_gradient(t, 1, 1, w, h, palette, params.dither_type)
  
      generated = 0
      missing_coords = []
  
      # Check for coordinates that have no value in current plane
      xs = range(params.plane_x0, params.plane_x0 + params.plane_w - 1)
      ys = range(params.plane_y0, params.plane_y0 + params.plane_h - 1)
      for x in xs:
          for y in ys:
              if plane[x, y] is None:
                  missing_coords.append((x, y, params))
                  generated += 1
  
      # Compute all missing values via multiprocessing
      n_processes = 0
      if len(missing_coords) > 0:
          n_cores = pool._processes
          n_processes = len(missing_coords) // 256
          if n_processes > n_cores:
              n_processes = n_cores
  
          start = time.time()
          for i, result in enumerate(pool.imap_unordered(compute, missing_coords, chunksize=256)):
              plane[result[0], result[1]] = result[2]
              if time.time() - start > 2:
                  if i % 200 == 0:
                      draw_progress_bar(cb, "Render is taking a longer time...", i, len(missing_coords))
                      cb.refresh()
  
      if generated > 0:
          params.log("Added %d missing cells" % generated)
          if n_processes > 1:
              params.log("(Used %d processes)" % n_processes)
  
      min_value = 0.0
      max_value = params.max_iterations
      max_iterations = params.max_iterations
  
      if params.adaptive_palette:
          min_value, max_value = plane.extrema(params.plane_x0, params.plane_y0,
                                               params.plane_w, params.plane_h)
  
      crosshairs_coord = None
      if params.crosshairs:
          crosshairs_coord = params.crosshairs_coord
  
      # Draw all values in cursebox
      for x in xs:
          for y in ys:
              value = (plane[x, y] + params.palette_offset) % (params.max_iterations + 1)
              if params.adaptive_palette:
                  # Remap values from (min_value, max_value) to (0, max_iterations)
                  if max_value - min_value > 0:
                      value = ((value - min_value) / (max_value - min_value)) * max_iterations
                  else:
                      value = max_iterations
  
              # Dithered mode
              if params.dither_type < 2:
                  draw_dithered_color(cb, x - params.plane_x0 + 1,
                                             y - params.plane_y0 + 1,
                                             palette, params.dither_type,
                                             value, max_iterations,
                                             crosshairs_coord=crosshairs_coord)
              # 256 colors mode
              else:
                  draw_color(cb, x - params.plane_x0 + 1,
                                y - params.plane_y0 + 1,
                                value, max_iterations, palette,
                                crosshairs_coord=crosshairs_coord)
  
      # Draw bounding box
      draw_box(cb, 0, 0, w + 1, h + 1)