//
// ICListSlider::ResizeKnob
//
// Resize the knob
//
void ICListSlider::ResizeKnob()
{
  ASSERT(controlState & STATE_ACTIVE)
  ASSERT(listBoxes.GetCount())

  // This only resizes the knob on the first list box size
  ListBoxWatcher *watch = listBoxes[0];

  S32 vis = watch->vis->GetIntegerValue();
  S32 cnt = watch->count->GetIntegerValue();
  F32 newPct;

  if (cnt == 0)
  {
    // List is empty, avoid divide by zero
    newPct = 1.0F;
  }
  else
  {
    // Clamp size fo 0-100%
    newPct = Clamp<F32>(0.0F, F32(vis) / F32(cnt), 1.0F);
  }

  // Did it actually change size?
  if (knobPct != newPct)
  {
    knobPct = newPct;

    // Calculate new slider size
    ClipRect thumbRange = GetThumbRange();
    Point<S32> newSize;

    if (horizontal)
    {
      newSize.x = Clamp<S32>
                  (
                    thumbRange.Height(),
                    Utils::FtoL(knobPct * thumbRange.Width()),
                    thumbRange.Width()
                  );
      newSize.y = thumbRange.Height();
    }
    else
    {
      newSize.x = thumbRange.Width();
      newSize.y = Clamp<S32>
                  (
                    thumbRange.Width(),
                    Utils::FtoL(knobPct * thumbRange.Height()),
                    thumbRange.Height()
                  );
    }

    // Resize it
    thumbBtn->Resize(newSize);
  }
}
    //
    // TransferList::Item::DrawSelf
    //
    // DrawSelf
    //
    void TransferList::Item::DrawSelf(PaintInfo &pi)
    {
      // Fill the background
      DrawCtrlBackground(pi, GetTexture());

      // Draw the frame
      DrawCtrlFrame(pi);

      if (!pi.font)
      {
        return;
      }

      CH buff[128];
      const CH *ch;

      // Draw the name of the file
      ch = Utils::Ansi2Unicode(offer->path.str);
      pi.font->Draw
      (
        pi.client.p0.x + transferList.offsetFile.x,
        pi.client.p0.y + transferList.offsetFile.y, 
        ch, 
        Utils::Strlen(ch),
        pi.colors->fg[ColorIndex()],
        &pi.client
      );

      Network::Player *player = Network::GetPlayers().Find(offer->who);
      if (player)
      {
        Utils::Sprintf(buff, 128, L"%s %s", offer->from ? L"From" : L"To", Utils::Ansi2Unicode(player->GetName()));
        ch = buff;
        pi.font->Draw
        (
          pi.client.p0.x + transferList.offsetPlayer.x,
          pi.client.p0.y + transferList.offsetPlayer.y, 
          ch, 
          Utils::Strlen(ch),
          pi.colors->fg[ColorIndex()],
          &pi.client
        );
      }

      ch = Utils::Ansi2Unicode(offer->path.str);
      pi.font->Draw
      (
        pi.client.p0.x + transferList.offsetFile.x,
        pi.client.p0.y + transferList.offsetFile.y, 
        ch, 
        Utils::Strlen(ch),
        pi.colors->fg[ColorIndex()],
        &pi.client
      );

      U32 state;
      U32 remaining;
      U32 rate;

      offer->transfer.Progress(state, remaining, rate);

      switch (state)
      {
        case StyxNet::TransferState::Transferring:
          break;

        default:
          remaining = offer->size;
          rate = 0;
          break;
      }

      U32 transferred = offer->size - remaining;

      // Draw the amount transferred
      if (transferred < 1000)
      {
        Utils::Sprintf(buff, 128, L"%.1fB", F32(transferred));
      }
      else if (transferred < 1000000)
      {
        Utils::Sprintf(buff, 128, L"%.1fkB", F32(transferred) / 1000.0f);
      }
      else
      {
        Utils::Sprintf(buff, 128, L"%.1fMB", F32(transferred) / 1000000.0f);
      }
      ch = buff;
      pi.font->Draw
      (
        pi.client.p0.x + transferList.offsetTransferred.x,
        pi.client.p0.y + transferList.offsetTransferred.y, 
        ch, 
        Utils::Strlen(ch),
        pi.colors->fg[ColorIndex()],
        &pi.client
      );

      // Draw the rate
      if (rate < 1000)
      {
        Utils::Sprintf(buff, 128, L"%.1fB/s", F32(rate));
      }
      else if (rate < 1000000)
      {
        Utils::Sprintf(buff, 128, L"%.1fkB/s", F32(rate) / 1000.0f);
      }
      else
      {
        Utils::Sprintf(buff, 128, L"%.1fMB/s", F32(rate) / 1000000.0f);
      }
      pi.font->Draw
      (
        pi.client.p0.x + transferList.offsetRate.x,
        pi.client.p0.y + transferList.offsetRate.y, 
        ch, 
        Utils::Strlen(ch),
        pi.colors->fg[ColorIndex()],
        &pi.client
      );

      // Draw the ETA
      if (rate)
      {
        S32 eta = remaining / rate;
        Utils::Sprintf(buff, 128, L"%d:%02d", eta / 60, eta % 60);
      }
      else
      {
        ch = L"?:??";
      }
      pi.font->Draw
      (
        pi.client.p0.x + transferList.offsetETA.x,
        pi.client.p0.y + transferList.offsetETA.y, 
        ch, 
        Utils::Strlen(ch),
        pi.colors->fg[ColorIndex()],
        &pi.client
      );

      // Draw a progress bar
      ClipRect c
      (
        pi.client.p0.x + transferList.offsetProgress.x, pi.client.p0.y + transferList.offsetProgress.y,
        pi.client.p1.x - transferList.offsetProgress.x, pi.client.p0.y + transferList.offsetProgress.y + transferList.heightProgress
      );

      IFace::RenderRectangle
      (
        c,
        Color(0.0f, 0.0f, 0.0f, pi.alphaScale), 
        NULL, 
        pi.alphaScale
      );

      IFace::RenderGradient
      (
        ClipRect
        (
          c.p0.x, c.p0.y,
          c.p1.x - (c.Width() * remaining / offer->size), c.p1.y
        ), 
        Color(0.2f, 1.0f, 1.0f, pi.alphaScale), 
        Color(0.1f, 0.5f, 0.5f, pi.alphaScale)
      );

    }