The 18F4550 has built-in PWM generators, so this is easy. Once you set up the hardware, it continues to generate the PWM waveform on its own. The hardware to do this is called a "CCP" module, which stands for Compare, Capture, and Pulsewidth modulation. In your case you want to use it in PWM mode.
You set up timer 2 to provide the PWM period, then the duty cycle is written to CCPRxL. Actually the duty cycle has 2 extra fraction bits below the timer 2 period. These fraction bits are written to the CCPxCON register in the right place. It's a little squirrely, but it all works.
If you want to change the PWM duty cycle every period, then you probably want to interrupt on timer 2. Note that with its postscaler, you can interrupt every N periods, where N is 1 to 16. In the interrupt, you change CCPRxL and CCPxCON (if you want to use the extra fraction bits) to the new duty cycle. The duty cycle in these registers is in units of timer 2 counts, which is the absolute on time per pulse, not the fraction of on time per pulse. The fraction of on time is the absolute on time divided by the period.
Once you know how change the PWM duty cycle, it can be triggered from any decision in the code. To change it based on a external switch press means detecting that press then performing the change.